API keys
The machine credential for git, event ingest and agents — its scopes, app set, role ceiling, expiry and what each one refuses.
An API key is a machine identity for a bot: a CI job, a deploy script, an agent. It acts as its owner — the account whose Account page minted it — and every request re-resolves that account’s role, so removing a collaborator, transferring an app or lowering a role takes effect on the key’s very next request.
Keys are created, listed and revoked on Account → API keys. The raw key is shown once; keep it secret.
What a key can reach
| Surface | How the key is presented | Scope it needs |
|---|---|---|
| Git over HTTPS | HTTP Basic: username git, password the key (http://git:<domain>/<slug>) |
App Management; view fetches, push/admin pushes |
| MCP (agents) | Authorization: Bearer noite_… on /mcp (Agents) |
App Management |
| Event ingest | Authorization: Bearer noite_… on /api/apps/<id>/ingest/events |
Events |
The two scopes are independent checkboxes: an events-only key cannot push code or reach MCP, and an app-management-only key cannot ingest events.
Narrowing a key
Beyond its scopes, a key can be narrowed three ways. All three are enforced by one function on every key-authenticated surface, including the ones added later.
| Field | Default | What it does |
|---|---|---|
| Apps | All apps | Limits the key to the app ids you pick. A request naming any other app — by slug or by id — is refused. create_app (and claiming a new slug with a git push) is refused too, because the new app would not be in the key. |
| Role ceiling | Admin (no cap) | The key’s effective role is the lower of your role on that app and this ceiling. A push key owned by an admin can push and open pull requests but cannot change variables or settings, force-push, delete a branch, or commit to a protected branch. |
| Expiry | Never | 1 hour, 1 day, 7 days or 30 days. Once the instant passes the key is refused everywhere, and the next attempt deletes it. |
The account page lists each key with its apps, ceiling, expiry and last use, so an old credential is visible before it is a problem.
Enforcement, precisely
- App restriction is by id. The app is resolved first (slug first, then id), then the resolved row’s
idis checked against the key’s set. A renamed app keeps its restriction; a deleted app is simply gone; naming one app’s slug can never resolve to a different app’s id. - Roles are re-resolved per request from the collaborator grants and the instance-admin rule the UI uses, so a key minted while you were an admin loses that power the moment you are demoted or removed.
- Every refusal is uniform. A key scoped elsewhere, an app you cannot see and an app that does not exist answer the same way, so a key is never an existence oracle for apps it cannot reach. An expired key is the one exception: the caller holds it, so the answer says
API key expired. - A key whose stored scope cannot be read is refused, never treated as account-wide.
- Bans win. A banned account’s keys stop working immediately and are deleted; unbanning does not restore them.
- Not a session. A key cannot sign in, change the account, mint another key or read
/account; it only reaches the surfaces in the table above.
Attribution
Actions a key performs are labelled with it, so a bot’s work stays visible as a bot’s:
- A commit the control plane writes for a key (an MCP
create_appimport today) is authored and committed as<your name> via key <key name>. - A preview-environment redeploy triggered with a key records that label on its deploy row, shown under the deploy as “by …”.
Automatic deploys from a plain git push carry the pusher’s own git identity in the commit, so there is no key label on the deploy row.
Rotating a key
Revoke the old key on the Account page and mint a new one — revocation is immediate on every surface (git, MCP, ingest). Short expiries are the low-effort version of the same discipline: a CI key with a 30-day expiry cannot become a permanent credential nobody remembers.
Related
- Agents (MCP) — the tool list and client setup an app-management key unlocks.
- Collaborators — what
view,pushandadminmean on an app.