Skip to content

Reference

alter keys

Mint, rotate, revoke, and rename runtime API keys.

Runtime API keys authenticate application code against Alter. These commands manage the keys for one app.

alter keys list [--status active|revoked] [--limit ...] [--offset ...]
alter keys statistics [--output json|jsonl|table]
alter keys mint --name <name> --scopes <list> [--key-type ...] [...]
alter keys show --key <key-id>
alter keys rotate --key <key-id> [--scopes ...]
alter keys revoke --key <key-id> [--force] [--yes]
alter keys rename --key <key-id> --name <name>

All commands are app-scoped — pass --app <id> (or the app’s name), or link a workspace / set ALTER_APP_ID. list / show / statistics need dashboard_keys:read; mint / rotate / rename need dashboard_keys:write; revoke needs dashboard_keys:admin.

FlagDefaultDescription
--status <status>allClient-side filter on the fetched page: active means revoked_at is null (including rotated keys still in grace); revoked means it is set.
--limit <n>200Page size (1–1000).
--offset <n>0Pagination offset.
Terminal window
alter keys list --status active

All output formats emit the filtered current-page rows as an array/row stream, not the pagination envelope. Filtering happens after the page is fetched.

The table includes a RATE LIMIT column showing the ceiling each key is actually held to and which layer produced it — 1000 (key) for a per-key value chosen at mint time, 1000 (org) for the organization’s per-key maximum, and 1000 (platform) for the platform default. The distinction matters when capacity-planning: a platform default can move, a per-key value cannot. A — means the backend did not report a ceiling — unknown, never unlimited. 500 (?) means the backend reported the effective ceiling but omitted or used an unrecognized source; the number remains usable while its controlling layer is unknown.

Read-only quota summary for the app’s keys — active, rotated_in_grace, total, and max_allowed. Useful for a CI preflight before minting (e.g. fail the job if active is near max_allowed).

FlagDefaultDescription
--output <format>jsonjson, jsonl, or table.
Terminal window
alter keys statistics --output table

Mint a new scoped key. --name and --scopes are required unless you supply a full JSON body with --input.

FlagRequiredDescription
--name <name>yesDisplay name.
--scopes <list>yesComma-separated Alter scopes (e.g. grants:read,agents:read).
--key-type <type>noruntime (default — an SDK key, alter_rk_…) or agent (an agent-typed alter_ak_… key bound to no managed agent: it cannot reach grants bound or delegated to a named agent and does not satisfy key_type: agent in ALTER_INTEGRATION.md — use alter agents create or alter agents mint-key for a named agent).
--cidr <list>noComma-separated CIDR allowlist. Catch-all ranges are rejected: a single /0, a split-range set whose union covers a whole address family (e.g. 0.0.0.0/1,128.0.0.0/1), and an entry covering the entire IPv4-mapped-IPv6 block (::ffff:0.0.0.0/96). For an unrestricted key, omit the flag entirely.
--rate-limit-rpm <n>noPer-key requests-per-minute cap (1–100000). When the organization sets a per-key maximum, a higher value is rejected at mint time. Omitted, the organization’s per-key maximum becomes this key’s limit — it replaces the platform default rather than capping it, so the effective limit can be well above 1,000. With no per-key value and no organization maximum, the platform default of 1,000 requests/minute applies. See Errors for the full precedence table.
--expires-in <duration>noRelative expiry, e.g. 30d, 12h, 5m. The backend samples the start time, so client-clock skew cannot push an exact-maximum request over the ceiling. Mutually exclusive with --expires-at. Omit both expiration flags to use the organization’s finite default TTL.
--expires-at <iso>noAbsolute ISO 8601 expiry. Mutually exclusive with --expires-in; the organization’s maximum TTL still applies.
--input <path>noJSON body from a file (@path) or stdin (-); replaces the per-field flags. expires_in is a server-relative lifetime in seconds and is mutually exclusive with the absolute expires_at. Omitting both applies the organization’s finite default TTL.
Terminal window
alter keys mint --name "prod-worker" --scopes grants:read,agents:read --expires-in 90d

Capture the secret from the plain_key field in the same pipeline, so it never lands in the terminal or shell history:

Terminal window
# Only the secret, as a bare string — pipe it straight into a secret store
alter keys mint --name ci-deploy --scopes grants:read --output json | jq -r '.plain_key'
# Or narrow the JSON to that one field
alter keys mint --name ci-deploy --scopes grants:read --output json --fields plain_key

Every app key expires. If neither expiration flag is supplied, the backend applies the organization key policy’s Default key TTL (days) (90 days by default). Explicit values are rejected when they exceed Maximum key TTL (days) (365 days by default). The CLI has no unlimited-key flag.

Terminal window
alter keys show --key <key-id>

Issue a new secret for an existing key. The new plaintext is returned once; the old key enters a grace period until it’s revoked. An app-key successor receives a fresh lifetime from the organization’s current finite default. --scopes optionally changes the scope set (defaults to the current one). A key created before the September 2026 key-security upgrade (including every historical no-expiration key) can no longer authenticate and cannot be rotated — mint a new key instead; see Keys created before the September 2026 upgrade.

Terminal window
alter keys rotate --key <key-id>

Revoke a key immediately. This cascades to any derived keys. Revocation is recoverable — mint a new key — so the CLI asks a simple y/N (skip with --yes).

--force overrides the last-active-key guard, which otherwise blocks revoking the last active key on an app or an agent (whatever authenticates with that key stops working until a fresh key is minted). Use it deliberately — for example to clear a key whose plaintext was never captured.

Terminal window
alter keys revoke --key <key-id>
alter keys revoke --key <key-id> --yes --force # CI, deliberate

Change a key’s display name. Cosmetic only — it does not rotate the secret.

Terminal window
alter keys rename --key <key-id> --name "prod-worker-east"

Mint the Developer Portal’s Backend service template from the CLI

Terminal window
alter keys mint --name backend-service \
--scopes grants:write,providers:read,tokens:retrieve,proxy:execute,connect:initiate,audit:emit

This is the CLI equivalent of choosing Backend service under App → API Keys → Create key. OAuth Connect requires connect:initiate and grants:write together; providers:read powers SDK provider discovery, and audit:emit lets direct SDK calls record provider outcomes.

Rotate a key without downtime

Terminal window
# 1. Rotate — a new plaintext is printed once; the old secret keeps
# working during its grace window.
alter keys rotate --key <key-id>
# 2. Roll the new value out everywhere and confirm healthy traffic.
# 3. Revoke the superseded key once nothing depends on it.
alter keys revoke --key <key-id> --yes

Mint a short-lived key for a CI job

Terminal window
alter keys mint --name ci-deploy --scopes grants:read,agents:read --expires-in 1h

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.