# Three kinds of key

`get_project_keys` gives you all three. They have different uses, and putting one in the wrong place causes incidents.

| Key | Where | What it can do |
|---|---|---|
| Publishable key | Fine in browsers and apps | Only what the access rules allow |
| Secret key | **On the server only** | Bypasses every access rule |
| Access token (PAT) | This MCP server and the management API | Creates and deletes projects |

## Keys per use

The two keys from `get_project_keys` are tied together, so if one leaks you have to replace both.
To give each server or app its own key, create named keys with `create_api_key`.
`bw_publishable_…` has the same rights as the publishable key, `bw_secret_…` the same as the secret key.
`list_api_keys` shows when each key was last used, so revoke unused keys one by one with `revoke_api_key`.

## When a key leaks

```
get_jwt_signing      the signing method (HS256 | ES256) and old keys still accepted
rotate_signing_key   a new key to sign the publishable and secret keys (grace_hours: 0, 1, 24, 168)
retire_signing_key   end an old key's grace period now
set_jwt_signing      sign-in tokens as ES256 (other servers verify them with a public key)
```

`rotate_signing_key` changes **both** keys from `get_project_keys`. Every key in your apps has to be moved over, so
after a leak use `grace_hours: 0`; for a planned rotation, allow as much grace as moving takes. Only owners and admins can do this.
With `grace_hours: 0` (or empty), put the project name exactly in `confirm`.
When you only need values for frontend code, call `get_project_keys { ref, only: "publishable" }` to get just the address and the publishable key.

## Never do this

Never put the secret key in browser code, a mobile app or a public repository.
That key reads and writes every table in the project with no rules applied.
If a key has to go into frontend code, it is always the publishable key.

## Addresses

The project API is at `https://<ref>.<zone>`. `get_project_keys` tells you this too.

```
GET  https://<ref>.<zone>/rest/v1/notes?select=*     apikey: <publishable key>
POST https://<ref>.<zone>/auth/v1/signup             apikey: <publishable key>
```

---

https://end.blackall.ai/docs/keys?lang=en
