Repository navigation
Stage-3: Multi-account UX #1384
Description
Note
TL;DR — After Stage-2 the CLI can store several accounts but can only use the active one. This adds the selection surface: a global --profile on commands that hit the API, apify auth switch, apify auth list, and per-profile logout. First stage users see. APIFY_TOKEN still wins over everything, so any flag or switch that it would override is an error.
Part of #1297. Depends on Stage-2 (#1386).
Commands and flags
--profile <name|userId>on every command that hits the API. Injected by the command framework for commands that opt in, the same wayenableJsonFlaginjects--json.create,initand other offline commands do not get it.apify auth switch [name]— set the active profile. Prompts when called without an argument, errors in a non-interactive shell.apify auth list— all profiles with last login and storage backend, active one marked, organization profiles labeled fromorganizationOwnerUserId.--jsonform for scripts. No network calls, so it works offline and does not validate tokens.apify logout --profile <name>andapify logout --all.--allconfirms first and takes the existingYesFlagfor scripts.apify infogains--profile, and its existing token-source row covers the new source.
APIFY_TOKEN interaction
resolveAuth() resolves APIFY_TOKEN before the stored login (shipped in #1418). A profile selection cannot beat it, so the rule is an error rather than a silent override.
| Case | Behavior |
|---|---|
--profile with APIFY_TOKEN set |
error, even when the two tokens match |
auth switch with APIFY_TOKEN set |
error — the switch would change nothing until the variable is unset |
auth list with APIFY_TOKEN set |
works, and says the variable is in use and overrides the active profile |
auth token with APIFY_TOKEN set |
works, prints the env token with its source |
logout with APIFY_TOKEN set |
works — it only touches stored profiles |
Wording follows the message login already uses: name the variable, say other commands ignore the change, say to unset it.
Other behavior
--profilenaming something that is not stored fails fast and lists the profiles that are, exitInvalidInput.auth switchchecks the target profile still has a secret in the keyring before switching. Local read, no network.apify run --profile xpasses that profile's token and proxy password to the Actor process.- Auth failures name the profile. A 401 means re-authenticate that profile, not that the CLI is logged out (actors search fails with 401 when user has expired/invalid token #1051).
- Telemetry follows the active profile, so
auth switchcallsupdateUserId().--profileon a single command does not change it. - A user with one profile sees no change apart from the new commands existing.
Not in this stage
No renaming profiles — names come from the token. No APIFY_PROFILE environment variable. No actor.json pin or directory overrides. mcp install keeps its own --token behavior and is not aligned with the rule above.
Verification
--profileselects the right account for a command that hits the API, and does not appear oncreateorinit--profileplusAPIFY_TOKENerrors; so doesauth switchwith the variable setauth switchprompts interactively, errors when non-interactive, refuses a profile whose secret is goneauth listmatches the file, works offline,--jsonis stable for scriptslogout --profileleaves the active profile alone;logout --allclears everything and needs confirmationapify run --profilesends that profile's token and proxy password to the child- docs regenerated with
pnpm run update-docs
🤖 Generated with Claude Code
Activity
[-]Multi-account UX[/-][+]Stage-4: Multi-account UX[/+][-]Stage-4: Multi-account UX[/-][+]Stage-3: Multi-account UX[/+]feat: auth.json v2 with profiles keyed by user ID (#1434)
feat: make token login additive across accounts (#1458)
feat: add --profile, auth switch, auth list and per-account logout (#…