Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
78da6a7
📖 [doc] Application for BSI Certification
edulix Jan 22, 2026
a4217f4
cross reference the cybersec page
edulix Jan 22, 2026
a648d4c
more explictly addressing disclosure
edulix Jan 22, 2026
d71a86c
wip
edulix Jan 22, 2026
658089b
wip
edulix Mar 13, 2026
6c7c295
wip
edulix Mar 17, 2026
4371a10
vulnerabilities
edulix Jul 22, 2026
a2404b1
fix broken links
edulix Jul 22, 2026
a99de66
Merge remote-tracking branch 'origin/main' into feat/meta-10548/main
edulix Aug 2, 2026
d8c56c4
wip
edulix Aug 3, 2026
3cbfd56
fix(vdp): align the disclosure policy with ALC-05 for ITSEF delivery
edulix Aug 3, 2026
27d94ec
fix(vdp): drop repository identity from the policy scope
edulix Aug 3, 2026
fd12dc4
fix(vdp): drop the pointer to the product lifecycle page
edulix Aug 3, 2026
b4ef9fe
fix(vdp): say where advisories are published and how customers are re…
edulix Aug 3, 2026
91ff09f
fix(vdp): use "consumer" for the TOE recipient, as CC:2022 does
edulix Aug 3, 2026
e1970c3
docs(vdp): state the policy version so a reviewed copy can be identified
edulix Aug 3, 2026
866af8f
build: pin every base image by immutable digest in the TOE build defi…
edulix Sep 2, 2026
0847495
docs(security): publish CSAF provider metadata under .well-known/csaf
edulix Sep 2, 2026
0e495ca
Merge remote-tracking branch 'origin/main' into feat/meta-10548/main
edulix Sep 2, 2026
00588a0
build: gate the Miru/ECIES integration behind a default-off feature a…
edulix Sep 2, 2026
0429112
build: prune Cargo.lock after removing the unused ecies crate
edulix Sep 2, 2026
afc67e2
windmill: encrypt exports in-process with PBKDF2-HMAC-SHA-256 and AES…
edulix Sep 2, 2026
80b0bcd
style(windmill): cargo fmt the in-process export encryption
edulix Sep 3, 2026
f23594b
test(velvet): keep the Miru receipts stage out of the default test pi…
edulix Sep 3, 2026
26519eb
build: make the production build definitions of the TOE parts buildable
edulix Sep 4, 2026
90ea027
build: put the cargo vendoring configuration where cargo reads it
edulix Sep 4, 2026
aead483
build: build the sequent-core WebAssembly module instead of committin…
edulix Sep 4, 2026
d5d9ccf
build: take the Maven local repository from the accepted inputs, not …
edulix Sep 4, 2026
9025263
build: make the WebAssembly toolchain the publishers' archives, not b…
edulix Sep 4, 2026
c83d295
build: drop the auto_generate_cdp patch that Cargo.lock never used
edulix Sep 4, 2026
9b1a68f
build: take every stage's packages, crates and npm packages from the …
edulix Sep 4, 2026
9b92eda
build: declare webpack with the range the lockfile resolves
edulix Sep 4, 2026
9c219c8
build: forbid unsafe code in every crate, and report the uses that re…
edulix Sep 4, 2026
422592d
strand: compare the shuffle sizes for zero the way an unsigned type a…
edulix Sep 4, 2026
e58b3b2
docs: point the dependency report at the reference it documents, and …
edulix Sep 4, 2026
c2154a6
Gate optional trustee cloud clients and require offline production in…
edulix Sep 5, 2026
3df3435
Return errors for invalid ballot encoding bases
edulix Sep 5, 2026
0d53588
Use the offline build engine frontend for Keycloak
edulix Sep 5, 2026
d4682e7
Resolve Rust correctness diagnostics and test target configuration
edulix Sep 5, 2026
de898b7
Correct tally CSV columns and publication preview status
edulix Sep 5, 2026
1416712
Identify public reporting artifacts and their documentation build inputs
edulix Sep 5, 2026
793d92c
Export selected consumer guidance with bound pages and local images
edulix Sep 5, 2026
f977fff
Check large documentation Git objects without buffering their contents
edulix Sep 5, 2026
240a02d
Bound role and permission pagination before slicing returned lists
edulix Sep 5, 2026
eabf94d
Resolve strict Strand diagnostics without weakening lint checks
edulix Sep 6, 2026
aaa141e
Protect immudb client diagnostics and propagate database deletion fai…
edulix Sep 6, 2026
1b67a54
Restrict area-contest matches to the requested contest selection
edulix Sep 6, 2026
e3275d6
Protect Keycloak credential diagnostics and report rejected HTTP oper…
edulix Sep 6, 2026
a65c7c7
Bound ballot decoding and complete strict sequent-core lint review
edulix Sep 6, 2026
c1ad12f
Complete strict lint review for bulletin-board clients and message types
edulix Sep 6, 2026
182706f
Complete strict native Braid lint review and preserve protocol behavior
edulix Sep 6, 2026
8d73fda
Complete Velvet construct review and use its library from the CLI
edulix Sep 6, 2026
046b65d
Fix pinned Celery task macro scope without changing task contracts
edulix Sep 6, 2026
8f1f3ff
Include patched code generator in Rust Docker build contexts
edulix Sep 6, 2026
ad9c598
Complete Windmill construct review and reject malformed vault keys
edulix Sep 6, 2026
bab277d
Complete Harvest, CLI and immu-board construct review
edulix Sep 6, 2026
4c6205d
Close the native workspace lint gate and preserve renderer variants
edulix Sep 6, 2026
9900463
Repair offline package installation and lock the Wasm build
edulix Sep 6, 2026
ffb9a5e
Remove Wasm compiler warnings while preserving public error values
edulix Sep 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
29 changes: 7 additions & 22 deletions .devcontainer/scripts/build-sequent-core.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,14 @@ which wasm-bindgen
wasm-bindgen --version

