Skip to content

Commit 208837d

Browse files
docs: add agent control auth reference
1 parent 87897c1 commit 208837d

4 files changed

Lines changed: 179 additions & 1 deletion

File tree

core/authentication.mdx

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: Authentication
3+
description: Auth modes, HTTP upstream authorization, namespace scoping, and runtime JWT claims.
4+
icon: "shield-check"
5+
---
6+
7+
Agent Control keeps authentication and authorization provider-neutral. The server asks a
8+
configured provider whether a request may perform an operation, then scopes all data access with
9+
the returned `Principal`.
10+
11+
## Operations
12+
13+
Operations are stable strings. Deployers map them to their own permission model.
14+
15+
```text
16+
controls.read
17+
controls.create
18+
controls.update
19+
controls.delete
20+
policies.read
21+
policies.create
22+
policies.update
23+
agents.read
24+
agents.create
25+
agents.update
26+
evaluators.read
27+
observability.read
28+
observability.write
29+
control_bindings.read
30+
control_bindings.write
31+
runtime.token_exchange
32+
runtime.use
33+
```
34+
35+
## Principal
36+
37+
Providers return a generic principal. Agent Control treats `namespace_key`, `caller_id`,
38+
`target_type`, and `target_id` as opaque strings.
39+
40+
```json
41+
{
42+
"namespace_key": "tenant-a",
43+
"is_admin": false,
44+
"caller_id": "user-or-key-id",
45+
"target_type": "session",
46+
"target_id": "target-123",
47+
"scopes": ["runtime.use"],
48+
"expires_at": "2026-05-11T15:00:00Z"
49+
}
50+
```
51+
52+
`namespace_key` is the tenancy boundary. Server queries filter by it, and namespace-aware foreign
53+
keys prevent cross-namespace references.
54+
55+
## Auth Modes
56+
57+
Management auth is selected by `AGENT_CONTROL_AUTH_MODE`.
58+
59+
| Mode | Meaning |
60+
| --- | --- |
61+
| `none` | No credentials required. Intended for local development only. |
62+
| `api_key` | Validate caller credentials locally with `AGENT_CONTROL_API_KEYS` and/or `AGENT_CONTROL_ADMIN_API_KEYS`. Requires `AGENT_CONTROL_API_KEY_ENABLED=true`. `header` is accepted as a backwards-compatible alias. |
63+
| `http_upstream` | POST each management authorization decision to `AGENT_CONTROL_AUTH_UPSTREAM_URL`. |
64+
65+
When `AGENT_CONTROL_AUTH_MODE` is unset, startup selects `api_key` if local API-key validation is
66+
enabled and `none` otherwise.
67+
68+
Runtime auth is selected by `AGENT_CONTROL_RUNTIME_AUTH_MODE`.
69+
70+
| Mode | Meaning |
71+
| --- | --- |
72+
| unset | Use `jwt` when `AGENT_CONTROL_RUNTIME_TOKEN_SECRET` is set. Otherwise runtime requests fall through to management auth. |
73+
| `none` | No runtime credentials required. Intended for local development only. |
74+
| `api_key` | Validate runtime requests with the same local API-key mechanism. |
75+
| `jwt` | Require target-bound runtime tokens minted by `/api/v1/auth/runtime-token-exchange`. |
76+
77+
Common combinations:
78+
79+
| Management | Runtime | Use case |
80+
| --- | --- | --- |
81+
| `api_key` | unset | Existing standalone deployments. |
82+
| `api_key` | `jwt` | Local management keys with short-lived target-bound runtime tokens. This does not perform per-target authorization; any valid local API key can exchange for any target in the local namespace. |
83+
| `http_upstream` | `jwt` | External identity or authorization service for management, local token verify for high-volume runtime calls. |
84+
| `none` | `none` | Single-process local development. Do not use in production. |
85+
86+
## HTTP Upstream Contract
87+
88+
When `AGENT_CONTROL_AUTH_MODE=http_upstream`, the server sends:
89+
90+
```text
91+
POST {AGENT_CONTROL_AUTH_UPSTREAM_URL}
92+
```
93+
94+
```json
95+
{
96+
"operation": "control_bindings.write",
97+
"context": {
98+
"target_type": "session",
99+
"target_id": "target-123"
100+
}
101+
}
102+
```
103+
104+
The provider forwards inbound `X-API-Key`, `Authorization`, and `Cookie` headers. Add
105+
deployer-specific header names with `AGENT_CONTROL_AUTH_UPSTREAM_EXTRA_FORWARD_HEADERS`, for
106+
example:
107+
108+
```text
109+
AGENT_CONTROL_AUTH_UPSTREAM_EXTRA_FORWARD_HEADERS=Vendor-API-Key,X-Workspace-Id
110+
```
111+
112+
If `AGENT_CONTROL_AUTH_UPSTREAM_SERVICE_TOKEN` is set, it is forwarded on
113+
`AGENT_CONTROL_AUTH_UPSTREAM_SERVICE_TOKEN_HEADER` or `X-Agent-Control-Service-Token` by default.
114+
115+
A successful upstream response is:
116+
117+
```json
118+
{
119+
"namespace_key": "tenant-a",
120+
"is_admin": false,
121+
"caller_id": "user-or-key-id",
122+
"target_type": "session",
123+
"target_id": "target-123",
124+
"scopes": ["runtime.use"],
125+
"expires_at": "2026-05-11T15:00:00Z"
126+
}
127+
```
128+
129+
Only `namespace_key` is always required. `target_type` and `target_id` must be returned together
130+
when present. `expires_at` must include timezone information.
131+
132+
Status handling:
133+
134+
| Upstream status | Agent Control result |
135+
| --- | --- |
136+
| `200` | Parse the principal grant. |
137+
| `401` | Authentication error. |
138+
| `403` | Forbidden error. |
139+
| `404` | Not found error. |
140+
| `429` | `503` with a rate-limit detail and `Retry-After` hint when present. |
141+
| Other statuses or upstream network errors | Fail closed with `503`. |
142+
| Malformed `200` principal response | Fail closed with `502`. |
143+
| `200` target grant that conflicts with request context | Fail closed with `403`. |
144+
145+
## Runtime JWT Claims
146+
147+
`/api/v1/auth/runtime-token-exchange` is a management-style request. The configured management
148+
provider authorizes `runtime.token_exchange` for the requested target. Agent Control then mints
149+
its own HS256 JWT with `AGENT_CONTROL_RUNTIME_TOKEN_SECRET`.
150+
151+
The token payload contains:
152+
153+
```json
154+
{
155+
"iss": "agent-control/server",
156+
"domain": "runtime",
157+
"namespace_key": "tenant-a",
158+
"actor_id": "user-or-key-id",
159+
"target_type": "session",
160+
"target_id": "target-123",
161+
"scopes": ["runtime.use"],
162+
"iat": 1778509800,
163+
"exp": 1778510100,
164+
"jti": "opaque-token-id"
165+
}
166+
```
167+
168+
Verification requires the expected issuer, `domain="runtime"`, a valid signature, an unexpired
169+
`exp`, and `runtime.use` in `scopes`. The token is accepted only for requests whose `target_type`
170+
and `target_id` match the bound target.
171+
172+
The expiry is the earlier of `AGENT_CONTROL_RUNTIME_TOKEN_TTL_SECONDS` and the upstream grant's
173+
`expires_at` when supplied. Runtime token TTLs are capped at 86400 seconds.

