AUTHENTICATION
Two principals, one boundary.
Everything in APPEN authenticates as one of two principals, and the whole security model lives in that split: you (a JWT from email + password) and your agent (an ak_live_ key). Same endpoints, different powers. The API, the MCP server, and the CLI all enforce the same line.
You — the human JWT
POST /auth/signup { "email": "...", "password": "..." } → { "access_token": ... }
POST /auth/login { "email": "...", "password": "..." } → { "access_token": ... }
# then, on every request:
Authorization: Bearer <JWT>
X-Business-Id: <business uuid> # which of your businesses to act asThe JWT can do everything: create businesses, issue cards, write rules, mint and revoke agent keys, approve or deny parked purchases, pause cards.
Your agent — the ak_live_ key
POST /businesses/{id}/agent-keys { "name": "pizza-bot" }
→ { "secret": "ak_live_9f2a71c4_...", "note": "save this — it will not be shown again" }
# the agent's requests:
Authorization: Bearer ak_live_... # no X-Business-Id needed — the key IS the scopeKeys are shown once and stored as a sha256 hash. Each key is bound to one business, can be scoped to specific tools (allowed_tools), and is revoked in one call — killing one agent without touching the rest.
What an agent can never do
- — Approve its own purchases. The approval endpoints require a human JWT; an agent key gets a 403, by design, always.
- — See a card number. Card responses carry a handle (crd_…), last-four, limit, status. There is no PAN column in the model an agent can reach and no endpoint that returns one.
- — Rewrite its own rulebook beyond the tools you granted its key.
# agent declares — fine:
curl -X POST $APPEN_API/intents -H "Authorization: Bearer $AGENT_KEY" -d '{...}' # 200
# agent tries to approve a parked purchase:
curl -X POST $APPEN_API/intents/$ID/approve -H "Authorization: Bearer $AGENT_KEY" # 403WHERE THIS RUNS TODAY
The rule engine decides every declared intent today — live in the API, the MCP server, and the demo. Enforcement on real card swipes begins at our BIN connection with our issuing partner, when the same pre-authorized, user-directed policies execute inside the network authorization step. Card issuance opens by invite once our issuing-partner sandbox is live.