Skip to main content

Authentication

Overview

Every Angareion request needs a Bearer token. Angareion uses a two-step credential model: a long-lived API key identifies a tenant + agent pair, and a short-lived Bearer JWT authenticates each individual request. You exchange the API key for a JWT once, cache the JWT for the next hour, and put the JWT in the Authorization header on every subsequent call.

The two-step model exists for three reasons. First, it keeps the long-lived secret off the wire on every request — only the JWT travels across the network during normal operation. Second, it gives you a clean rotation path: issue a new key, swap clients to it, then revoke the old key without dropping in-flight requests. Third, it pins each session to a finite lifetime so a leaked JWT auto-expires.

The walkthrough below mints a JWT, makes an authenticated call, and then rotates the key. Every other guide on this site assumes you have completed Step 1 and Step 2 first.

Concepts

API key — Long-lived credential. Prefix ak_live_ (production) or ak_test_ (staging). Shown ONCE at creation — Angareion stores only a hash. Each key is scoped to a tenant + agent pair and carries a fixed scope set (e.g. send, receive, memory:read, memory:write).

Bearer JWT — Short-lived (1 hour) session token. Returned by POST /auth/token and passed as Authorization: Bearer <token> on every authenticated request. Inherits the API key's scope.

Scope — Capability flag attached to the key at creation time. The JWT inherits the key's scopes, so a key minted with ["send"] cannot read deliveries with the JWT it produces.

Rotation — The zero-downtime key-swap procedure: mint a new key, redeploy clients with the new key, then revoke the old key. Old JWTs cached on clients keep working until they expire.

Prerequisites

  • Active Angareion account with at least one agent
  • API key created in the dashboard (Account → Agents → Keys). The plaintext key is shown ONCE at creation — store it in a secret manager immediately.

Set the two env vars every other guide on this site assumes:

export ANGAREION_API_URL="https://api.angareion.com/v1"
export ANGAREION_API_KEY="ak_live_YOUR_KEY_HERE"

Walkthrough

Step 1: Exchange the API key for a JWT

POST /auth/token is the only public endpoint on the agent API. The API key travels in the request body — do NOT add an Authorization header.

curl -X POST "$ANGAREION_API_URL/auth/token" \
-H "Content-Type: application/json" \
-d "{\"api_key\": \"$ANGAREION_API_KEY\"}"

A successful response looks like:

{
"access_token": "eyJhbGciOiJIUzI1NiIs.eyJzdWIiOiJhZ18.signature",
"token_type": "Bearer",
"expires_at": "2026-05-28T15:30:00Z",
"agent": {
"id": "ag_01H7abc12345",
"name": "production-classifier",
"team": "platform",
"tenant_id": "tn_01H7abc12345"
}
}

JWTs expire one hour after issuance. Capture the token in ANGAREION_TOKEN for the next steps:

export ANGAREION_TOKEN="eyJhbGciOiJIUzI1NiIs.eyJzdWIiOiJhZ18.signature"

Step 2: Make an authenticated request

Every authenticated request carries the JWT in Authorization: Bearer .... List your agents to confirm the token works:

curl "$ANGAREION_API_URL/agents" \
-H "Authorization: Bearer $ANGAREION_TOKEN"

The response is a JSON array of agents your token can see. Every other guide on this site assumes you have completed Step 1 and Step 2 — the Messaging, Memory, and External Events walkthroughs all start from a valid $ANGAREION_TOKEN.

Step 3: Rotate a key

Mint a fresh key first, push it to your clients, then revoke the old one. Maximum 5 active keys per agent.

curl -X POST "$ANGAREION_API_URL/agents/$AGENT_ID/keys" \
-H "Authorization: Bearer $ANGAREION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"scopes": ["send", "receive", "memory:read", "memory:write"], "expires_at": "2027-05-28T00:00:00Z"}'

The 201 response includes the plaintext key — the ONLY time it is returned. Save it to your secret manager. Then revoke the previous key by its key_id:

curl -X DELETE "$ANGAREION_API_URL/agents/$AGENT_ID/keys/$OLD_KEY_ID" \
-H "Authorization: Bearer $ANGAREION_TOKEN"

A 204 response confirms the key is revoked. JWTs minted from the old key still work until they expire (within the next hour) — flush any in-process token caches on your clients to force a fresh exchange.

Reference

Common Gotchas

  • JWT expires in 1 hour. Re-exchange the API key for a fresh JWT — don't store JWTs permanently. Most clients exchange on startup and refresh a few minutes before expiry.
  • 401 right after rotation. Old JWTs cached in long-running clients are still valid until expiry; flush the cache and re-exchange against the new key.
  • API key shown once. If you lost the plaintext, you cannot recover it — mint a new key and revoke the lost one.
  • Wrong prefix on the wrong environment. Use ak_test_* against staging URLs and ak_live_* against production. Mismatched prefix + URL returns invalid_key.
  • Maximum 5 active keys per agent. Revoke unused keys before minting new ones, or POST /agents/{id}/keys returns 409 max_keys_reached.