AI Agent Gateway authorizes every agent call before it reaches a downstream system. This page is the posture behind it -- what is enforced, what is encrypted, what is logged, and the gaps we have not closed yet.
Every agent call passes a per-tool permission check in the logic layer before the call reaches the downstream system. The transport (HTTP, MCP, REST) cannot bypass the check.
Web, REST, and MCP all pass the user's permission map down to the business logic module. The module checks. No transport-level bypass.
Held in memory only. Not emitted in responses, cookies, or logs. No external system sees the shape of the key space.
Agents operate under a bearer token scoped to a subset of the owner's permissions, with TTL and per-call audit. Revocation is immediate.
Argon2id via argon2_elixir. Account locking after five failed login attempts with a fifteen-minute lockout window. Failed attempts are logged to an append-only audit table.
OAuth refresh tokens are stored encrypted with a system key held in an environment variable. Tokens are per user, not shared across accounts. Refresh runs on a fifty-five-minute cycle in a dedicated per-user process.
Sub-tokens (st_ prefix) grant a subset of the owner's permissions with a TTL. Every use updates last_used_at and use_count. Owner revocation is immediate: strip the owner of a permission and every sub-token scoped to it stops on the next request.
The Orchestrator runs on the Erlang VM (BEAM), the same runtime that powers RabbitMQ. Every per-user component -- credential refresh, chat session, MCP manager -- is its own supervised process. A crash in one process does not affect any other process.
| Property | Mechanism |
|---|---|
| Fault isolation | Per-user GenServer keyed by username in a Registry. Crash restarts under one_for_one supervision. |
| Cross-user contention | Stateless tool calls run in the caller's process; stateful calls shard per user. No single serialisation point. |
| Memory model | Message passing, no shared memory. No data races in the application layer. |
| Schedule fairness | BEAM preemptive scheduler caps per-process scheduler time. Latency tail is bounded under load. |
Every update carries the observed updated_at. If it changed between read and write, the update fails loud. No silent last-writer-wins.
Cancellations and deactivations set timestamps rather than destroying rows. Auditors can reconstruct state after the fact.
Every row id is System.system_time(:millisecond) at insert. Creation time is free on every row.
Every deployment is a dedicated instance on a customer-owned or customer-dedicated host. There is no shared process tree and no shared database across customers.
Runs inside your VPC, data centre, or fully isolated network. No telemetry, no phone-home, no third-party services required to operate.
We operate the instance on a dedicated host. No multi-tenant process or storage. Your data never touches another customer's runtime.
HTTPS only in production. Certificate and key paths are supplied at deploy time via environment variables.
SECRET_KEY_BASE, COOKIE_SALT, and the system encryption key are read from the environment at boot. They are never written to disk by the application.
This list exists because an auditor should see it. Each item is named, localised, and does not require an architectural rewrite to close.
| Gap | Impact | Status |
|---|---|---|
| Permission-invalidation push | Session processes cache the permission map; grant/revoke propagates on next request, not immediately. | Designed, not shipped. |
| WebSocket auth in URL query param | Pre-alpha shortcut. Tokens land in access logs. Not exposed externally today. | Must fix before external access. |
| Load-test numbers | Per-user model has not been benchmarked under realistic concurrent agent load. | Planned. |
| Tidewave introspection key | Development-only MCP server uses a static dev key. Gated by Mix.env() == :dev. |
Needs rework before any remote access. |
| Compliance certifications | SOC 2 Type 2, ISO 27001, HIPAA attestations not yet obtained. | Architecture is designed to pass; paperwork is next. |
The codebase is open to inspection under NDA. The architecture is documented. The gaps are named. Bring your diligence team.