Issuing API keys
Create and rotate personal access tokens for agents and services.
Personal Access Tokens (PATs) are the Phase 1 client credential for IBEX Harness. Each token is scoped to an organization, carries a permission bitmap, and is verified by Argon2id hash lookup — only the hash is stored; the plaintext is shown once at creation (ADR-0007, ADR-0010).
PAT wire format
ibex_pat_<token_uuid>_<secret>Example dev token (from make db-seed):
ibex_pat_00000000-0000-0000-0000-000000000004_LOCALDEVELOPMENTONLYThe auth service parses the prefix, looks up token_uuid in ibex_core.tokens, and verifies the secret with Argon2id. Revoked tokens fail immediately regardless of hash match.
Permission bitmap
Tokens encode capabilities as a 64-bit bitmap (ADR-0009). Common bits for proxy integrators:
| Bit | Name | Needed for |
|---|---|---|
| — | ProxyChatCompletion | POST /v1/chat/completions |
| — | TokenCreate | CreateToken gRPC |
| — | TokenRevoke | RevokeToken gRPC |
ProxyChatCompletion is a composite of memory/session read bits — sufficient for Phase 1 chat probes.
Quick start with seed data
Migrate and seed
make db-migrate && make db-seed — idempotent; refuses production DSNs.
Export env vars
Seed output sets IBEX_DEV_TOKEN, IBEX_DEV_AGENT_ID, IBEX_DEV_ORG_ID.
Smoke test
make dev-smoke — validates probes and chat stub with seeded credentials.
Fixed seed IDs: org 00000000-0000-0000-0000-000000000001, agent 00000000-0000-0000-0000-000000000003.
Create via gRPC
CreateToken requires an existing admin bearer with TokenCreate permission.
grpcurl -plaintext \
-H "authorization: Bearer ibex_pat_<admin-uuid>_<secret>" \
-d '{"org_id":"<org-uuid>","name":"dev-pat","type":1,"permissions":23}' \
localhost:9091 ibex.auth.v1.AuthService/CreateTokenThe response field plaintext is the only chance to copy the secret. Persist it immediately.
CreateToken parameters
| Parameter | Type | Description |
|---|---|---|
org_idRequired | string (uuid) | Organization that owns the token. Must match caller's org. |
nameRequired | string | Human-readable label for audit and ListTokens. |
typeRequired | integer | Token type enum from proto (1 = standard PAT). |
permissionsRequired | int64 | Permission bitmap. Use packages/permissions constants in Go. |
Revoke a token
Immediate invalidation — no grace period:
grpcurl -plaintext \
-H "authorization: Bearer ibex_pat_<admin-uuid>_<secret>" \
-d '{"org_id":"<org-uuid>","token_id":"<token-uuid>"}' \
localhost:9091 ibex.auth.v1.AuthService/RevokeTokenRevoked tokens return 401 on the next proxy request.
Rotation procedure
Issue replacement
CreateToken with the same org and desired permissions.
Deploy new secret
Update client env vars or secrets manager entry.
Verify traffic
Probe /v1/internal/auth-probe with the new PAT.
Revoke old token
RevokeToken on the previous token_id — instant cutover.
Never rotate by deleting rows in Postgres — use the gRPC API so audit and revocation caches stay consistent.
Operator checklist
- Permissions follow least privilege (
ProxyChatCompletiononly for LLM clients) - Token name identifies the owning service or agent
- Plaintext stored in vault, not
.envcommitted to git - Revocation tested in staging
Related
- Org and project model — how agents map to orgs
- Multi-tenant RLS — where hashes are stored
- Proxy authentication — headers clients send
- Authentication — fail-closed validation rules
Was this page helpful?
Last updated on