Skip to main content
Use a personal Firebase credential or personal MCP token within the server’s current authority checks. API keys, including legacy keys, cannot manage credentials. Creating or rotating a key requires private human browser confirmation after a recent real Firebase sign-in; preparation and metadata readback never disclose its secret. Legacy key operations below require an explicitly selected team and its current team administrator/owner or billing-account administrator. Named scoped operations instead use the explicit billing account and returned server capabilities: its owner or bounded credential administrator may create, while an existing key’s managers may read, revoke or prepare rotation within their per-key permissions. Named metadata access does not require selecting a team. Personal Firebase access must pass real-provider and current MFA checks; a body field or administrator label cannot substitute for those checks.

Named keys with explicit scope

Use a separate named key for each integration. A scoped key belongs to one billing account and one explicit mode, with reviewed team_ids, action_ids, expires_at (epoch milliseconds), and manager_user_ids. Action IDs are exact public operation IDs from the current server policy catalog; a label such as “all writes” is not a scope. Named service keys belong to the organization: the issuer UID records attribution, rather than borrowing that person’s current human permissions. Each request still checks the key’s exact scope and current account/team state, API entitlement and server policy. Read GET /users/me/scoped-api-keys/policy?billing_account_id=ACCOUNT_ID using a personal Firebase or MCP identity. The policy lists eligible teams, actions and managers, creation authority, and expiry/overlap bounds. Account owners may omit expires_at or set it to null for no expiration. A chosen expiry cannot exceed 365 days; bounded delegated administrators must supply a future expiry within their assigned limit. Existing dates are preserved. The server rechecks eligibility during private execution rather than trusting a saved policy. Prepare api_keys.create_scoped through POST /users/me/account-approvals with a saved UUIDv4 and payload {name,livemode,billing_account_id,team_ids,action_ids, expires_at,manager_user_ids}. Preparing does not issue a credential. The initiating person reviews the exact scope in the private browser after a recent real sign-in. Only the first successful private execution response contains the secret. Store it locally in the integration’s secret manager; subsequent reads and retries contain metadata only. An API key, including a legacy key, cannot manage key lifecycles. List metadata with GET /users/me/scoped-api-keys?billing_account_id=ACCOUNT_ID. Read one key at GET /users/me/scoped-api-keys/{keyId} and its safe lifecycle audit at GET /users/me/scoped-api-keys/{keyId}/audit; include the billing-account query. Use the returned capabilities and per-key management permissions. Audit entries contain safe lifecycle evidence, never request bodies, headers or tokens. last_used_at is observed usage only; null means unavailable, not never used. Prepare api_keys.rotate_scoped with {key_id,overlap_seconds}. Rotation copies that key’s immutable scope and managers without widening them. Review the explicit overlap period: the predecessor remains usable only until its scheduled revocation or earlier expiry. Other keys remain untouched. Revoke a single key using DELETE /users/me/scoped-api-keys/{keyId} with {operation_id:UUID} and the exact billing-account query. Preserve the UUID after an uncertain response and inspect metadata before repeating the identical request; do not automatically rotate again.

Use named keys from CLI or MCP

The create file contains the fields listed above; expires_at is optional for owners. manager_user_ids:[] adds no delegated managers. Choose action_ids from policy, and set expires_at to null for no expiration or an actual future epoch-ms value within its expiry bound. Rotation preserves the expiry choice, including no expiration. List/audit accept --limit and --cursor; continue until next_cursor:null, even after an empty page. Preparation succeeds with safe approval metadata and a review_url, not a key. CLI exits nonzero for refused or unconfirmed requests and retains the operation reference for readback; it never repeats a consequential request automatically. The named MCP equivalents are account_api_keys_policy_get, account_api_keys_list, account_api_keys_create_prepare, account_api_keys_rotate_prepare, account_api_keys_get, account_api_keys_audit_list, and account_api_keys_revoke. Use existing get_account_approval to inspect preparation. An agent can request review within current authority, but cannot execute the private secret-disclosure terminal.

Migrate an existing integration

Existing keys and tokens remain valid according to their existing checks. The legacy_unrestricted label means no reviewed explicit action/team scope was stored; it does not exempt a legacy credential from current account and permission checks. No migration deadline, forced rotation, or automatic retirement is implied.
  1. Inventory one integration’s actual teams, mode and API operations.
  2. Read policy and prepare a named key with those exact allowed operation IDs.
  3. Review privately and store the one-time secret in that integration.
  4. Verify its required requests and expected denial for excluded actions/teams.
  5. Switch that integration, then deliberately revoke its old key when ready.
Repeat per integration. Keep the legacy key until its remaining consumers have migrated; do not use legacy pair rotation as a shortcut for per-key rotation. Legacy pair creation and rotation below exclude scoped keys. The existing emergency operation revokes legacy API/MCP credentials only; named scoped keys are untouched.

