Skip to content

API tokens

API tokens are how everything that isn’t a browser authenticates. They belong to an organization, carry a set of scopes, and optionally expire.

Kind Prefix Acts as Bound to Use it for
PAT cavs_pat_ you — capped by your org role the organization your laptop, the CLI, ad-hoc scripts
REPO cavs_repo_ itself one repository a single deploy target or consumer
CI cavs_ci_ itself the organization build pipelines

The distinction that matters: a PAT is capped by your role. Its effective permission is your role ∩ its scopes, so if you’re demoted to VIEWER, every PAT you hold loses write access instantly. REPO and CI tokens have no user behind them and are authorized by their scopes alone — which makes them the right choice for automation that must keep working when people move around, and the wrong choice to leave lying about.

Scope Grants
repo:read Read repositories and metadata; pull. Also satisfies org:read-level reads.
repo:write Everything in repo:read, plus push and updating repositories.
repo:admin Everything in repo:write, plus create/delete repositories and manage collaborators.
org:read Read the organization and its member list. Also satisfies usage reads.
usage:read Read usage and storage metrics.

Scopes are a hard cap, never a grant: a repo:admin token held by a VIEWER still can’t push.

Job Scopes
CI publishing build artifacts repo:write
CI consuming a dataset repo:read
A cost dashboard usage:read
A provisioning script that creates repositories repo:admin
Interactive use from your laptop repo:write (+ usage:read if you use cav storage)

Start narrow. Widening a token is one API call; recovering from a leaked repo:admin token is not.

  1. Organization settings → Tokens → New token.

  2. Give it a name that says where it lives — github-actions/vision-build, not token1. This name is what you’ll see when deciding what to revoke.

  3. Pick the kind, the scopes, and an expiry in days.

  4. Copy the secret. It is shown exactly once.

Over the API
curl -sS -X POST "https://cavsnode.com/api/v1/organizations/acme-ai/tokens" \
-H "Authorization: Bearer $CAVS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "github-actions/vision-build",
"kind": "CI",
"scopes": ["repo:write"],
"expires_in_days": 90
}'
Response — the only time you see the secret
{
"token": {
"id": "6f1a…",
"name": "github-actions/vision-build",
"kind": "CI",
"prefix": "cavs_ci",
"scopes": ["repo:write"],
"expires_at": "2026-10-26T12:00:00Z",
"created_at": "2026-07-28T12:00:00Z"
},
"secret": "cavs_ci_9dK2…"
}

A REPO token additionally needs "repository_id": "<uuid>". Creating a token requires the tokens.create permission (DEVELOPER and above) and counts against your plan’s token limit.

Terminal window
curl -sS "https://cavsnode.com/api/v1/organizations/acme-ai/tokens" \
-H "Authorization: Bearer $CAVS_TOKEN"
curl -sS -X DELETE "https://cavsnode.com/api/v1/organizations/acme-ai/tokens/$TOKEN_ID" \
-H "Authorization: Bearer $CAVS_TOKEN"

The list shows name, kind, prefix, scopes, expiry, creation and last used (timestamp and IP). Revocation is immediate — the next request with that token gets 401. Both actions are recorded in the audit log.

There is no in-place rotation; you create a replacement and retire the old one. This is deliberate — it means there’s always a window where both work, so rotation never causes an outage.

  1. Create a new token with the same scopes and a clear name including the date: github-actions/vision-build-2026-07.

  2. Update the secret in your secret store (GitHub Actions secret, Vault, etc.).

  3. Run the pipeline and confirm it passes.

  4. Revoke the old token.

  5. Confirm the old token’s “last used” stops advancing.

Rotate on a schedule (quarterly is a reasonable default), and immediately when:

  • Someone with access to it leaves.
  • It may have been logged, pasted or committed.
  • Its scope turns out to be wider than the job needs.
  1. Revoke it first. Don’t investigate first — revoke, then investigate.
  2. Check the audit log for actions attributed to it.
  3. Check the token’s last-used IP for anything unexpected.
  4. Create a replacement with narrower scopes.
  5. If it was committed to Git, purge it from history — revocation is what actually protects you, but a live-looking secret in history invites confusion.

Do

  • Keep them in a secret manager or your CI platform’s secret store.
  • Use --token-stdin or an interactive prompt rather than a command-line flag.
  • Give each consumer its own token, so revocation is surgical.
  • Set an expiry.

Don’t

  • Commit them, including in .env files that aren’t ignored.
  • Echo them in CI logs, or pass them as URL query parameters.
  • Share one token across teams or environments.
  • Use a repo:admin token where repo:read would do.

The CLI stores its token in ~/.config/cav/config.toml — a plain file. On a shared machine, verify its permissions, or use CAVS_TOKEN per invocation instead of logging in.

Plan Max active tokens
Free 5
Developer 50
Team 200
Business unlimited

Exceeding it returns 402 quota_exceeded. Revoked tokens don’t count.

The SDK contract documents cavs_sk_ service-account keys with fine-grained scopes and per-key rotation endpoints. That work is not deployed — those endpoints return 404 today. Use cavs_ci_ machine tokens for automation. See Choosing an integration.