// Tools

xeroctl keys

Mint, rotate, and revoke project API keys from the terminal. The key value prints once at create or rotate; everything after that is metadata.

One look only. The full key value prints once at create and once at rotate. Save it before you close the terminal. The router cannot show it again.

Keys carry permission scopes, an optional endpoint pin, an optional expiration, optional IP allow/block rules, and a per-key rate quota. The action is selected by the action flag (--create, --delete, --rotate, --ip-filter, --quota); one action per invocation.

Base URL and authenticating key are read from the active xeroctl deployment. The project is taken from the deployment's base_url (the /<project>/v1 path segment), not supplied separately. Use --frontend-url to override for a single invocation. The global --dry-run flag prints the planned request for every write action without sending it.

Wire surface

Method Path Action
GET/v1/management/api-keyslist
POST/v1/management/api-keyscreate
GET/v1/management/api-keys/<id>get
DELETE/v1/management/api-keys/<id>revoke (soft, is_active=false)
POST/v1/management/api-keys/<id>/rotaterotate (opens grace window)
PUT/v1/management/api-keys/<id>/ip-filterip-filter, whole-object replace
PUT/v1/management/api-keys/<id>/quotaquota, whole-object replace

Placeholders used below: key_abc123 is an example key id, 11111111-2222-3333-4444-555555555555 is an example endpoint UUID, INTERNAL_IP stands in for a literal address like 198.51.100.7. Substitute real values.

Usage Pattern

bash
xeroctl keys # List API keys xeroctl keys <id> # Show key details xeroctl keys --create --name <n> --scopes <s> # Create a new key xeroctl keys <id> --delete # Revoke a key xeroctl keys <id> --rotate # Rotate a key xeroctl keys <id> --ip-filter --allow <ip> # Update IP filter xeroctl keys <id> --quota --quota-requests <n> --quota-window <s> # Update quota

list

List all API keys for the project. This is the default action when no ID or action flag is given.

bash
xeroctl keys xeroctl keys --include-inactive

Options

Option Description
--include-inactive Include revoked (inactive) keys in the listing. Maps to query ?include_inactive=true.

Output columns: ID, NAME, PREFIX, SCOPES, ACTIVE, LAST_USED, EXPIRES.

get

Show full details of a specific API key.

bash
xeroctl keys key_abc123 xeroctl keys key_abc123 -o json

The default (text) renderer prints the following fields:

  • ID
  • Project ID
  • User ID (or (machine key) when unset)
  • Name
  • Prefix
  • Scopes
  • Active
  • Quota Requests
  • Quota Window (seconds)
  • Total Requests
  • Last Used
  • Expires
  • Created
  • Allow List (only when non-empty)
  • Block List (only when non-empty)
  • Endpoint (UUID; only when the key is endpoint-scoped)

create

Create a new API key. Both --name and --scopes are required.

bash
# Basic key for inference access xeroctl keys --create --name "Production App" --scopes inference # Key scoped to a specific endpoint (UUID, not slug) xeroctl keys --create \ --name "CI Pipeline" \ --scopes inference \ --endpoint-id 11111111-2222-3333-4444-555555555555 # Key with expiration xeroctl keys --create \ --name "Temporary Key" \ --scopes inference \ --expires 2026-12-31T00:00:00Z # Full options (multiple scopes, endpoint pin, expiration) xeroctl keys --create \ --name "Data Pipeline" \ --scopes inference,research \ --endpoint-id 11111111-2222-3333-4444-555555555555 \ --expires 2027-01-01T00:00:00Z

Options

Option Description
--name <name> Human-readable key name (required)
--scopes <scopes> Comma-separated scopes (required). See Scopes.
--endpoint-id <uuid> Restrict key to a specific endpoint UUID (not a slug).
--expires <date> Expiration date in ISO 8601 format (e.g., 2026-12-31T00:00:00Z)

Two MCP-related fields, catalog tier and Allow destructive XEM tools, are not set from this CLI. They live on the Scopes reference and the frontend key edit form.

delete / revoke

Revoke an API key. The key is immediately deactivated (the underlying row is marked is_active=false; it is not hard-deleted). Revoked keys remain visible to xeroctl keys --include-inactive. A confirmation prompt is shown by default.

bash
# With confirmation prompt xeroctl keys key_abc123 --delete # Skip confirmation xeroctl keys key_abc123 --delete --force # Dry run xeroctl keys key_abc123 --delete --dry-run

Options

Option Description
--force Skip the confirmation prompt
--dry-run Show what would be deleted without making changes

rotate

Rotate an API key, generating a new key value. Rotation opens a grace window during which the previous key value also continues to authenticate; update consumers within the grace window. A confirmation prompt is shown by default.

bash
# With confirmation prompt xeroctl keys key_abc123 --rotate # Skip confirmation xeroctl keys key_abc123 --rotate --force # Rotate and set a new expiration on the rotated key xeroctl keys key_abc123 --rotate --expires 2027-01-01T00:00:00Z

Options

Option Description
--expires <date> Optional new expiration (ISO 8601) for the rotated key.
--force Skip the confirmation prompt
--dry-run Show what would happen without making changes

Response fields