wasm-pack build --mode no-install --out-name index --release --target web --features=wasmtest,default_features
wasm-pack -v pack . 2>&1 | tee output.log

# The package is a dependency of the workspace packages as a directory (file:./rust/pkg),
# not as a committed tarball, so it is copied into place and yarn.lock never changes.
cd ..
hash=$(grep "shasum:" sequent-core/output.log | awk '{printf $4}')
awk -v hash="${hash}" '
/^"sequent-core@file:/ { in_sequent = 1 }
/^"[^"]+":$/ && !/^"sequent-core@file:/ { in_sequent = 0 }
/sequent-core-0.1.0.tgz#/ {
sub(/#.*/, "#"hash"\"")
}
/^ uid "/ && in_sequent {
sub(/"[^"]*"$/, "\""hash"\"")
}
{ print }
' yarn.lock > yarn.lock.tmp

mv yarn.lock.tmp yarn.lock

rm sequent-core/output.log
rm ./ui-core/rust/sequent-core-0.1.0.tgz ./admin-portal/rust/sequent-core-0.1.0.tgz ./voting-portal/rust/sequent-core-0.1.0.tgz ./ballot-verifier/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./ui-core/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./admin-portal/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./voting-portal/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./ballot-verifier/rust/sequent-core-0.1.0.tgz
for dir in ui-core admin-portal voting-portal ballot-verifier; do
rm -rf "./${dir}/rust/pkg"
mkdir -p "./${dir}/rust"
cp -a sequent-core/pkg "./${dir}/rust/pkg"
done

rm -rf node_modules ui-core/node_modules voting-portal/node_modules ballot-verifier/node_modules admin-portal/node_modules
30 changes: 6 additions & 24 deletions .devcontainer/scripts/rebuild-sequent-core-full.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,14 @@ echo "==> Building sequent-core WASM..."
wasm-pack build --mode no-install --out-name index --release --target web \
--features=wasmtest,default_features

echo "==> Packing..."
wasm-pack -v pack . 2>&1 | tee output.log

