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 as

The 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 scope

Keys 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.
the boundary, demonstrated
# 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"  # 403

WHERE 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.