Security Overview
Security in AnvilBase is on by default and layered. The design goal is strong tenant isolation — no project can read or write another project’s data — backed by defense in depth so no single failure leaks data.
Principles
- Default deny at every boundary (network, API, database, storage, runtime).
- Tenant isolation first — cryptographic and physical separation between projects.
- Least privilege — scoped API keys, short-lived tokens, role-gated operators.
- Defense in depth — RLS and routing isolation and encryption and audit.
- Self-hostable — every control works without an external SaaS dependency.
- Verifiable — immutable audit logs and a testable RLS sandbox.
Trust boundaries
Public Internet │ (1) TLS terminates here ▼Traefik │ (2) only the gateway is exposed ▼Control Plane ──(3)──► Internal services (Postgres, Valkey, MinIO, Realtime, Deno) │ ▲ │ (5) tenant config │ (4) edge functions egress boundary ▼ │Secrets vault (pgcrypto) ──(7)┘Database ──(6)──► RLS & schema isolation (the primary data line)- Internet → Traefik (edge TLS)
- Traefik → control-plane APIs
- Gateway → internal services
- Edge functions → outbound networks (egress/SSRF control)
- Tenant code/config → control plane (provisioning, secrets)
- Database → RLS & schema boundaries (the main data-isolation line)
- Secrets vault → services (key material boundary)
The defaults that protect you
| Control | Default | Page |
|---|---|---|
| Row Level Security | enabled on every created table (fail-closed) | RLS |
| Encryption at rest | LUKS (Postgres), SSE-S3 (storage), pgcrypto (secrets) | Encryption |
| Encryption in transit | TLS at the edge; optional internal mTLS | Network Security |
| API key scopes | anon/authenticated/service_role, RLS-aware | API Keys & Scopes |
| Cache isolation | per-project Valkey ACL user proj_<pid> physically confined to the <project_id>:* keyspace | Cache / KV |
| Edge function auth | verify_jwt: true by default | Functions |
| Management plane | fail-closed (401 without a valid credential) | Concepts |
| Webhook targets | SSRF guard (no loopback/RFC1918/metadata) | Webhooks |
| Destructive DDL | requires name-echo confirmation | Tables & Schema |
| Audit logging | every administrative action recorded | Audit Logs |
How isolation is enforced (twice)
- At the routing layer — the control plane resolves the project from the
credential and only ever routes to that project’s database, bucket, cache
namespace, and queue namespace. A credential for project A cannot address
project B. Cross-tenant id guessing returns
404(IDOR-safe). - Inside Postgres — RLS evaluates policies against the injected user/role context, so even within a project a user only sees permitted rows.
See Multi-Tenancy for the full isolation matrix.
Two credential systems
- Management plane (
/api/v1) — admin token or Personal Access Token; for operators/console/CLI. Fail-closed. - Data plane (
/v1) — per-project API keys and user JWTs; for applications.
They’re not interchangeable. Concepts → The two API planes.
Read next
- Row Level Security — the core data-access control.
- API Keys & Scopes — what each key can do and how to rotate.
- Multi-Tenancy & Isolation.
- RBAC & Team Management — who can operate what.
- Encryption, Audit Logs, Network Security.
- Operational hardening: Production Checklist.