# Keys and identity

> Check who a key belongs to, and mint, list, rotate and revoke narrower keys.

### `GET /v1/whoami`

Any valid key. Shows who the key belongs to and what it can do. Make this the first call when debugging a `401` or `403`.

```json
{ "principal": "provider(prv_…)", "kind": "provider", "providerId": "prv_…", "scopes": ["…"], "keyId": "akey_…" }
```

### `GET /v1/auth/self`

The same, plus `label`, `source` (`managed` or `static`) and `expiresAt`.

### `GET /v1/auth/scopes`

The full list of scopes. Use it to build a scope picker without hard-coding the list.

### `POST /v1/auth/keys`

Scope `keys:write`. Mints a key for **your own** tenant.

| Field | Type | Notes |
|---|---|---|
| `label` | string | required. Shown in listings |
| `scopes` | string[] | must be a subset of the minting key's scopes. `"<resource>:*"` is allowed if you hold it |
| `expiresInSeconds` | number | can't be later than the minting key's expiry |

```json
// 201: the token is returned once, and only its hash is stored
{ "key": { "id": "akey_…", "label": "invoice-bot", "scopes": ["…"], "expiresAt": "…", "status": "active" }, "token": "zk.akey_….…" }
```

### `GET /v1/auth/keys`

Scope `keys:read`. Your keys, without their secrets. Console sessions aren't listed. Add `?includeRevoked=true` to include revoked keys.

### `GET /v1/auth/keys/:id`

Scope `keys:read`. One key's details.

### `POST /v1/auth/keys/:id/rotate`

Scope `keys:write`. Issues a new secret with the same scopes. Body `{ graceSeconds? }` keeps the old secret working for a rolling deploy.

### `DELETE /v1/auth/keys/:id`

Scope `keys:write`. Revokes a key, effective on the next request. `?cascade=true` also revokes every key minted from it. Use that for a leak.
