# auth.md

How an AI agent authenticates and pays at ZenVault. There is no human signup: credentials are
bought, anonymous, and disposable.

- Resource server: https://api.zenvault.eu
- Protected resource metadata: https://zenvault.eu/.well-known/oauth-protected-resource
- Authorization server metadata: https://zenvault.eu/.well-known/oauth-authorization-server
- JWKS: https://zenvault.eu/.well-known/jwks.json

## Audience

Autonomous agents calling the ZenVault API. No human account, email address or KYC is involved at
any point, and we never ask an agent to hold a human's credentials.

## Registration (credential provisioning)

`POST https://api.zenvault.eu/v1/credits` with a payment buys a prepaid credit token (`zv_…`) and returns it once.
That token *is* the identity: whoever holds it can spend its balance. There is nothing else to register.

```
POST https://api.zenvault.eu/v1/credits
Content-Type: application/json
X-PAYMENT: <x402 payment payload>

{"amount_usd": 5}
```

Sub-agents get their own spend-capped credential:

```
POST https://api.zenvault.eu/v1/credits/subtokens
Authorization: Bearer zv_parent...

{"cap_usd": 0.50, "label": "worker-3", "days": 7}
```

## Supported methods

1. **Bearer credit token** — `Authorization: Bearer zv_…` (or `X-CREDIT-TOKEN: zv_…` when the
   Authorization header already carries a resource management token). Simplest; no exchange step.
2. **OAuth 2.0 client credentials** — exchange the credit token for a short-lived access token:

```
POST https://api.zenvault.eu/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_secret=zv_...&scope=zenvault.write
```

   The response is an RS256 JWT (`typ: at+jwt`) valid for one hour, verifiable against the published
   JWKS without calling us. Send it as `Authorization: Bearer eyJ…`.
3. **x402 per call** — no credential at all: send `X-PAYMENT` with a signed USDC authorization on
   Base. Payment is the identity.
4. **Anonymous free tier** — no credential; 0 cheap calls per day per IP.

## Credential use and lifetime

Access tokens expire in 3600 seconds; credit tokens live until their balance or expiry runs out.
Resource management tokens (`zvm_…`) are returned once at creation and scope to a single resource:
status, extend, export, cancel. Lost tokens cannot be recovered — everything has a TTL by design.

## Revocation

Spend the balance, let the token expire, or ask the operator at zenvault@agentmail.to. Sub-tokens
stop working the moment their cap is reached or the parent balance is exhausted.
