Docs menu

API keys and tokens

.md

Personal API keys for scripts, CI, and agents β€” and how the CLI picks its credential.

Everything that talks to oak.space β€” the CLI, the HTTP API, CI jobs, agents β€” authenticates with a bearer token:

Authorization: Bearer oak_...

There are three kinds of token.

TokenComes fromLifetimeUse it for
Login sessionoak login90 daysYou, at your own terminal.
Personal API keyYou create itUntil revokedScripts and tools acting as you.
Service-account keyAn org admin creates itUntil revokedBots, CI systems, and agents with their own identity.

Personal API keys#

Create one under Settings β†’ API keys on oak.space, or over the API:

curl -X POST https://oak.space/api/api-keys \
  -H "Authorization: Bearer $OAK_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "release script", "scope": "read", "repo": "acme/web"}'
FieldValue
name1–100 characters, for your own reference.
scopefull (default) or read β€” a read key can only make read requests.
repoOptional owner/name. The key then works only for that one repo.

The full key is shown once, when it's created. After that only its first characters are displayed, so store it somewhere safe. List your keys with GET /api/api-keys and revoke one with DELETE /api/api-keys/{id}.

A personal key acts as you, with your access β€” a repo-scoped or read-only key can only do less, never more.

Service accounts#

A service account is a non-human identity owned by an organization β€” a deploy bot, an external CI system, a coding agent that runs unattended. Its actions show up under its own name in the audit log, and its keys carry explicit scopes, so you can give it exactly what its job needs.

Organization owners and admins manage them under the organization's Settings β†’ Agents, or over the API:

# Create the account
curl -X POST https://oak.space/api/orgs/acme/service-accounts \
  -H "Authorization: Bearer $OAK_TOKEN" -H "Content-Type: application/json" \
  -d '{"name": "nightly-agent", "display_name": "Nightly refactor agent"}'

# Give it a key that can push branches but never merge
curl -X POST https://oak.space/api/orgs/acme/service-accounts/nightly-agent/keys \
  -H "Authorization: Bearer $OAK_TOKEN" -H "Content-Type: application/json" \
  -d '{"name": "prod", "scopes": "read,write"}'
ScopeAllows
readEvery read request: clone, pull, list, view.
writePush branches, create repos and branches, and other changes β€” except the ones below.
mergeMerge branches onto main.
adminOrganization management (/api/orgs/...).
releaseAuthorize protected releases. Never implied by any other scope, including admin.

Scopes are required on service-account keys. A key can never do more than the person who created it can. A request outside a key's scopes gets a 403 naming the missing scope.

Disable a service account (PATCH …/service-accounts/{name} with {"disabled": true}) to stop all its keys at once, or delete it. Revoke one key with DELETE …/service-accounts/{name}/keys/{key_id}.

For coding agents, a read,write service-account key is a good default: the agent can clone, push its branches, and file what it did, but can't merge to main β€” merging stays a human decision.

Using a key with the CLI#

export OAK_API_KEY=oak_...
oak clone acme/web
oak auth status       # confirms which credential is in use and who it resolves to

The CLI picks its credential in this order:

  1. OAK_API_KEY, if set.
  2. A key stored in the checkout itself (oak clone saves one, bound to the server it came from).
  3. Your oak login session for that server, from ~/.oak/credentials.

If a push or pull unexpectedly says a repo you know exists isn't found, a stale key from step 2 is the usual suspect β€” oak auth status shows which source is winning.

Using a key with the API#

curl https://oak.space/api/repos -H "Authorization: Bearer $OAK_API_KEY"

See the HTTP API reference.

Something here wrong or missing? Run oak feedback -m "…" or email [email protected].