vote.direct Election security, explained Download the two-page PDF

Elections built to survive a challenge.

Every election here writes a permanent, verifiable record of itself as it runs. This page shows the machinery in plain terms: what gets recorded, why nothing can change quietly, and what still holds up when someone disputes the result. The claim is not that tampering is impossible. The claim is that tampering cannot succeed silently.

SHA-256 hash chain on every election Append-only log, enforced by the database Every ballot fingerprinted at the moment it is cast Re-verified nightly, anomalies page the founder
01 The chain

Every action becomes a link in a chain

When anything happens in an election, the database itself writes an entry: the ballot goes live, a member votes, a deadline moves, the count freezes. Each entry gets a SHA-256 fingerprint, and each fingerprint includes the fingerprint of the entry before it. That is the whole trick. Change any entry, even one character, and its fingerprint no longer matches. Every entry after it points at a fingerprint that no longer exists.

The log is append-only. The database refuses edits and deletions of past entries for everyone, including us. We tested that refusal against our own administrator access.

This is a live model of six real entries. Click any entry to edit it and watch the verification respond. Click it again to restore it.

✓ Chain verifies: 6 of 6 entries recompute correctly.

On a real election this check is not a demo. It is a button on the dashboard, a line on the results certificate, and a job that re-runs every night.

02 The ballot

Every ballot is fingerprinted the moment it is cast

A chain of events proves what happened. It does not by itself prove that a stored ballot still says what the voter marked. So in the same instant a ballot is stored, the database computes a fingerprint of its content and commits that fingerprint into the chain. The fingerprint is salted with a secret value held on the ballot record, which means reading the log never reveals how anyone voted, not even for a simple yes or no question.

From then on, anyone with access can recompute: take the stored ballot, recompute its fingerprint, compare it with what the chain recorded at cast time. We ran this drill in production: edited a stored answer directly in the database, and the verification named the exact ballot that no longer matched. Then we restored it and the record verified clean again.

Ballot cast one transaction Stored ballot answers + secret salt Chain entry ballot_recorded: a1f4… Verification recompute, must match writes commits fingerprint ballot today promise at cast
One transaction stores the ballot and commits its salted fingerprint into the chain. Verification recomputes from the stored ballot and compares against the cast-time promise. An edited ballot fails by name.
03 The watchers

The changes people actually worry about are watched

Disputes rarely start with "the ballots were forged." They start with "the deadline moved when our side was winning" or "her vote counted for five, mine for one." So the database watches the sensitive record itself. These entries are written by triggers inside the database. No application code path can skip them.

vote_settings_changed

The deadline, quorum rule, eligibility, or secrecy setting of a live election changed. The entry records the old value and the new value.

voter_record_changed

A voter's weight or contact identity changed mid-election, with a flag for whether they had already voted. Identity changes are recorded as fingerprints, so the log itself never leaks a roster.

voter_status_reverted

A member who had voted was marked as not having voted. No legitimate flow does this. If it ever appears, it is the first question to ask.

voter_record_removed

A member was removed from the roster of a running election, including whether they had already cast a ballot.

ballot_recorded

A ballot's content fingerprint, committed at cast time. The promise every later recount is checked against.

results_frozen

The final count froze, with its own fingerprint. The results row is then write-once: the database refuses any later change to it.

04 Sealed ballots

Sealed elections separate who from what, permanently

Some statutes, including California's and Florida's for association elections, require that a ballot can never be connected back to a member. For those elections we offer sealed ballots: the ballot is stored with no reference to the voter at all. The poll book records that a member voted. The ballot box holds ballots. Nothing joins the two, and the chain names who voted, never which ballot.

Because there is no per-ballot link, sealed ballots are protected as a box rather than one by one. When voting closes, the box is shuffled and rewritten in random order, and a checksum of the whole box is computed before and after. The two must match or the close refuses to happen. That checksum enters the chain, and every later check recomputes the box against it.

Poll book Ballot box Unit 12 voted ✓ Unit 31 voted ✓ Unit 07 voted ✓ Unit 44 not yet ballot · no name ballot · no name ballot · no name shuffled at close NOTHING JOINS THE TWO checksum must match chain at close
The chain records who voted on the left side and protects the whole box on the right side. Row order, timestamps, and receipts are all coarsened or withheld so they cannot recreate the link. The tally opens only after close.
05 The freeze and the signature

Closing freezes the count, and a named person signs it

When an election closes, the results are computed once and frozen with their own SHA-256 fingerprint. The database refuses any later change to the frozen results, and the fingerprint itself enters the chain as results_frozen.

Where an inspector of elections is appointed, a named human being reviews and certifies. Their signed certification records the results fingerprint, the ballot count, and the head fingerprint of the entire chain at the moment of signing. A person put their name on a specific version of history. Rewriting that history later means contradicting a signature that already left the building.

06 The copies

Copies leave the building

Here is the honest limit, stated before you have to ask. A hash chain has no secret key. Someone with total control of the database could, in theory, rewrite the whole story and recompute every fingerprint so it self-verifies. What defeats that is not more math inside the same database. It is copies outside it.

Every results certificate prints the chain head fingerprint and entry count. Audit packages carry the full log to inspectors and auditors. Voters hold their own confirmations. Board packets get printed and emailed. A rewrite would have to be consistent with every copy already in other people's hands, and it cannot be. The database cannot un-print a PDF.

The database chain head: 7c19f2… Results certificate · printed, filed Audit package · inspectors, auditors Inspector's signed certification Voter confirmations · in inboxes carries the chain head out
The chain head travels outward on every document the election produces. A rewrite inside the database fails against paper and inboxes it cannot reach.
07 The night shift

A machine re-checks everything, every night

Tamper-evident records only matter if someone is looking. Every night, a sweep re-verifies every election's chain, recomputes every ballot fingerprint against its stored ballot, and checks every closed sealed box against the checksum recorded when it was sealed. Any anomaly raises an alert and emails the founder the same day. A sweep that fails to run is itself treated as an alert. Silence never reads as health.

· Who can change what

Four levels of access, one honest table

If this person tried…What they can doWhat they cannot do quietly
A voter Cast their own ballot. Hold their own confirmation. Verify their ballot was recorded. Vote twice, vote as someone else, or see anyone else's ballot. Eligibility, one-ballot rules, and verification are enforced before a ballot is accepted.
An organizer Run the election: roster, schedule, reminders. Move a deadline. Fix a voter's record. Change any of that invisibly. Every sensitive change lands in the chain with old and new values. Ballot content and frozen results are never editable, and on anonymous or sealed elections the organizer never sees how anyone voted.
vote.direct, operating the platform Everything an organizer can, plus support access, which is itself chain-logged. Edit or delete a past log entry. The database refuses the write, for us too. We tested the refusal with our own administrator access, and the nightly sweep would name any exception.
Someone with total database control In theory: rewrite the whole record and recompute every fingerprint. Make the rewrite agree with the certificates, audit packages, signed certifications, and confirmations that already left the building. Copies outside the database are the final control.
· On purpose

What we will not do

· In your hands

The records you can hold

Results certificate

The outcome, participation, verification methods, the chain head fingerprint, and the integrity status. Made for the board packet.

Audit package

The full chained log, reconciliations, ballot fingerprint checks, and the sealed box comparison. Made for inspectors and auditors, sealed by its own fingerprint.

Inspector certification

A named person's signed statement binding the results fingerprint and the chain head at the moment of signing.

Voter confirmation

Each voter's own proof their ballot was recorded, held by them, not by us.