Scope
A request is granted only when both are true:- The action is in the key’s action set.
- The target box is in the key’s box set, or in one of its environments.
box.create for the destination and snapshot.read access to the source. Replacing a named snapshot requires access to both its existing source and the Box being saved. Selecting a destination environment does not grant access to snapshots from other environments.
Actions
Presets
In-box key
The credential written into a box is scoped to that box. It can prompt, exec, read and write files, SSH, desktop, host, and snapshot itself. It cannot create, resume, fork, or delete boxes, and it cannot write environments or administer the account. A compromised box is one box.Create a key
Creating a key usesPOST /api/box/v1/api-keys/scoped and requires a browser session (box login with no key, or the dashboard) or an already-admin token. During a credential rollout the server may temporarily disable creation; GET /api/box/v1/api-keys reports catalog.scopedCreationEnabled, and the create endpoint returns a typed 503 while it is off.
--ttl max is 365 days. --box and --env are repeatable. --actions and --preset are mutually exclusive. Omit both and the key is admin-scoped with a 90-day TTL.
The secret is shown once. In scripts:
List
Listing is the one key operation available on every surface. Secrets are never returned. Each row includes the id, name, prefix, last four characters, scope, expiry, last used, 30-day request total, and how many Boxes and Agents that key created that still exist. Expired and expiring keys are labeled. Restricted API keys receive an emptyapiKeys list; the account-wide inventory is returned only to a browser/CLI session or an unrestricted account key.
TypeScript
Python
See usage for one key
box api-key usage <id> prints the same 30-day request total and live resource count. Add --verbose for the Boxes/Agents split and the created resource list. GET /api-keys/{id}/usage is the matching API.
Usage still works after you revoke the key, as long as you still have the id. Revoking stops the secret. It does not delete Boxes or Agents the key created.
Creating, rotating, and revoking keys stay session-gated, except that an admin-scoped token can create a new key. A credential that could mint more credentials would defeat the point of least privilege. Use
box api-key create|rotate|revoke after a browser sign-in, or the API Keys tab.Errors
Scoped keys return typed 403s:
The bearer header and SDK config are unchanged.
Store keys
Do not put API keys in:
- Dockerfiles
- Images
- Source code
- Shell history
- Public CI logs
Rotate a key
Rotating a key immediately revokes the old secret, preserves the API key id, and shows a new secret once. An expired scoped key cannot be rotated; the API returns409 api_key_expired, so create a replacement instead.
Use Rotate only when you can update the deployed secret immediately:
- Rotate the key:
box api-key rotate <id>(find ids withbox api-key list), or use the dashboard. - Copy the new secret.
- Update
BOX_API_KEYin your platform secret manager. - Redeploy or restart workers that use the key.
- Create a new key.
- Update the platform secret to the new key.
- Redeploy or restart workers.
- Revoke the old key after the new deployment is live.
Revoke a key
Revoking a key immediately disables it. Existing CLI configs or running processes using that key will fail the next Box API request with an auth error. Boxes and Agents that key created stay.box api-key usage <id> still shows their totals.
Do not put keys in Dockerfiles, images, source, shell history, or public CI logs.
Production guidance: one key per job, shortest TTL you can live with, read-only or ci unless you truly need admin. Reissue legacy keys.
Rotate and revoke
Rotate keeps the id, scope, and expiry date, replaces the secret, and shows the new secret once. It does not extend the key’s lifetime or convert a legacy key into a scoped key. To avoid downtime, create a second key, cut over, then revoke the old one.box api-key revoke <id> or Revoke in the dashboard. The next request with that secret fails auth.