-
Notifications
You must be signed in to change notification settings - Fork 0
Security
github-actions[bot] edited this page Jul 5, 2026
·
3 revisions
Every line of Agora is written security-first, and the server is the trust boundary: it talks to Postgres as the RLS-bypassing owner role and enforces every read/write rule in the handlers, with RLS underneath as a verified backstop.
Full posture, threat model, hardening checklist, and known limitations:
docs/SECURITY.md.
- Tokens — short-lived access tokens (30 m) + refresh tokens (30 d) with rotation, reuse-detection, and a 30 s racing-tabs grace window. Auth/crypto stays in the vetted libs (jose, pinned alg).
-
Anonymous reads, authenticated writes — public content is readable without a token (matching the
contract); every mutation is
requireAuth. - Space privacy — a members-only space is invisible to non-members on every path (feed, single reads, reactions, comment creation, semantic search).
- Private chat — conversation messages are readable only by active members, enforced on the REST routes and inside the search RPC.
- End-to-end-encrypted secure chat — an optional, separate surface where the server stores only ciphertext and cannot read messages at all (deny-all RLS on every secure table). See Secure Chat.
- Moderation visibility — removed content is always hidden from non-privileged readers (omitted from lists, 404'd on single reads, filtered in the search RPC); operators bypass to review. See Governance.
-
Operators, owners/admins, stewards — a deployment-operator allowlist grants a project-wide
god-view; within-project, DB-backed
owner/admin/stewardgrants form theoperator ⊇ owner ⊇ admin ⊇ steward ⊇ memberhierarchy. -
Native-auth email links fail closed — the confirm/reset/resend flows refuse to send
(
503 auth/email-not-configured) unlessAUTH_EMAIL_LINK_ALLOWED_ORIGINSis configured, and a client-suppliedemailRedirectTois validated against that allowlist (a non-listed origin 400s) so a link is never built on an unvalidated host — an open-redirect guard. See Deployment. -
Content deletion defaults to hard (
CONTENT_DELETE_MODE=hard) — a delete truly removes the row and its uploaded media from storage, rather than tombstoning and orphaning the objects in the bucket.softkeeps the recoverable-tombstone behavior. A privacy-forward default; set per deploy. -
RLS backstop — denies
anon/authenticatedany private-space, removed, or draft row directly.
- Validate and authorize on the server for every request; fail closed.
- Wire every gate on every new path (
requireAuth, ownership, space access, moderation visibility). - Validate input with zod at the boundary; parameterize all SQL; guard outbound fetches against SSRF.
- Never leak secrets, tokens, internal ids, or another user's PII in responses, logs, or errors.
Please report privately — see the disclosure process in
docs/SECURITY.md
(GitHub private security advisory + email). Don't open a public issue for a security report.
Agora · AGPL-3.0-only · the community edition is AGPL-3.0 forever.
These pages are published from wiki/ in the main repo — edit there via PR, not in the wiki directly.
Start here
Operate
Internals
Subsystems
Project