Security and privacy
What travels the network, where credentials are kept, how access is enforced, and how to report a vulnerability.
What travels the network
- Note content moves as opaque binary CRDT updates, not as Markdown. Each device re-derives its own
.mdfiles from them. - Attachment bytes move as themselves, either through the server or directly to S3-compatible storage.
- Presence is ephemeral and never persisted.
- Voice is played and dropped: no blob, no row, no file, no history.
Credentials
- Passwords are hashed with argon2id, and sessions are held server-side.
- A session token lives in the OS keychain, per server, which is why changing servers signs you out of the one you left.
- Sync tokens are per document and short-lived, ten minutes by default.
- MCP tokens are scoped to one person in one vault, shown once, and revocable.
Enforcement
Access is resolved on the server before a token is minted, so a client cannot open a document it was not granted. Revoking access force-closes live sockets rather than waiting for a token to expire, and the content of something you lose access to leaves your disk into a recoverable trash rather than staying readable in any editor forever.
Self-hosting posture
- Generate a real
JWT_SECRET. Rotating it invalidates every session and sync token. - Set
BETTER_AUTH_URLto the URL people actually use, since every auth link is built from it. - Serve over TLS. A bare host is upgraded to
https://precisely so credentials are not sent in the clear. - Restrict
CORS_ORIGINSif you serve any web client from another origin.
Reporting a vulnerability
Not through public issues, discussions or pull requests. Use GitHub's private vulnerability reporting on the repository's Security tab, or email the address in SECURITY.md with the subject SECURITY: Baalda. Reports are acknowledged within three business days, and credit is given once a fix ships if you want it.
Include what you can: the impact, steps to reproduce, the affected component and version, and any suggested remediation.
This page is written from SECURITY.md, docs/specs/04-team-collaboration.md and docs/DEPLOY.md in the repository. Those documents go further, and they are the ones that change first.
Read it on GitHubWas this page helpful?
