Skip to content

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).

Terminal window
alter auth login

This 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:read

It 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. The one exception is dashboard_pats:read: the CLI always adds it, because it verifies every sign-in by reading the new token’s own metadata (the same call alter auth status makes), and a token without it cannot complete the login. It is a read-only self-inspection permission, never a widening. The consent page shows it as required and does not let it be dropped, so the approved token always carries it.

Terminal window
# Read-only session
alter auth login --scopes dashboard_apps:read,dashboard_keys:read
# Privileged session containing exactly these two permissions (plus dashboard_pats:read)
alter auth login --scopes dashboard_keys:admin,dashboard_apps:delete

The browser flow waits up to 10 minutes for the approval; if the page is left unapproved, the CLI exits with a timeout and the login can simply be re-run.

Scope names are validated before the browser opens, so a typo fails fast. See the scope reference below.

FlagApplies toBehavior
--token-file <path>Pre-minted PATRead the token from a file. Mutually exclusive with the other token channels.
--token-stdinPre-minted PATRead the token from stdin. At a terminal this prompts with hidden input; a pipe or redirect is read non-interactively. Mutually exclusive with the other token channels.
--token <pat>Pre-minted PATRead the token from argv. The value is visible in shell history and process listings; prefer a file or stdin.
--base-url <url>Both flowsUse and persist an alternate API origin. HTTPS is required and trailing slashes are removed.
--dashboard-url <url>Browser flowOverride the consent-page origin when it cannot be derived from the API origin. HTTPS is required.
--scopes <list>Browser flowReplace the default requested scopes with a validated comma-separated list. dashboard_pats:read is always added (CLI 0.9.2 and later).
--bind-ip <ip-or-cidr>Browser flowBind 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-ipBrowser flowExplicitly 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.

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. Include dashboard_pats:read in its scopes: alter auth login and alter auth status verify the token by reading its own metadata, and a token without that permission is refused at sign-in with a message naming it.

The cleanest option for CI is a masked secret named ALTER_PAT. Configure it in your CI provider and let the provider inject it into the job environment — do not type a literal token into a shell command.

Terminal window
# ALTER_PAT is injected by the CI provider's secret store
alter apps list

Keeps the value out of shell history and out of ps output.

Terminal window
umask 077 && printf '%s' "$PAT" > ~/alter-pat.txt
alter auth login --token-file ~/alter-pat.txt

At a terminal this prompts for the token with hidden input, so the value never enters argv, shell history, or the visible screen:

Terminal window
alter auth login --token-stdin
# Paste the token at the prompt and press Enter — input stays hidden

When stdin is a pipe or redirect the token is read non-interactively instead, with no prompt. Use this in scripts where the value is already held in a variable or secret store:

Terminal window
printf '%s' "$PAT" | alter auth login --token-stdin

Passing 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.

After a successful alter auth login, the PAT is resolved in this order (highest precedence first):

  1. ALTER_PAT environment variable — the canonical CI / headless source.
  2. OS keychain — macOS Keychain, Linux Secret Service / gnome-keyring, or Windows Credential Manager. This is the default location after an interactive login.
  3. Plaintext fallback file at $XDG_CONFIG_HOME/alter/auth.toml, or ~/.config/alter/auth.toml when XDG_CONFIG_HOME is unset (mode 0600) — 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:

Terminal window
xcode-select --install
npm install -g @alter-ai/cli
Terminal window
sudo apt install libsecret-1-dev gnome-keyring
npm install -g @alter-ai/cli

For the app and agent keys you mint with the CLI, which the CLI does not store, see Your Credentials.

Terminal window
# Show the active PAT, its scopes, and expiry
alter auth status
# Same view, under the pats namespace
alter pats whoami
# Forget the locally-stored PAT (does NOT revoke it server-side)
alter auth logout

alter 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 and pats whoami return exit code 3 both when no credential resolves and when the backend rejects the resolved PAT (revoked, expired, or created before the September 2026 key-security upgrade), so a script can treat 3 as “sign in again”. A PAT that lacks the scope needed to read itself returns 7, and a backend that is temporarily unavailable returns the generic 1 — retry instead of signing in again. Regular resource commands map a backend 401 to code 3 the same way.

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.

A PAT’s scopes are <resource>:<verb> strings. Each resource supports a fixed verb set:

ResourceVerbsUsed by
dashboard_appsread, write, admin, deleteapps
dashboard_keysread, write, adminkeys
dashboard_agentsread, write, adminagents
dashboard_providersread, write, admin, deleteproviders; delete is wildcard-excluded
dashboard_secretsread, write, admin, deletemanaged-secrets
dashboard_app_policyread, rules_create, rules_update, rules_deletepolicy — the rules_* verbs are mintable for API automation and consumed by alter policy rules …; CLI update/delete also require read for the before/after review
dashboard_auditreadaudit — grants the runtime audit trail to any member; management-plane rows (key / provider / identity-provider lifecycle) narrow to the token owner’s own actions unless that owner is an organization admin, and audit integrity-check is admin-only. Checked at use time against the live role, like keys mint below.
dashboard_identity_providerscreate, webhooksidentity-providers — both verbs must be admin-minted (see below)
dashboard_patsreadpats whoami
dashboard_grantsread, admingrants
dashboard_analyticsreadanalytics
dashboard_end_usersreadend-users
dashboard_brandingread, writebranding
dashboard_approvalsreadapprovals

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.

Report an issue with this page

Necessary

Required for sign-in, security, authorization, and remembering your choices.

Always active

Analytics

Helps us understand which product and documentation features are useful.

Performance diagnostics

Uses performance tracing and privacy-masked session replay to diagnose problems.

You can change these choices at any time from Cookie settings.