Owner emergency for named scoped keys

The current personal billing-account owner can revoke all scoped keys across both modes using POST /users/me/scoped-api-keys/emergency-revoke with the exact billing account query and {operation_id:UUID}. Delegated credential administrators, key managers and API keys cannot use this operation. Legacy API keys, MCP and OAuth credentials remain untouched. Pending scoped create/rotate approvals are invalidated. Save the UUID before requesting revocation. Read GET /users/me/scoped-api-keys/emergency-revocations/{operationId} with the same billing account after an uncertain response. processing reports a partial revoked_count and completed_at:null; only completed reports the final count. Repeating POST with the same UUID deliberately resumes the existing operation; do not retry automatically or substitute a new UUID.
MCP uses account_api_keys_emergency_revoke with the saved operation UUID, scope:"billing_account_scoped_keys" and confirmed:true, followed by account_api_keys_emergency_get for readback. The confirmation fields express intent; the backend independently checks current personal owner authority.

First-release action catalog

The first scoped-key catalog permits business reads, including client reads, and service creation, updates and deletion. Client mutations, fiscal issuance or cancellation, refunds, automation, team/user administration, and credential lifecycle are not grantable. Client writes can trigger downstream Stripe/fiscal effects whose scope proof is not yet covered. Read policy for the exact allowed operation IDs; new routes never inherit a grant. Unknown or unreviewed routes return scoped_action_unavailable. Existing legacy credentials retain their existing behavior; this release does not claim scoped-key coverage for every account workflow.

Handle a server denial

Select an allowed team and the key’s exact mode. If an operation is missing from action_ids, ask a current credential administrator to prepare a separately reviewed key; the integration cannot grant itself permission. If current module permissions or account entitlement are missing, correct that authority first. Per-key managers can inspect/revoke/prepare rotation for managed keys, without receiving permission to create or widen keys. Policy and safe key responses expose current capabilities; credentials never override an explicit server denial.

Legacy pair: inspect before creating

The equivalent API request is GET /api-keys?team=TEAM_ID. It returns metadata only: keyid, type, team, livemode, valid, timestamp, invalidTimestamp and lastUsedAt. Stored JWTs never appear in list responses. Pagination uses limit (1–100, default 20), cursor, has_more and next_cursor. include_revoked=true includes revoked API keys. A filtered page can be empty and still have another cursor; stop only when has_more is false. Personal MCP tokens have their own account endpoints.

Legacy pair: prepare creation or rotation

Credential issuance requires an authenticated browser approval. Save a UUIDv4 before preparing each new request. The CLI commands return safe approval state and review_url, never secrets:
These commands call POST /users/me/account-approvals with action api_keys.generate or api_keys.rotate, the explicit team_id and payload:{}. The old --out secret-file and issuance confirmation flags are no longer accepted. The initiating person opens the authenticated review link, verifies the team, requested live/test modes and exact revocations, and confirms there after a recent real sign-in. Only that committing browser request receives the newly issued keys. Legacy pair creation requires no active legacy API keys; rotation revokes only the reviewed legacy API keys and preserves scoped keys and personal MCP tokens. Relevant account/key changes invalidate the request rather than silently expanding its scope. The current API entitlement and administrator authority are rechecked at execution. After an uncertain preparation response, repeat only the original operation UUID and exact input. After a lost browser execution response, read the approval receipt; secrets cannot be retrieved. See credential approvals. POST /api-keys and POST /api-keys/rotate are retired and return HTTP 403 account_approval_required, including for freshly authenticated Firebase users. They do not create credentials. Existing list and revocation operations remain.

Revoke one key or perform emergency revocation

DELETE /api-keys/{keyId}?team=TEAM_ID returns metadata with valid: false. Calling it again returns the revoked state. Foreign keys and MCP token IDs return 404; this operation only revokes API credentials. For an explicitly requested team-wide emergency:
POST /api-keys/emergency-revoke?team=TEAM_ID revokes active legacy API and personal MCP credentials associated with the team. It can revoke the calling legacy MCP credential. Named scoped keys and records with malformed scoped markers are untouched. OAuth tokens are not revoked. Its historical scope: "team_api_and_mcp_keys" label describes the legacy operation; it does not mean all named scoped keys were revoked. oauth_revoked remains false. The server batches large revocations and retains a revocation fence across interruptions. Continue through another still-authorized Firebase/user session if the calling MCP token has been revoked; do not assume the whole account has been disconnected from OAuth integrations.

Handle an uncertain result

Responses are not cacheable. Never log one-time keys or copy them into source files. A timeout can happen after a pair was created or revoked: read the current metadata before another mutation. Listing cannot recover an already-issued secret. If delivery of a new key was lost, a subsequent deliberate rotation is a new consequential action, not an automatic retry. Before release, the signing identity and audience must match the deployed API gateway. Source and offline checks do not prove that environment configuration.