Signing in
The operator gets a full-privilege API key from the server — the owner keytai setup prints once — then pastes it into the Studio
at /login. The key is held in memory by
default; the remember on this device opt-in persists it to the browser
session so later navigations in the tab stay authenticated. When the server also
runs an accounts provider, the key field sits behind the
“Use an API key instead” toggle on the sign-in screen — a
permanent fallback alongside human login.
Keys are owned credentials
Once an accounts provider is enabled, an API key is a credential owned by an account rather than a free-standing secret. Ownership changes what a key may hold and who may mint it:- A key can never out-scope its owner. A key a non-admin mints is capped at a subset of its owner’s own authority; a request for more is rejected at mint time. The cap is re-checked on every call, so if the owner’s role is narrowed — or the owner is disabled — the key is attenuated with them on its next request.
- Machine keys belong to a service principal. For automation an admin creates a service principal — a non-human identity that holds keys but never logs in — and mints keys for it. That keeps the machine-to-machine path working while making an owner-bound key the default.
- Key breadth is not admin. A wide
["*"]scope on a key does not by itself make its holder an administrator of the key surface; the owner’s role decides it. A["*"]key owned by an administrator, with no condition on the key, is an administrator and can list, edit, and revoke other owners’ keys. A["*"]key owned by any other user, one that carries a condition, or a narrower key, cannot.
Provisioning more keys
Once signed in, the operator provisions further keys — full-privilege or scoped — from the API-keys tab of the Settings screen. That tab drives the server’s/api/auth provisioning endpoints, so a
key minted in the Studio is the same key you could mint from the
tai keys CLI. When you mint a key, the create dialog
asks which principal owns it — yourself by default; an admin may pick a service
principal or create one inline.
Every field in the dialog carries a one-line hint saying what it is for and whether
it is optional. The Key user ID is required: a new, unique ID the key acts as,
such as ci-runner, and it cannot be changed later. It is not the same field as the
Principal user ID in the inline create-service-principal form, which names the
principal and is optional — leave it empty to generate one.
Scopes are picked one by one, or with Full access (all scopes), which mints
the key with the universal ["*"] scope. While it is ticked the individual scopes
are hidden and a warning says what the key holds: every scope, including scopes
added later, yet no further than its owner’s access. If the owner is an
administrator and the key has no condition, the key is an administrator too and can
list, edit, and revoke other owners’ keys (see Key breadth is not admin above).
The box is offered to an
admin, or to a user whose own access already holds *; the edit dialog opens a key
that holds * with it ticked, and the keys table shows that scope as a
Full access badge.
The keys table carries a Principal column. Each row shows the principal that
owns the key — a human or a service principal, by kind and display name. A key
whose identity record was lost in a restore shows no principal and is marked
orphaned until the backup is re-imported. Ownership is the whole story of what
a key may hold and who may revoke it: an owned key is
capped at a subset of its owner’s authority and dies when its owner does. The
scope picker in the create dialog is capped to your own scopes, and a non-admin is
offered Full access only when it holds * itself, so a non-admin cannot mint a
key wider than itself.
Key provisioning and access control run on the
server’s Redis-backed auth store. A server booted without access control accepts
any key; a deployment that enforces it provisions keys and policies through this
tab.
Sharing a key by claim link
The create dialog is also where you hand a freshly minted key to another device without ever putting the secret in a URL. The moment a key is created its rawsk-… value is shown once, and the dialog offers a Create claim link (QR)
step: it turns that raw key into a one-time, short-lived
claim link and renders it as a QR code.
Scanning the code opens the sign-in page on the other device,
which exchanges the claim token for the key and signs in — the token rides the
URL fragment and burns on first use, so the credential never reaches a server
log.


The mint dialog's claim-link step: a freshly created key turned into a one-time QR claim link.
tai auth claim and CLI legs.
See access control for the jq policy model behind
scoped keys, owned keys for the delegation model, and the
CLI reference for provisioning keys from a terminal.
