Reference
Authentication
Sign in with a browser or a pre-minted PAT, and control where credentials are stored.
The CLI authenticates with a Personal Access Token (PAT) — the same credential the dashboard issues under Settings → Personal Access Tokens. A PAT carries a fixed scope set chosen at mint time; the CLI sends it on every request.
There are two ways to sign in: an interactive browser flow (best for laptops) and a pre-minted token (best for CI).
Interactive sign-in
Section titled “Interactive sign-in”alter auth loginThis opens the dashboard in the browser, waits for the Authorize click, and receives the freshly-minted PAT on a local listener. No copy-paste, and the token never lands in shell history.
With no --scopes flag, the browser flow requests this exact routine set:
dashboard_apps:read, dashboard_apps:write,dashboard_keys:read, dashboard_keys:write,dashboard_agents:read, dashboard_agents:write,dashboard_providers:read, dashboard_providers:write,dashboard_app_policy:read, dashboard_audit:read, dashboard_pats:read,dashboard_secrets:read, dashboard_secrets:write,dashboard_grants:readIt deliberately excludes every admin / delete permission, policy-rule
mutation, identity-provider trust/webhook permission, and the read-only
analytics, end-user, branding, and approvals families. Pass --scopes to
request a different set. The supplied list replaces the defaults; it does
not append to them:
# Read-only sessionalter auth login --scopes dashboard_apps:read,dashboard_keys:read
# Privileged session containing exactly these two permissionsalter auth login --scopes dashboard_keys:admin,dashboard_apps:deleteScope names are validated before the browser opens, so a typo fails fast. See the scope reference below.
Login flags
Section titled “Login flags”| Flag | Applies to | Behavior |
|---|---|---|
--token-file <path> | Pre-minted PAT | Read the token from a file. Mutually exclusive with the other token channels. |
--token-stdin | Pre-minted PAT | Read the token from stdin. Mutually exclusive with the other token channels. |
--token <pat> | Pre-minted PAT | Read the token from argv. The value is visible in shell history and process listings; prefer a file or stdin. |
--base-url <url> | Both flows | Use and persist an alternate API origin. HTTPS is required and trailing slashes are removed. |
--dashboard-url <url> | Browser flow | Override the consent-page origin when it cannot be derived from the API origin. HTTPS is required. |
--scopes <list> | Browser flow | Replace the default requested scopes with a validated comma-separated list. |
--bind-ip <ip-or-cidr> | Browser flow | Bind the minted PAT to one IPv4/IPv6 host or CIDR. Bare hosts normalize to /32 or /128; DNS names, zone IDs, malformed ranges, and every /0 catch-all are rejected. |
--no-bind-ip | Browser flow | Explicitly request an unbound PAT. This is also the current default, so the flag is a compatibility no-op. |
--bind-ip and --no-bind-ip use last-flag-wins semantics when both appear.
Neither binding flag nor --scopes may be combined with a pre-minted token,
because those properties were fixed when that PAT was minted.
Headless and CI
Section titled “Headless and CI”In an environment with no browser, mint a PAT in the dashboard (Settings → Personal Access Tokens → New token) and hand it to the CLI through one of these channels, in decreasing order of safety.
The cleanest option for CI — nothing is persisted to disk and the value never appears in process arguments.
export ALTER_PAT="alter_pat_..."alter apps listKeeps the value out of shell history and out of ps output.
umask 077 && printf '%s' "$PAT" > ~/alter-pat.txtalter auth login --token-file ~/alter-pat.txtPipe the token in:
echo "$PAT" | alter auth login --token-stdinPassing the token inline with --token <pat> works but is discouraged — the value is visible to other local users via ps and lands in shell history.
The CLI verifies the token authenticates before storing it, so a wrong paste fails immediately rather than on the next command.
Credential storage
Section titled “Credential storage”After a successful alter auth login, the PAT is resolved in this order (highest precedence first):
ALTER_PATenvironment variable — the canonical CI / headless source.- OS keychain — macOS Keychain, Linux Secret Service /
gnome-keyring, or Windows Credential Manager. This is the default location after an interactive login. - Plaintext fallback file at
$XDG_CONFIG_HOME/alter/auth.toml, or~/.config/alter/auth.tomlwhenXDG_CONFIG_HOMEis unset (mode0600) — used only when the OS keychain isn’t available on the host. The CLI prints a warning on every fallback save and warns on reads if the file is group- or world-readable.
If keychain support isn’t loading, install the platform build tools and reinstall:
xcode-select --installnpm install -g @alter-ai/clisudo apt install libsecret-1-dev gnome-keyringnpm install -g @alter-ai/cliStatus and sign-out
Section titled “Status and sign-out”# Show the active PAT, its scopes, and expiryalter auth status
# Same view, under the pats namespacealter pats whoami
# Forget the locally-stored PAT (does NOT revoke it server-side)alter auth logoutalter auth logout only clears the local credential. To revoke a PAT so it can no longer be used anywhere, delete it in the dashboard.
ALTER_PAT has higher precedence than every stored credential and is not
modified by logout. If it remains exported, subsequent commands continue to
authenticate with that environment token; unset it separately. auth status
returns exit code 3 when no credential resolves, but its explicit backend
probe returns generic code 1 when a resolved PAT is rejected. pats whoami
uses the same generic code for a rejected resolved PAT. Regular resource
commands that use the shared authenticated-command path map a backend 401 to
code 3.
Self-hosted and staging
Section titled “Self-hosted and staging”By default the CLI talks to Alter’s production API. For an alternate
deployment, pass --base-url during login; that origin is stored with the PAT
and reused by later commands. The browser flow derives the dashboard origin
from it, or accepts --dashboard-url when the origins do not follow the
standard naming pattern. Both flags require https://. --dashboard-url is
ignored by the pre-minted-token flow because no browser is opened.
Scopes
Section titled “Scopes”A PAT’s scopes are <resource>:<verb> strings. Each resource supports a fixed verb set:
| Resource | Verbs | Used by |
|---|---|---|
dashboard_apps | read, write, admin, delete | apps |
dashboard_keys | read, write, admin | keys |
dashboard_agents | read, write, admin | agents |
dashboard_providers | read, write, admin, delete | providers; delete is wildcard-excluded |
dashboard_secrets | read, write, admin, delete | managed-secrets |
dashboard_app_policy | read, rules_create, rules_update, rules_delete | policy — the rules_* verbs are mintable for API automation and consumed by alter policy rules … |
dashboard_audit | read | audit |
dashboard_identity_providers | create, webhooks | identity-providers — both verbs must be admin-minted (see below) |
dashboard_pats | read | pats whoami |
dashboard_grants | read, admin | grants |
dashboard_analytics | read | analytics |
dashboard_end_users | read | end-users |
dashboard_branding | read, write | branding |
dashboard_approvals | read | approvals |
Three resources separate delete into its own verb instead of bundling it under admin: dashboard_apps, dashboard_secrets, and dashboard_providers. Each delete is an irreversible cascade, so it requires an explicit opt-in at mint time and a server-enforced type-to-confirm value — the same posture as GitHub’s separate delete_repo scope. A token with write or admin can do everything except those cascade deletes. dashboard_app_policy applies the same explicit opt-in to its rules_update and rules_delete verbs: updating or deleting a deny rule can loosen enforcement, so neither is ever granted by a wildcard — select them by name at mint time (rules_create only ever restricts, so it stays a routine automation verb).
dashboard_identity_providers:create and :webhooks govern SSO trust configuration — an organization-admin area — so, like the wildcard-excluded delete/policy verbs, they are never granted by a wildcard and only an organization admin can mint a PAT carrying them: a non-admin’s alter auth login --scopes dashboard_identity_providers:create is refused at sign-in. (Creating an SDK API key via alter keys mint/rotate is likewise admin-only, but enforced at use time against the token owner’s role rather than at mint time — so dashboard_keys:write itself stays member-mintable.)
If a command returns exit code 7 (FORBIDDEN), the request was refused — most often because the PAT is valid but missing a scope. Start a new browser login with --scopes containing the complete desired set, or mint a broader PAT in the dashboard; a plain login only requests the routine default set and never upgrades the existing token implicitly. The same code is also returned when the organization’s plan does not include the feature (for example alter branding set without custom branding) — no PAT can satisfy that, so read the stderr line, which names which of the two applies.