ibexharness
DocsBlogReleasesRoadmap
GitHub
ibexharness

Documentation

OverviewConfigurationAuthenticationRate limitingRequest routingProvider adapters
Proxy›Authentication
Proxy

Authentication

How the proxy validates tokens and resolves agent identity.

Protected proxy routes require two credentials: a Personal Access Token (PAT) in the Authorization header and an active agent UUID in X-IBEX-Agent-ID. The proxy never stores token hashes — every validation is delegated to the auth service over gRPC (ADR-0011, ADR-0016).

Fail-closed on auth outage

When auth gRPC is unavailable, token validation returns 503 SERVICE_DEGRADED and agent verification returns 503 AUTH_UNAVAILABLE. There is no permission cache bypass in Phase 1.

Required headers

HeaderRequired onDescription
AuthorizationAll protected routesBearer ibex_pat_<uuid>_<secret>
X-IBEX-Agent-IDAll protected routesUUID of an active agent owned by the token's org
Content-TypePOST bodiesMust be application/json on chat completions

Organization scope is derived from the validated token, not from request body fields. Never send org_id in JSON to select a tenant — that would be a spoofing vector. See Security authentication.

Validation flow

Mermaid diagram: sequenceDiagram
+--------+                            +-------+                          +-----------+                      +----------+   
| Client |                            | Proxy |                          | Auth gRPC |                      | Postgres |   
+--------+                            +-------+                          +-----------+                      +----------+   
     |                                    |                                    |                                  |        
     |  Authorization + X-IBEX-Agent-ID   |                                    |                                  |        
     |------------------------------------>                                    |                                  |        
     |                                    |                                    |                                  |        
     |                                    |    ValidateToken(access_token)     |                                  |        
     |                                    |------------------------------------>                                  |        
     |                                    |                                    |                                  |        
     |                                    |                                    |  Argon2id lookup + permissions   |        
     |                                    |                                    |---------------------------------->        
     |                                    |                                    |                                  |        
     |                                    |                                    |   org_id, permissions bitmap     |        
     |                                    |                                    <..................................|        
     |                                    |                                    |                                  |        
     |                                    |          valid / invalid           |                                  |        
     |                                    <....................................|                                  |        
     |                                    |                                    |                                  |        
     |                                    |  ValidateAgent(org_id, agent_id)   |                                  |        
     |                                    |------------------------------------>                                  |        
     |                                    |                                    |                                  |        
     |                                    |                                    |      agent row + org match       |        
     |                                    |                                    |---------------------------------->        
     |                                    |                                    |                                  |        
     |                                    |        authorized / denied         |                                  |        
     |                                    <....................................|                                  |        
     |                                    |                                    |                                  |        
     |          200 / 4xx / 5xx           |                                    |                                  |        
     <....................................|                                    |                                  |        
     |                                    |                                    |                                  |        
+--------+                            +-------+                          +-----------+                      +----------+   
| Client |                            | Proxy |                          | Auth gRPC |                      | Postgres |   
+--------+                            +-------+                          +-----------+                      +----------+   

Chat completions additionally require the ProxyChatCompletion permission bit on the token (ADR-0009).

Path org enforcement

Two probe routes help integrators verify credentials:

GET/v1/internal/auth-probe

Returns org_id and permissions from the validated token. No path org parameter.

GET/v1/orgs/{org_id}/auth-probe

Same response shape; path org_id must equal token org or returns 403.

Cross-tenant path access returns 403 with an ambiguous message — not 404 — to prevent resource enumeration. This is enforced at every layer: middleware, gRPC handler, store WHERE clause, and Postgres RLS. Details: Tenant isolation.

Probe examples

bash
# Internal probe — org from token
curl -s http://localhost:8080/v1/internal/auth-probe \
  -H "Authorization: Bearer ${IBEX_DEV_TOKEN}" \
  -H "X-IBEX-Agent-ID: ${IBEX_DEV_AGENT_ID}"
 
# Path org probe — must match token org
curl -s "http://localhost:8080/v1/orgs/${IBEX_DEV_ORG_ID}/auth-probe" \
  -H "Authorization: Bearer ${IBEX_DEV_TOKEN}" \
  -H "X-IBEX-Agent-ID: ${IBEX_DEV_AGENT_ID}"

Successful probe response:

JSON
{
  "org_id": "00000000-0000-0000-0000-000000000001",
  "permissions": 23
}

Chat completion probe

After auth and agent checks pass, chat returns 501 in Phase 1 — that is success for credential verification:

bash
curl -s -X POST http://localhost:8080/v1/chat/completions \
  -H "Authorization: Bearer ${IBEX_DEV_TOKEN}" \
  -H "X-IBEX-Agent-ID: ${IBEX_DEV_AGENT_ID}" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"ping"}]}'

Expected: HTTP 501 with error.code = PROVIDER_NOT_CONFIGURED.

Error matrix

HTTPCodeWhen
401UNAUTHORIZEDMissing, malformed, expired, or revoked PAT
400MISSING_AGENT_IDX-IBEX-Agent-ID absent or not a UUID
403AGENT_NOT_AUTHORIZEDAgent missing, wrong org, or cross-tenant path
403AGENT_SUSPENDEDAgent exists but is not active
403PATH_ORG_MISMATCHPath org_id ≠ token org on org-scoped routes
503SERVICE_DEGRADEDAuth gRPC timeout or unavailable on token validation
503AUTH_UNAVAILABLEAuth gRPC failure on agent verification

Full envelope reference: API errors. Security integration tests cover 35+ negative cases — see current state.

Issue a dev PAT

1

Seed local data

make db-seed writes a fixed dev PAT and exports IBEX_DEV_TOKEN, IBEX_DEV_AGENT_ID, IBEX_DEV_ORG_ID.

2

Or create via gRPC

Use CreateToken with an admin bearer — see Issuing API keys.

3

Never log secrets

Log only token prefixes in application code. Rotation procedure: Secrets and keys.

Related

  • Auth overview — gRPC surface and token lifecycle
  • Org and project model — how agents map to orgs
  • Overview — full middleware order
  • Request routing — body validation after auth

Was this page helpful?

Edit on GitHub

Last updated on

PreviousConfigurationNextRate limiting

On this page

  • Required headers
  • Validation flow
  • Path org enforcement
  • Probe examples
  • Chat completion probe
  • Error matrix
  • Issue a dev PAT
  • Related
0%