System overview
The complete stack has five application services and two stateful dependencies. Each external interface accepts a different credential class and has a deliberately bounded job.
Browser
→ Next.js dashboard
→ management API
→ Postgres
App or agent + Gate Token
→ request gateway
→ policy + budget + active credential
→ provider adapter
→ upstream API
MCP client + MCP session token
→ MCP server
→ read tools or access request
→ Postgres
Worker
→ expiration, rollups, alerts, reconciliation
→ PostgresApplication services
- Dashboard
- A Next.js interface for setup, Provider Vault, Gate Tokens, policies, requests, usage, budgets, audit, and settings.
- Management API
- An authenticated service for sessions and administrative operations. It performs role checks and writes audit events.
- Gateway
- The hot path for provider traffic: token verification, route normalization, policy, rates, budget reservation, credential unlock, proxying, and events.
- MCP server
- A JSON-RPC 2.0 streamable HTTP surface for actor-bound read tools and structured token requests. It never receives the provider master key.
- Worker
- Runs token and request expiry, abandoned reservation cleanup, usage rollups, budget alerts, and supported provider cost reconciliation.
Stateful dependencies
Postgres
Postgres is the system of record for organizations, users, projects, apps, actors, provider integrations and encrypted credentials, tokens, policies, budgets and reservations, usage, denials, access requests, MCP sessions, kill switches, and audit events.
Budget reservation and settlement use atomic database operations so concurrent requests do not all pass one stale spend check.
Redis
Redis backs fixed-window request rate limiting across gateway instances. Production tokens fail closed when the limiter cannot be evaluated. Development fail-open behavior exists only behind an explicit configuration setting and is disabled by default.
Provider request flow
- Assign a request identifier and extract the bearer Gate Token.
- Parse its kind, public identifier, and secret; load the candidate by public identifier.
- Verify the peppered token HMAC in constant time, then check status and expiration.
- Load and validate the attached policy. A missing or malformed policy denies the request.
- Resolve the provider from the native route, provider header, model prefix, or one unambiguous allowed provider.
- Ask the adapter to normalize a known method and path to a capability. Unknown paths deny.
- Evaluate allow and deny rules, required metadata, environment, and model or endpoint boundaries.
- Apply configured request rates and reserve a conservative estimate against applicable budgets.
- Load and decrypt the active upstream credential in gateway memory.
- Build provider-native authentication, forward the request, and pass streaming responses through.
- Extract available usage, settle reservations, and write the usage event.
Management and secret flow
authenticated admin
→ create provider integration
→ submit candidate credential
→ management API encrypts before storage
→ test candidate through implemented adapter
→ activate candidate
→ previous active credential becomes retiring
→ revoke old credential after verificationThe management API needs the encryption key to accept and test provider credentials. The gateway needs it to proxy. The worker needs it only for supported reconciliation jobs. The dashboard browser and MCP service do not receive it.
Credential boundaries
- Browser session
- Authenticates the management API. It is not accepted as provider-gateway or MCP authorization.
- Gate Token
- Authenticates one policy-bound provider identity. It cannot call management endpoints or authenticate directly to a provider.
- MCP session token
- Authenticates one known actor and permission level to MCP tools. It does not reveal provider credentials.
- Provider credential
- Accepted by an upstream provider and therefore the highest-value integration secret. It remains behind the gateway.
- Application secrets
- Sign browser sessions, verify Gate Tokens, and encrypt stored credentials or one-time MCP collections. Keep each purpose separate.
Failure behavior
Dashboard unavailable
Management UI is unavailable; the independent gateway can continue serving provider requests.
Management API unavailable
Admin reads and changes stop; the gateway does not depend on the management API in its hot path.
Worker unavailable
Rollups, cleanup, alerts, and reconciliation lag; request proxying and raw event writes continue.
Postgres unavailable
The gateway cannot validate the current token, policy, credential, kill state, or hard budget and fails closed.
Redis unavailable
Rate-limit behavior follows the token environment and explicit fail-mode configuration; production fails closed.
MCP unavailable
Agent tools and requests stop; existing Gate Tokens can continue through the separate gateway.
Provider unavailable
The gateway returns a safe provider error, releases or settles reservations, and records the request outcome.
Default deployment shape
The repository’s full Docker Compose profile builds and starts the application services with Postgres and Redis. Published interfaces bind to loopback by default, while the management API and worker remain internal to the Compose network.
docker compose --profile full up -d --build