The new key value prints once. Grace metadata prints alongside it: Prefix, Previous Prefix, Grace Expires, Grace Remaining (s). Match Previous Prefix against in-flight client logs to find consumers still presenting the old key, and roll them before the grace window closes.

ip-filter

Update IP filter rules for a key. Specify allowed and/or blocked IP addresses and CIDR ranges. Both --allow and --block are repeatable.

bash
# Allow only private network traffic xeroctl keys key_abc123 --ip-filter \ --allow 10.0.0.0/8 \ --allow 192.168.0.0/16 # Block specific IP addresses xeroctl keys key_abc123 --ip-filter \ --block 203.0.113.5 \ --block 203.0.113.6 # Allow a range and block a specific IP xeroctl keys key_abc123 --ip-filter \ --allow 10.0.0.0/8 \ --block INTERNAL_IP # Clear the allow list (leaves the block list as-is) xeroctl keys key_abc123 --ip-filter --clear-allow # Clear both lists xeroctl keys key_abc123 --ip-filter --clear-allow --clear-block

This endpoint is a PUT, the request is a whole-object replacement of the field(s) you send. Omitting --allow / --block leaves that list unchanged; passing --clear-allow or --clear-block explicitly sends an empty list.

Options

Option Description
--allow <ip> Allowed IP address or CIDR range (repeatable)
--block <ip> Blocked IP address or CIDR range (repeatable)
--clear-allow Replace the allow list with an empty list (removes all allow rules).
--clear-block Replace the block list with an empty list (removes all block rules).
--dry-run Show what would be updated without making changes

quota

Update rate quota settings for a key. The quota is expressed as a request count over a window of N seconds; there is no implicit per-minute meaning. Defaults are quota_requests=60 and quota_window=60.

bash
# 1000 requests per 60 second window (default window) xeroctl keys key_abc123 --quota --quota-requests 1000 # 500 requests per 120 second window xeroctl keys key_abc123 --quota --quota-requests 500 --quota-window 120 # Dry run xeroctl keys key_abc123 --quota --quota-requests 200 --dry-run

This endpoint is a PUT, the request is a whole-object replacement. Omitted fields are left unchanged on the key.

Options

Option Description
--quota-requests <n> Maximum number of requests allowed per quota window.
--quota-window <n> Quota window length in seconds.
--dry-run Show what would be updated without making changes

Scopes

Scopes control which API operations the key is authorized to perform. The router accepts exactly four scope values; any other value is rejected with HTTP 400 unknown scope. Pass multiple scopes as a comma-separated list to --scopes. See also Authentication for the canonical scope reference.

Scope Description
inference Baseline inference dispatch (chat completions, Responses API, embeddings, and other model-serving routes).
management Administrative management-plane access (keys, projects, endpoints, quotas).
execution XEM execution surface (x_exec and per-tool execution gates). Implies the per-tool research gates as well.
research Research-surface tools (e.g. deep_think) that need gated access without full XEM execution rights.

Catalog tier and destructive XEM tools

Each API key also carries two MCP-related fields that scopes alone do not express:

  • Catalog tier (core, exec, intel, all), trims the MCP tools/list surface to a fixed subset of wire names. all is the inclusive default. core publishes the read-only baseline (workspace lookup, memory recall / save / search, calculator, session init, web research / fetch / inspect). exec adds the governed XEM xerotier.exec.* family. intel adds the intelligence surface (decisions, milestones, relations, graph, artifact lifecycle, code / repo tools).
  • Allow destructive XEM tools, a per-key opt-in toggle that lets the key invoke XEM adapters tagged as destructive.

The xeroctl keys CLI does not currently expose either field; both are configured on the frontend API key edit form. See MCP for the catalog-tier definitions and Authentication for the destructive opt-in semantics.

Examples

Create a Production Key

bash
# Create key with multiple scopes xeroctl keys --create \ --name "Production API" \ --scopes inference,research # The full key value is printed once, save it immediately

Secure a Key with IP Filtering

bash
# Allow only your datacenter CIDR xeroctl keys key_abc123 --ip-filter --allow 203.0.113.0/24

Apply Rate Limits

bash
# Limit to 100 requests per 60 second window xeroctl keys key_abc123 --quota --quota-requests 100 --quota-window 60

Rotate a Compromised Key

bash
# Immediately rotate (no prompt) xeroctl keys key_abc123 --rotate --force # New key value is printed, update your systems before proceeding

Troubleshooting

Symptom Likely cause Fix
401 on a rotated key Consumer still presenting the pre-rotate value; grace window expired. Match Previous Prefix from --rotate output against client logs; roll the consumer to the new value.
403 not authorized Key missing the scope for the route (e.g. management for key admin). See Scopes; recreate or rotate with the correct --scopes.
400 unknown scope Scope value outside inference / management / execution / research. Use one of the four documented values; multiple as a comma-separated list.
403 from an allowed IP Allow list set but request egress IP not covered, or block list shadows allow. xeroctl keys <id> -o json to inspect allow/block; re-run --ip-filter with the correct CIDR.
429 spike after key swap New key inherited the default quota (60 / 60s). Resize with --quota --quota-requests <n> --quota-window <s>; see Error handling for retry guidance.
Lost key value Not saved at create or rotate. Cannot be recovered. --rotate the key and capture the new value.