Skip to main content

Key lifecycle

After issuing an API key, you can update its metadata, rotate the secret, or revoke it. All lifecycle operations use the admin plane.

First, issue a key to work with:

RESPONSE=$(talos keys issue "lifecycle-test" \
--actor user_1 \
--scopes "read,write" \
--metadata '{"team":"backend"}' \
--format json \
-e "$TALOS_URL" 2>/dev/null)

echo "$RESPONSE" | jq .

export API_SECRET=$(echo "$RESPONSE" | jq -er '.secret')
export KEY_ID=$(echo "$RESPONSE" | jq -er '.issued_api_key.key_id')

When you set ttl on issue or import requests, the HTTP API accepts extended formats such as 1y, 1mo, 1w, 1d, and compounds like 1y6mo in addition to standard Go durations. The current CLI --ttl flags still expect standard Go duration strings; see the configuration reference for the canonical duration format summary.

Update key metadata

Use PATCH to update a key's name, scopes, metadata, or rate limit policy without changing the secret:

talos keys issued update "$KEY_ID" \
--name "lifecycle-test-updated" \
--scopes "read" \
--metadata '{"team": "backend", "tier": "premium"}' \
-e "$TALOS_URL"

Update mask

The update_mask field controls which fields are modified. Only fields listed in paths are changed. This follows the AIP-134 standard for partial updates.

Updatable fields include name, scopes, metadata, and rate_limit_policy. For the complete field reference, see the UpdateIssuedAPIKey API reference.

Rotate a key

Rotation creates a new key with a new secret and immediately revokes the old one:

RESPONSE=$(talos keys issued rotate "$KEY_ID" \
--scopes "read,write,admin" \
--format json \
-e "$TALOS_URL" 2>/dev/null)

echo "$RESPONSE" | jq .

export API_SECRET=$(echo "$RESPONSE" | jq -er '.secret')
export KEY_ID=$(echo "$RESPONSE" | jq -er '.issued_api_key.key_id')

Rotation response

The response includes the new issued_api_key (with a new key_id), the new secret (shown once), and old_issued_api_key (status KEY_STATUS_REVOKED). For the complete field reference, see the RotateIssuedAPIKey API reference.

Zero-downtime rotation

The :rotate endpoint revokes the old key immediately. For zero-downtime rotation:

  1. Issue a new key with POST /v2alpha1/admin/issuedApiKeys
  2. Deploy the new secret to all services
  3. Verify the new secret works everywhere
  4. Revoke the old key with POST /v2alpha1/admin/apiKeys/{old_key_id}:revoke

Revoke a key

Revocation is irreversible. Once revoked, the key fails verification immediately (subject to cache TTL):

talos keys revoke "$KEY_ID" --reason superseded -e "$TALOS_URL"

Revocation reasons

Standard reasons include REVOCATION_REASON_KEY_COMPROMISE, REVOCATION_REASON_SUPERSEDED, REVOCATION_REASON_AFFILIATION_CHANGED, and REVOCATION_REASON_PRIVILEGE_WITHDRAWN (admin only). For the complete list, see the RevokeAPIKey API reference.

When using PRIVILEGE_WITHDRAWN, you can include a reason_text field with a human-readable explanation.

Revocation and caching

Revocation takes effect in the database immediately. However, if caching is enabled, previously cached verification results may remain valid until the cache entry expires. To force immediate effect, use the Cache-Control: no-cache header on verification requests.

Verify after revocation

Confirm the key is no longer valid:

talos keys verify "$API_SECRET" --no-cache -e "$TALOS_URL" || true

Next steps