Security
Auth at the edge (Bearer / X-API-Key), namespace and agent isolation, the loopback admin surface, and network posture.
Threat model
Brain stores user-generated content, some of it sensitive ("the user's home address is…"). The model assumes:
- Hostile clients — anyone with network access to the data plane.
- Trusted operators — people with volume access, config/secret access, and container shell access. Operators can read stored data; Brain is not a zero-knowledge system. Limit operator access with standard infrastructure controls.
- External LLM provider — Brain sends text to the configured provider for HyPE and extraction. Treat the provider as external egress and scope its key tightly.
Authenticating callers
Clients authenticate with a bearer key, sent one of two equivalent ways:
Authorization: Bearer <key>X-API-Key: <key>Both carry the same key. There is no legacy rcall_-prefixed key format and no X-Recall-* headers — those belonged to an earlier product name and are gone. On the binary wire protocol, the key is sent as a token credential after the WELCOME handshake (mTLS is also supported at that layer).
Namespace and agent isolation
A key resolves to an identity: a namespace (the company / tenant) and an agent (the app). Isolation is per-(namespace, agent) across every layer — a caller sees only the memories, entities, statements, and relations within its own scope. This is the tenancy boundary; enforce it by minting a distinct key per tenant and per app, never sharing one key across tenants.
The admin surface
The admin HTTP surface (/v1/* — key mint/revoke, stats, snapshot operations) is separate from the data plane and, by default, binds to loopback only (127.0.0.1:9092 inside the container). It is deliberately not published by the image or Compose file.
- Reach it from the host with
docker exec brain .... - If you must reach it remotely, front it with a token/mTLS reverse proxy — never publish the raw port.
- The admin listener is gated by an operator token (
[admin] token/BRAIN__ADMIN__TOKEN) and refuses to start without one. Never ship the placeholder token from the default config.
The admin plane has no per-user auth of its own beyond the operator token. Its safety comes from being on loopback. If you expose it, you are responsible for the proxy in front of it.
Network posture
The container exposes three surfaces; treat them differently:
| Surface | Default bind | Publish? |
|---|---|---|
| Data plane (wire protocol) | 0.0.0.0:8080 | Yes — behind TLS termination / a gateway. |
| Health + metrics HTTP | 0.0.0.0:9091 | Internal only — /healthz, /metrics. Keep off the public internet. |
Admin HTTP (/v1/*) | 127.0.0.1:9092 | No — loopback; docker exec or a trusted proxy. |
brain-server speaks plaintext on the data plane; terminate TLS at a load balancer / gateway (NGINX, Caddy, an ALB) in front of :8080. Don't expose :8080 to the internet without TLS — the auth token flows over the wire otherwise.
Outbound, the server needs egress only to the configured LLM provider API (for HyPE + extraction) and, if tracing is enabled, an OTLP collector. There is no database, cache, or vector-store egress to allow — everything else is in-process. Lock down the rest at the security-group / firewall layer.
Key hygiene
- The bearer key is a secret — inject it into clients from a secret store, not source or client bundles.
- Rotate by minting a new key and revoking the old one via the admin surface.
- Scope keys per tenant/app so a leaked key blasts only its own namespace/agent.
Secrets management
Don't put the LLM provider key or the admin token in plain files in production.
| Platform | Pattern |
|---|---|
| Kubernetes | Secret → envFrom: secretRef |
| Docker Compose | External secrets via the secrets: block |
| AWS | Secrets Manager + IAM role on the task |
| GCP | Secret Manager + service account on the revision |
| Vault / Doppler / Infisical | Agent or CLI injects env at container entrypoint |
brain-server reads env once at boot and never persists it to disk; rotating a secret requires a restart.
Compliance notes
- Right to erasure — a hard
FORGETzeroes a memory's slot immediately rather than waiting out the tombstone grace window; the content is unrecoverable afterward. - Certifications — self-host compliance posture is your responsibility; managed cloud carries its own certifications.
Was this page helpful?