core/configuration.mdx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ For server database configuration, use the `AGENT_CONTROL_DB_*` variables in the
6767

6868
Agent Control supports API key authentication for production deployments.
6969

70+
For pluggable management auth, HTTP upstream authorization, namespace scoping, and runtime JWT
71+
claims, see the [Authentication reference](/core/authentication).
72+
7073
### Configuration
7174

7275
| Variable | Default | Description |

docs.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
"pages": [
120120
"core/reference",
121121
"core/configuration",
122+
"core/authentication",
122123
"sdk/python-sdk",
123124
"sdk/typescript-sdk",
124125
"testing",
@@ -183,6 +184,7 @@
183184
"pages": [
184185
"core/reference",
185186
"core/configuration",
187+
"core/authentication",
186188
"sdk/python-sdk",
187189
"sdk/typescript-sdk",
188190
"testing"

how-to/enable-authentication.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,4 @@ Agent Control accepts multiple comma-separated keys per variable, making zero-do
106106
2. Your key is present in the correct variable (`AGENT_CONTROL_API_KEYS` for regular, `AGENT_CONTROL_ADMIN_API_KEYS` for admin operations)
107107
3. The `X-API-Key` header (or SDK `api_key` argument) matches exactly — no trailing whitespace or quotes
108108

109-
See the [Authentication reference](/core/reference#authentication) for the full configuration table.
109+
See the [Authentication reference](/core/authentication) for auth modes and provider contracts.

0 commit comments

Comments
 (0)