echo "==> Updating yarn.lock..."
echo "==> Placing the package where the workspace packages expect it..."
cd "$PACKAGES_DIR"
hash=$(grep "shasum:" sequent-core/output.log | awk '{printf $4}')
hash="${hash}\\\""
awk -v hash="${hash}" '
/sequent-core-0.1.0.tgz#/ {
sub(/#.*/, "#"hash"")
}
{ print }
' yarn.lock > yarn.lock.tmp
mv yarn.lock.tmp yarn.lock
rm sequent-core/output.log

echo "==> Clearing yarn cache and replacing tgz files..."
rm -Rf /home/vscode/.cache/yarn/
rm -f ./ui-core/rust/sequent-core-0.1.0.tgz \
./admin-portal/rust/sequent-core-0.1.0.tgz \
./voting-portal/rust/sequent-core-0.1.0.tgz \
./ballot-verifier/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./ui-core/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./admin-portal/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./voting-portal/rust/sequent-core-0.1.0.tgz
cp sequent-core/pkg/sequent-core-0.1.0.tgz ./ballot-verifier/rust/sequent-core-0.1.0.tgz
for dir in ui-core admin-portal voting-portal ballot-verifier; do
rm -rf "./${dir}/rust/pkg"
mkdir -p "./${dir}/rust"
cp -a sequent-core/pkg "./${dir}/rust/pkg"
done

echo "==> Cleaning node_modules and dist..."
rm -rf node_modules */node_modules dist */dist
57 changes: 57 additions & 0 deletions .github/actions/build-sequent-core-wasm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# SPDX-FileCopyrightText: 2025 Sequent Tech Inc <legal@sequentech.io>
#
# SPDX-License-Identifier: AGPL-3.0-only

name: Build the sequent-core WebAssembly package
description: >
Build packages/sequent-core to WebAssembly with the pinned toolchain and place the resulting
package in the rust/pkg directory of every workspace package that depends on it. The package
is not committed, so this runs before any yarn install in packages/.

inputs:
features:
description: Cargo features passed to wasm-pack
required: false
default: wasmtest,default_features

runs:
using: composite
steps:
- name: Set up Nix
uses: cachix/install-nix-action@v25
with:
nix_path: nixpkgs=channel:nixos-unstable

