Reference
Security and privacy
What is protected, how, what is stored about you, and what is kept forever.
This page describes what Democratia protects, and equally what it does not. Both matter.
Accounts and roles
Every account is either a member or an administrator. Members own the polls they create and take part in the polls they are invited to. Administrators additionally reach every poll and manage every account — but not unpublished totals, and not a private poll's ballot box. The reasoning is in Roles and administration.
The role cannot be granted through a form, a link or an address. An administrator is made by another administrator, from the administration area, or by whoever set the installation up — and every change is recorded with the administrator who made it.
Registration is open to anyone, and always creates a member. Passwords are hashed, and never stored or logged in any recoverable form. Changing your password requires your current one.
A confirmed email address is required to create or manage a poll and to vote. Until you confirm, you can sign in and see a banner asking you to. Reading a public poll is unaffected: no account is needed for that at all.
Failed sign-ins are throttled per email address and per IP address, with a clear message telling you how long to wait. The same applies to registration, password resets, submitting an option, submitting a ballot and searching for people to invite.
Your session identifier is regenerated when you sign in and again when you sign out, so a session identifier obtained before you signed in cannot be used afterwards.
Poll links
A public poll's link contains a 32-character random identifier — around 190 bits of entropy, generated by a cryptographic random source. Guessing one is not feasible.
Sequential database identifiers never appear in a participant link, and no owner secret is ever placed in a URL. Management pages are protected by your session plus an authorization check on every request, not by a secret in the address.
If a link leaks, the owner can regenerate it. The old address stops working immediately.
Authorization
Every action is checked on the server: viewing a poll, editing it, managing options, submitting an option, managing invitations, taking part, submitting or editing a ballot, viewing results, exporting results, regenerating the link and every lifecycle transition.
The rules account for the owner, an administrator, an invited participant, a signed-in stranger, a visitor with no account, the poll's phase, its access mode and whether results are published.
Where the line falls is visible in the code: the two checks that answer "may this be read" accept a nullable user, and every other check requires a real one — so the Gate refuses a visitor without an account before the rule is even evaluated.
A hidden button is not a control. Buttons are hidden to keep the interface clean; the server refuses the action regardless. The whole authorization matrix is tested directly rather than through the interface.
Result secrecy
Results are unreachable before publication, and this is enforced three separate times so that no single mistake could leak a number:
- The authorization rule refuses, including for the owner.
- The code that calculates totals refuses to run for an unpublished poll — so even an internal mistake cannot compute one.
- No page contains hidden result markup, and no results link is rendered.
The organiser can see turnout during voting — how many were invited, identified and voted — but never option totals. Neither can an administrator: result secrecy is a phase rule, so it applies to every role without exception.
Ballot integrity
The database, not just the application, enforces:
- one ballot per participant per poll,
- one preference per option on a ranked ballot,
- one option per position on a ranked ballot,
- one selection per option on an approval ballot,
- and that an option any ballot refers to cannot be deleted.
That last one is what makes options genuinely immutable once voting starts. The application refuses too, but the database is what makes it impossible.
There are exactly two ways past it, and neither is a way around it. An owner who moves the schedule back to option collection deletes every ballot on the poll, in the open, after confirming it and with everyone taking part notified. An administrator who permanently deletes an archived poll destroys its ballots along with everything else it held. In both cases the options become removable because the ballots are already gone — never while they exist. See The poll lifecycle.
A double-clicked submission produces one ballot, not two, and not an error.
Private poll secrecy
Someone who was not invited is told the poll does not exist, not that they are forbidden. "Forbidden" would confirm a poll exists at that address — that a decision is being made, and roughly when. Drafts behave the same way.
What is stored about you
If you have an account: name, email address, hashed password, language, theme, layout and leaderboard preferences, your points ledger, and which polls you own, were invited to and took part in.
If you took part before accounts were required: the display name you chose, and a SHA-256 hash of a random token whose plaintext no longer exists. That is all. No email address. No IP address. No fingerprint. No user agent.
Democratia does not fingerprint browsers, and does not use IP addresses to identify participants.
What is kept, and for how long
Ballots are kept indefinitely. Deleting one would change a result — possibly one already published — and destroy the audit trail. So a submitted ballot is never silently removed.
Revoking someone's access keeps their ballot, and records that it was preserved. They lose access and cannot change it. Deleting it would let an organiser change a result by removing voters.
Cancelling a poll keeps everything. Only a draft can be deleted, and a draft cannot have ballots.
Activity logs record who did what and when, plus identifiers and counts. They never contain participant tokens, ballot contents or option totals.
The points ledger is append-only. Points that stop being valid are reversed with a matching negative entry rather than deleted, so a balance always adds up. The internal note recording why a reversal happened is never shown publicly.
Logs never contain a raw participant token or any vote total before publication.
Account deletion is not implemented, and this is an honest gap rather than an oversight. Owning a poll or having participated blocks deletion at the database level, by design. Supporting it properly needs an anonymisation policy — replace the name, keep the ballot — and that is a decision this release has not made.
Content safety
Everything anyone types is escaped when displayed. A description containing <script> shows as text.
No user-supplied HTML is ever rendered, anywhere.
Every state-changing form carries a CSRF token. Cookies are HTTP-only and SameSite=Lax, and secure in
production. Preference changes return you only to a page on this site, so a crafted referrer cannot
bounce you elsewhere.
Reporting something
If you find a security problem in a Democratia installation, report it to whoever runs it rather than filing it publicly.