Skip to content

Core Concepts

A short glossary-with-context. Everything else in these docs assumes you know these terms.

Deployment, instance, control plane

A deployment (or instance) is one running AnvilBase stack — the Docker Compose project or Kubernetes release. The control plane is the Rust service at its center; it’s what every client talks to. One deployment hosts many projects.

Project

A project is an isolated tenant. Creating one provisions:

  • a dedicated Postgres database platform_<project_id>,
  • a dedicated storage bucket bucket-<project_id> with its own encryption key,
  • a unique JWT secret,
  • an anon key and a service_role key.

Every project has a UUID (id) and a human slug (e.g. my-app). Most endpoints are addressed by the UUID. Deleting a project soft-deletes it and deprovisions the database and bucket in the background.

Terminal window
# Create a project (management plane)
curl -X POST http://localhost:39001/api/v1/projects \
-H "Authorization: Bearer $ANVILBASE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"My App"}'

The create response is the only time you see the jwt_secret and service_role_key — store them immediately. See Your First Project.

The two API planes

This is the single most important distinction in AnvilBase.

Management plane — /api/v1/*

The control surface: provisioning projects, configuring auth, managing users, wiring webhooks/email, running DDL/migrations, rotating secrets, reading stats and audit logs. Used by operators, the console, and the CLI.

  • Credential: an admin token (the value of the ANVILBASE_ADMIN_TOKEN env var) or a Personal Access Token (anvilbase_pat_…).
  • Sent as Authorization: Bearer <token>.
  • Fails closed — no valid credential means 401. There is no anonymous management surface.

Full catalog: Reference → Management API.

Data plane — /v1/*

The application surface: REST-over-SQL reads/writes, storage, auth flows, edge-function invocation, realtime, and eIDAS wallet flows. Used by your apps and your end users.

  • Credential: a per-project API key (anon / service_role) or a project JWT issued by Better Auth.
  • Sent as apikey: <key> and/or Authorization: Bearer <jwt>.

Full catalog: Reference → Data-Plane API.

Keys are not interchangeable across planes. A service_role key is a data-plane key and is not valid on /api/v1. A PAT is a management-plane credential and is not a data-plane key. Mixing them up is the most common first mistake.

API keys and scopes

Each project is born with two data-plane keys. They map to Postgres roles and determine how RLS treats the request.

KeyScopeBypasses RLS?Belongs in
anonanonNoClient code (browser, mobile, public)
service_roleservice_roleYesServer-side code only

A logged-in end user presents a JWT instead, which carries the authenticated scope and their user id. The key format is anvilbase_<scope>_<slug>_<random>.

  • The anon key is safe to ship in client bundles — by itself it can only read what RLS policies allow, and fresh tables have RLS on with no policies (so nothing is readable until you write a policy).
  • The service_role key bypasses RLS entirely — treat it like a database superuser password. Never put it in a browser or mobile app.

See Security → API Keys & Scopes.

JWTs and RLS context

When an end user signs in, Better Auth issues a JWT signed with the project’s JWT secret. On each data-plane request, the control plane validates the JWT and injects context into the Postgres session before running your query:

SET LOCAL ROLE authenticated;
SET LOCAL app.current_user_id = '<user-uuid>';
SET LOCAL request.jwt.claims = '{...}';

Your RLS policies read that context (e.g. author_id = current_setting('app.current_user_id')::uuid) to decide which rows the request can see. This is the core of the security model — see Row Level Security.

Roles (two kinds)

Per-project end-user roles (used in RLS and keys): anon, authenticated, service_role.

Platform operator roles (who can administer the deployment): super_admin, project_admin, developer, viewer.

Project membership roles (team management): owner, admin, editor, read_only. See RBAC & Team Management.

Isolation

“Isolation” in AnvilBase means complete, cross-layer separation between projects — separate database, bucket, secret, cache namespace, and queue namespace. It is enforced at the routing layer before any service is reached, and again by RLS inside Postgres. See Multi-Tenancy.

Secrets vs. the secrets vault

Two different things:

  • Deployment secrets live in .env (database passwords, the control-plane signing secret, etc.) and configure the stack. See Configuration.
  • The secrets vault is a per-project, encrypted key-value store for your application’s secrets (API keys, connection strings), accessible to your edge functions and code. See Secrets Vault.

Environments (dev / staging / prod)

The CLI models multiple deployments as environments declared in anvilbase.toml (topology only — no secret values). anvilbase deploy staging promotes schema + secrets + functions to a named environment, with CI as the approval gate. See CLI Reference.

Next: Getting Started → Installation.