- name: Cache the Cargo registry and the WebAssembly target directory
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
packages/sequent-core/target
key: ${{ runner.os }}-sequent-core-wasm-${{ hashFiles('packages/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-sequent-core-wasm-

- name: Build the WebAssembly package
shell: bash
working-directory: packages/sequent-core
run: |
nix develop --command bash -c '
set -euo pipefail
wasm-pack --version
wasm-bindgen --version
wasm-pack build --mode no-install --release --target web --out-name index \
--features=${{ inputs.features }}
'

- name: Place it where the workspace packages expect it
shell: bash
working-directory: packages
run: |
set -euo pipefail
for dir in ui-core admin-portal voting-portal ballot-verifier; do
rm -rf "${dir}/rust/pkg"
mkdir -p "${dir}/rust"
cp -a sequent-core/pkg "${dir}/rust/pkg"
done
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,12 @@ Each release follows this general schedule:
- **Emergency patches**: Released within 24-48 hours for critical security
issues

### Security Vulnerability Reporting

If you discover a security vulnerability in the Sequent Voting Platform, please
report it responsibly by following the guidelines outlined in our
[Vulnerability Disclosure Policy](../06-technology/06-vulnerability-disclosure-policy.md).

## Version Release Lifecycle

Each major and minor version follows a structured release process that includes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ The admin portal is a React-based web application for administrative functions.
| uuid | 9.0.0 | MIT | RFC9562 UUIDs |
| web-vitals | ^5.1.0 | Apache-2.0 | Easily measure performance metrics in JavaScript |

## B3
## B4

B3 is a Rust-based component providing cryptographic utilities and core functionality.
B4 is the Rust bulletin board: the server binary and the client library the other components use to publish to and read from the board.

| Dependency | Version | License | Description |
|------------|---------|---------|-------------|
Expand Down
11 changes: 0 additions & 11 deletions docs/docusaurus/docs/06-technology/04-cyber-security.md

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
---
id: vulnerability-disclosure-policy
title: Vulnerability Disclosure Policy
---

<!--
SPDX-FileCopyrightText: 2026 Sequent Tech <legal@sequentech.io>
SPDX-License-Identifier: AGPL-3.0-only
-->

import CodeBlock from '@theme/CodeBlock';
import SecurityTxt from '!!raw-loader!@site/static/.well-known/security.txt';
import PgpKey from '!!raw-loader!@site/static/security/pgp-key.txt';

Sequent Tech welcomes reports from security researchers, consumers, election
auditors, and the general public. The security of the Sequent Voting
Platform, including the `Sequent Voting Platform - uniWAHL Version`, depends
on independent scrutiny, and we are committed to working with anyone who
reports a vulnerability in good faith.

This policy explains what is in scope, how to report, what you can expect from
us, and what we ask of you. It also publishes our OpenPGP key for
confidential reports and the machine-readable [security.txt](#securitytxt)
pointer (RFC 9116).

**Version 1.0, 2026-08-03.** The authoritative version of this policy is the
one published at
[docs.sequentech.io/docusaurus/main/docs/technology/vulnerability-disclosure-policy](https://docs.sequentech.io/docusaurus/main/docs/technology/vulnerability-disclosure-policy);
a printed or forwarded copy may be out of date. Changes are announced in the
release notes.

## Scope

We accept security reports affecting:

- Sequent Voting Platform (SVP) components documented on this site.
- The `Sequent Voting Platform - uniWAHL Version`. Reports are accepted for
the product as delivered and documented; source access is not required in
order to report a vulnerability.
- Deployment configurations and operational guidance described in these docs.

We generally do not accept reports for:

- Vulnerabilities in third-party infrastructure not operated by Sequent.
- Issues requiring physical access to consumer-managed environments (unless
explicitly in scope for your deployment).
- Social engineering, phishing, and generic denial-of-service testing against
production systems.
- Findings from automated scanners without a demonstrated security impact.

## How to report

Send your report by email to
[security@sequentech.io](mailto:security@sequentech.io). For sensitive
details, encrypt to our
[OpenPGP key](#confidential-reporting-with-openpgp).
Encryption is recommended but never required; unencrypted reports are
accepted and processed identically.

Reports arriving through any other channel are forwarded to the security team
and processed identically.

Please include, where possible:

- A clear description of the issue and its potential impact.
- Affected component(s) and version(s).
- Reproduction steps or a proof of concept (safe and non-destructive).
- Any relevant logs or screenshots, with sensitive data removed.
- Your preferred contact details for follow-up, and whether you wish to be
publicly credited.

Reports should be submitted in English (`Preferred-Languages: en`).

### Confidential reporting with OpenPGP

| | |
|---|---|
| User ID | `Sequent Security Team <security@sequentech.io>` |
| Fingerprint | `DB6B 035E 872A B5DA 90C7 194A 60D3 CBE3 0BAC 91ED` |
| Expiry | `2028-07-21` (rotated before expiry) |
| Download | [https://keys.openpgp.org/vks/v1/by-fingerprint/DB6B035E872AB5DA90C7194A60D3CBE30BAC91ED](https://keys.openpgp.org/vks/v1/by-fingerprint/DB6B035E872AB5DA90C7194A60D3CBE30BAC91ED) |
| Keyserver | [keys.openpgp.org](https://keys.openpgp.org/search?q=DB6B035E872AB5DA90C7194A60D3CBE30BAC91ED) |

<CodeBlock language="text">{PgpKey}</CodeBlock>

To import and verify the key:

```bash
curl -O https://keys.openpgp.org/vks/v1/by-fingerprint/DB6B035E872AB5DA90C7194A60D3CBE30BAC91ED
gpg --show-keys pgp-key.txt # compare the fingerprint with this page
gpg --import pgp-key.txt
```

Verify the fingerprint against a second source before use: it is also stated
in the operational user guidance and in the delivery documentation provided to
consumers. To encrypt a report:

```bash
gpg --encrypt --armor --recipient security@sequentech.io report.txt
```

The key is a role key for the Sequent security team, carries an expiry date,
and is rotated before expiry (immediately, on suspicion of compromise). Key
rotations are announced in the release notes, and the old key remains
available for decrypting reports in transit.

## What you can expect from us

- **Acknowledgement** of your report within **5 business days**.
- A point of contact and a tracking reference for follow-up and status
enquiries.
- An assessment of the report (severity is scored with CVSS v3.1) and
regular status updates until resolution.
- Remediation according to our published targets: **30 calendar days** for
critical and **60 calendar days** for high severity issues, with other
severities corrected in the next scheduled release. Where a target cannot be
met, we communicate an interim mitigation and a revised plan.
- A security advisory sent directly to every affected consumer, and a public
advisory published in the release notes of the release containing the fix.
- Credit for your finding, if you want it (see [Recognition](#recognition)).

## What we ask of you

To protect voters and running elections, we ask reporters to:

- Act in good faith: avoid privacy violations, data destruction, and
degradation of the service.
- **Never test against real elections or production environments.** Use local
or dedicated test deployments; the
[Try It Out](../10-try_it_out/01-full-standalone-deployment/01-full-standalone-deployment.md)
section explains how to run the platform yourself.
- Never access, alter, or exfiltrate real voter data or real ballots. If you
encounter personal data accidentally, stop, do not copy it, and report
immediately.
- Do not perform denial-of-service, social-engineering, or physical attacks.
- Give us a reasonable opportunity to investigate and remediate before any
public disclosure. We aim to agree on a coordinated disclosure date with
you; by default we publish coordinated advisories 7-14 days after a fix
release has been made available to affected consumers.

## Safe harbor

We consider security research and vulnerability reporting conducted in
accordance with this policy to be authorized and conducted in good faith. We
will not initiate legal action or law-enforcement complaints against you for
such research, and we waive any claims based on the circumvention of
technology controls to the extent that your research complies with this
policy. If a third party initiates legal action against you for research
conducted in accordance with this policy, we will make it known that your
actions were authorized by us.

This safe harbor does not apply to testing against production election systems
or real voter data, which is never authorized by this policy.

## Recognition

We are happy to publicly credit reporters who wish to be named. With your
permission, your name or handle is listed in the public advisory for the
finding. If you prefer to remain anonymous, we respect that.

## Security advisories and updates

Every security fix results in a new release version. Consumers affected by the
vulnerability are notified directly, at the contact registered for them when
their release was delivered.

The public advisory for a fixed vulnerability is published in the release notes
of the release that contains the fix, in the Releases section of this
documentation. It describes the nature and effect of the vulnerability, the
affected versions, and the corrective action, and it identifies no consumer. Its
publication date follows the coordinated disclosure terms above.

## security.txt

This policy and our reporting channels are published in machine-readable form
following [RFC 9116](https://www.rfc-editor.org/rfc/rfc9116):

<CodeBlock language="text">{SecurityTxt}</CodeBlock>

The version-controlled, digitally signed master copy lives in this repository
(`docs/docusaurus/static/.well-known/security.txt`), is embedded above
verbatim, and is published with this documentation site at
[https://docs.sequentech.io/docusaurus/main/.well-known/security.txt](https://docs.sequentech.io/docusaurus/main/.well-known/security.txt).
The file is clear-signed with the security team OpenPGP key, and its `Expires`
value is renewed together with the periodic key review, before it lapses.
2 changes: 2 additions & 0 deletions docs/docusaurus/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const config = {
onBrokenLinks: 'warn',
onBrokenMarkdownLinks: 'warn',

plugins: [require.resolve('./scripts/publication-build.cjs')],

// i18n, if you ever need it:
i18n: {
defaultLocale: 'en',
Expand Down
4 changes: 3 additions & 1 deletion docs/docusaurus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"raw-loader": "^4.0.2",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.8.1",
"@docusaurus/types": "^3.8.1"
"@docusaurus/types": "^3.8.1",
"cheerio": "1.0.0-rc.12"
},
"browserslist": {
"production": [
Expand Down
Loading
Loading