Yours, and only yours
One person runs Papyra for themselves, their family, or a small team. Privacy between those people has to be real, not a filter on a shared list.
Each account has its own folder, and cannot leave it
Every account’s notes live in their own directory, and every path the API resolves is checked against that directory before anything is read or written. A crafted note id cannot walk up and out into someone else’s vault; the request is refused. This is enforced at the storage layer rather than by filtering query results, so it holds even for code paths nobody thought about.
Personal access tokens inherit the same jail as the account that created them.
Vault notes are locked by the server, not by CSS
Mark a note as secure and it becomes a Vault note. Its body is withheld by the API — a request for the note returns the metadata and an empty body — until you unlock it with a passkey: your fingerprint, your face, your hardware key. Unlocking issues a short-lived token that the server checks before it will send the text.
The blur you see is cosmetic. The lock is that the bytes were never sent. A locked note is also never shareable and never delivers a mention.


Signing in
Passwords are hashed with BCrypt. Sign-in attempts are throttled per account, and the auth endpoints are rate-limited per IP.
Passkeys can be registered per device for the Vault.
Single sign-on speaks OIDC, with accounts provisioned on first login. Crucially it is configured from the admin UI at runtime and takes effect without a restart — no editing a config file inside a container to change an identity provider. If the provider is unreachable, Papyra says so in words, naming the setting to check, rather than returning a bare 502.
Accounts an admin created or reset must choose a new password before the API will let them do anything else. A password somebody else chose is a password somebody else knows.
Getting your notes out, automatically
Your notes are already plain files, so backup is a question of convenience rather than possibility. Papyra offers three routes:
- Zip export of the whole vault, on demand.
- Encrypted backups — AES-GCM with a key derived from a password you choose. Generate one, and restore from it later.
- Git backup per account, using a real git implementation rather than shelling out. It commits and pushes on a schedule to a remote you nominate, and it will never force-push over a diverged remote — if history has moved apart it stops and tells you, instead of overwriting whatever is there.
Webhooks are signed with an HMAC so the receiver can verify a delivery genuinely came from your instance.
The rest of the posture
Security headers and a Content-Security-Policy are set on every response. When
Papyra runs behind a reverse proxy, it only trusts forwarded headers from
proxies you have explicitly listed — an unlisted proxy cannot spoof a client IP
past the rate limiter. Session cookies are HttpOnly and Secure in
production. Data-protection keys are persisted to the data volume, so restarting
the container does not sign everybody out.
Papyra is GPL-3.0. You can read all of this rather than take our word for it.