Skip to content

API keys: scopes, expiry, revocation

Everything against sandbox-api.k8s.tangovision.dev authenticates with an org-scoped tvk_… bearer token. You mint keys in the developer portal; the plaintext is shown exactly once. This page is the reference for how keys behave.

Two invariants first:

  • A key can never mint another key. Minting requires a signed-in portal session, so a leaked key can't multiply itself.
  • Up to 5 active keys per org. Revoked and expired keys don't count — revoke what you don't use.

Scopes

Every key carries one scope, chosen at mint time:

ScopeAllowsUse it for
sandbox (default)The sandbox lifecycle API (/api/v1/sandboxes*): create, list, extend, reset, deleteDay-to-day module development, CI that provisions sandboxes
publishThe module-publish surface (arrives with tv-sdk publish; no endpoint accepts it yet)Release pipelines, once publishing ships
fullEverything above, plus key listing and revocation over the APIBreak-glass automation; prefer the narrower scopes

A request outside your key's scope fails with 403 and the error code SCOPE_DENIED — mint a key with the right scope rather than widening an existing workflow's key. Keys minted before scopes existed behave as full.

Expiry

Self-service keys always expire — after 90 days by default. Minting through the API instead of the portal, you can pick the lifetime:

bash
curl -X POST https://sandbox-api.k8s.tangovision.dev/api/v1/keys \
  -H "Authorization: Bearer $PORTAL_JWT" \
  -H "Content-Type: application/json" \
  -d '{"label": "ci", "scope": "sandbox", "expiresInDays": 30}'

expiresInDays accepts 1–365. An expired key gets 401 on its next request; mint a replacement in the portal (the key list shows each key's expiry date, and its status flips to expired). Non-expiring keys exist only as operator-minted credentials — ask developers@tango.vision if a service genuinely needs one.

Revocation

Revoke in the portal, or over the API:

bash
curl -X DELETE https://sandbox-api.k8s.tangovision.dev/api/v1/keys/<keyId> \
  -H "Authorization: Bearer $PORTAL_JWT"

Revocation is effective on the key's next request — every request re-checks the key store directly, with no cache in between, so the observed propagation delay is however long your next request takes to arrive. (The platform's formal commitment is under 5 minutes globally; in practice it's seconds.) If a key leaks, revoke it immediately and mint a replacement — and tell us, so we can check the audit trail with you.

Audit trail

Every key event is recorded: issuance (who minted, which scope, what expiry), use (each authenticated request: key, route, source IP, user agent), denials (revoked/expired/unknown keys, scope violations), and revocation. Records are kept for 18 months.

From a portal session you can query your org's trail:

bash
curl "https://sandbox-api.k8s.tangovision.dev/api/v1/keys/audit?limit=50" \
  -H "Authorization: Bearer $PORTAL_JWT"

Filters: action (key.issued | key.used | key.revoked), keyId, limit (≤ 500). The audit log is readable only from a signed-in portal session — an API key can't read it, deliberately: the rows contain IP addresses, which have no business sitting behind a CI secret.

Built on the Tango Vision platform. Questions? developers@tango.vision