Personal access tokens

Create, scope, rotate, and revoke the personal access tokens that authenticate Management API calls.

A personal access token is the only credential the Management API accepts. It is a bearer credential that belongs to one person in one organization, carries an explicit list of scopes, and always expires. Personal access tokens authenticate the Management API only; they are rejected on the portal's own API (a plain 401) and on the Inference API (401 credential_type_mismatch).

PropertyHow it works
Formattf-pat_ followed by 43 URL-safe characters (256 bits of randomness). The fixed prefix lets secret scanners recognise a Token Factory management credential on sight.
Shown onceThe full secret is displayed exactly once, when you create it. Afterwards the portal shows tf-pat_…a91f and the API returns a masked prefix such as tf-pat_AbCdE...a91f, plus its name, scopes, expiry and last use.
Hashed at restToken Factory stores a hash of the token, never the token itself. Nobody — including support — can show it to you again.
AttributableEvery token names its creator, and every call made with it is recorded in the audit log as that person using that token. A token is never anonymous and never a shared "service" identity.
One orgA token acts only in the organization it was created in.
Portal-boundA token works only on the portal where it was created; a token from any other Token Factory portal is unknown here (401 invalid_credential).

A token carries: id · name · prefix · scopes · created_by · created_at · expires_at · last_used_at · status (active · revoked; expiry is read from expires_at). It carries no project, no region and no key material.

Warning

Treat a personal access token like a password. Store it in a secret manager or your CI system's secret store, never in source control, never in a URL, and never in a log line. A personal access token can reshape your organization; a project API key can only spend.

Mint policy

RuleValue
Who can mintOrganization Admins, in the portal only. There is no API endpoint that creates a token.
Re-authenticationMinting is a sensitive action. If your last sign-in is not recent, the portal asks you to re-authenticate before the token is created.
NoteRequired, up to 64 characters, unique case-insensitively among your active tokens. A revoked token's note is free again — ci-deploy and CI-Deploy cannot both be active at once, but you can reuse a note once the token that held it is revoked.
ScopesAt least one, from the scope vocabulary. No wildcard; an unknown scope is refused.
ExpiryMandatory. Default 90 days; the portal offers 30, 60, 90, 180 or 365. Maximum 365 days. There are no eternal tokens.
Active-token cap20 active tokens per user. Minting a 21st is refused (token_limit_reached) — revoke one you no longer use.

These are portal rules: minting is not a Management API call, so a refused mint is reported in the portal's token dialog (invalid_name, invalid_scopes, invalid_expiry, token_name_taken, token_limit_reached), not in the Management API error envelope.

Why mandatory expiry: a standing credential with no review point is how organizations fail their own access reviews. Renewal is "mint the successor, revoke the predecessor", which also gives every integration a rehearsed rotation procedure.

Lifecycle

StageHowNotes
MintPortal → Settings → API Tokens → Create token opens a dialog: Note, Expiration, Select scopes (a scope tree) → Generate token. Admin only, with re-authentication.The one credential action a token can never perform itself. Sensitive scopes are flagged at selection.
UseAuthorization: Bearer tf-pat_… on every call.Never a query parameter, never a cookie. last_used_at updates as you use it.
ExpireAutomatic at expires_at.The next call fails with 401 token_expired.
RevokePortal → Revoke, or DELETE /me/tokens/{id} for your own tokens. Automatic when the owner is disabled; the tokens are deleted with the member when they are removed.Immediate — the next call fails with 401 token_revoked (or 401 invalid_credential once the owner is removed). There is no grace window.
AuditMint (pat_create) and revoke (pat_revoke) are audited; every write made with the token records its id, name and the scope used.See Audit log.

A token's scopes are fixed at mint. Nothing widens a token: to grant more, mint a new token. Role changes can only narrow what a token can do (the intersection rule).

When a member is disabled or removed, every personal access token they created stops working immediately and irreversibly. Project API keys they created are not touched — keys are project assets; a personal access token represents a person still acting. (Removing a member with "delete_keys": true is the explicit exception — see Members.)

Create a token in the portal

  1. Sign in to the portal as an organization Admin and open Settings → API Tokens. The card is titled Management API tokens:

    Personal access tokens authenticate the Management API — provisioning keys, projects, and members programmatically. They can't make inference calls, and project API keys can't call the Management API.

  2. Click Create token. This opens the Create Management API token dialog — nothing is created yet.

  3. Enter a Note that says what the token is for and who runs it — for example CI · payments-deploy. It must be unique (case-insensitively) among your active tokens.

  4. Choose an Expiration: 30, 60, 90, 180 or 365 days (default 90). Each option shows the calendar date the token would expire on. There is no "never" option — every token expires.

  5. Choose scopes under Select scopes — a two-column tree, one row per resource group in scope order. org, members, projects and keys each show a parent row: ticking it grants both the group's :read and :write scopes, and the two child rows then show ticked and greyed out (still one scope each on the wire — read and write stay independent). The remaining groups (usage:read, billing:read, audit:read, catalog:read) are single rows. Every row shows that scope's description. The three Sensitive writes — org:write, members:write, projects:write — carry a badge, and selecting any of them shows a one-line warning below the list. Nothing is preselected. A summary strip below the list tracks how many scopes are selected and when the token would expire.

  6. Click Generate token. If your last sign-in is not recent, the portal asks you to confirm your identity: choose Sign in again, sign in, and you return to the dialog with your note, expiration and scopes kept — click Generate token once more to create the token.

  7. The dialog switches to Token created, showing the secret with a Copy button and the token's name, expiry and scopes. Copy the secret now and store it in your secret manager — it is shown once, and the dialog ignores Escape and outside clicks so you can't lose it to a stray click. Click Done to close.

Each token then appears as a row with its name, masked prefix, creation date, expiry and last use (tf-pat_…a91f · created Mar 20, 2026 · expires Jun 18, 2026 · last used never), its scopes, and (for active tokens) a red Revoke button that asks you to confirm.

Tip

Every call is attributed to the token's creator. Mint automation tokens under a person who will stay responsible for that automation, and name the token after the job, not the person.

Verify a new token

The cheapest authenticated call is reading your own token list — it needs no scope:

curl https://portal.<domain>/api/v1/mgmt/me/tokens \
  -H "Authorization: Bearer $TF_PAT"

Rotate a token

Tokens have no grace window: mint the successor first; both work side by side until you revoke the old one. Rotation is three steps:

  1. Mint the successor in the portal with the same scopes and a fresh expiry.
  2. Deploy it — replace the secret in your CI system or secret manager and confirm one call succeeds.
  3. Revoke the predecessor — in the portal, or with DELETE /me/tokens/{id} using the new token.

Put a reminder on the calendar a week before expires_at. An expired token fails with 401 token_expired and an action telling you to mint a new one.

If a token leaks

Revoke it immediately (portal, or DELETE /me/tokens/{id}); revocation is effective on the next call. Then read the audit log filtered to the token owner (actor) and look for entries whose metadata.pat_id is that token's id to see what it did. See Incident response.