# CLI authentication and browser login


The Scheduler Zero CLI authenticates API requests with a personal API key. Browser login uses your normal Scheduler Zero sign-in and an explicit consent screen to create a restricted key for the CLI. It does not copy your browser session, expose a WorkOS client secret, or require a localhost callback.

## Browser login and consent

```bash
npx --yes @scheduler-zero/sz@latest auth login
```

The CLI opens a browser when the operating system supports it and always prints the login URL. The flow is:

1. The CLI creates a ten-minute authorization request and retains a private proof locally.
2. The terminal prints a request URL and confirmation code.
3. You open Scheduler Zero and complete normal sign-in if required.
4. You compare the code, select the parent organization, workspaces and permission level, then explicitly approve or cancel.
5. The CLI polls the web app using its private proof. An approved request yields a one-time credential handoff.
6. The CLI validates the key against the API and saves it locally for later commands.

The browser URL is a handoff to the consent page, not a credential. Merely opening it never creates a CLI key. After approval, the browser tells you to return to the terminal; it does not redirect to a localhost port. Do not approve an unexpected request or a code that does not match your terminal.

The browser sign-in can use WorkOS authentication, including its applicable MFA checks. The CLI ultimately uses the resulting restricted personal key, not an OAuth refresh token. This is a device-style polling flow implemented by Scheduler Zero, not a claim that the CLI is a general RFC 8628 OAuth client.

## Choose access deliberately

| Choice | Meaning |
| --- | --- |
| Selected workspaces | Only the selected workspace grants within the chosen organization |
| All current and future workspaces | A grant covering current and newly created workspaces in that organization, where you are allowed to grant it |
| Full | The issuable permissions you hold for the chosen access; this does not bypass your own authority |
| Read-only | The issuable read and read-prefixed permissions, such as `campaign:read`; write permissions are omitted |

The consent screen only offers grants you can issue. All-workspace access has its own authorization requirement and may not be available to every member. Organization and workspace grants are distinct; selecting workspaces does not grant arbitrary organization administration.

The effective authority is **the key's restrictions intersected with the owner's live permissions**. Removing an owner from an organization or removing their access can reduce the key's reach. Keys cannot widen themselves beyond the approved restriction. See [the shared authentication and authorization reference](/authentication).

To restrict the request to one workspace before opening consent:

```bash
bunx @scheduler-zero/sz@latest auth login \
  --workspace 11111111-1111-4111-8111-111111111111
```

Use a real UUID. A login with exactly one selected workspace can save it as the default for later campaign commands; explicit `--workspace` overrides that default. `whoami` remains an identity summary, not a workspace switch command.

## SSH, containers and manual browser opening

```bash
bunx @scheduler-zero/sz@latest auth login --no-browser
```

Open the printed link on your laptop or another device while the terminal remains running. Both devices need access to the web app, and the CLI needs outbound access to the web login endpoint and API. There is no inbound connection to the CLI machine. Browser-opening failures do not remove the printed URL; you can open it manually.

Do not use interactive browser login in unattended CI. Use an environment-provided personal key instead, as described in [CLI scripting and CI](/cli/scripting).

## Personal API-key login

Create a key in **Settings → Personal → API keys**. The current personal-key prefix is `szp_`. Prefer a secret manager or an environment variable:

```bash
export SCHEDULER_ZERO_API_KEY='szp_your_key_here'
npx --yes @scheduler-zero/sz@latest whoami --json
```

An environment key authenticates commands without requiring a saved config. To validate and save the available key, run `auth login`. An explicit `--api-key` also works, but literal secrets in command arguments can appear in shell history or process listings.

Credential precedence is command-line `--api-key`, then `SCHEDULER_ZERO_API_KEY`, then the saved config. A saved key never overrides an explicit environment key. `auth status` calls the API with the effective credential; it does not merely test whether a file is present.

## Local storage and expiration

Browser-created CLI keys expire after 90 days. Logout and package removal do not change that expiry. The CLI saves `config.json` with the credential and, when applicable, a default workspace:

| Platform | Default directory |
| --- | --- |
| macOS | `~/Library/Application Support/scheduler-zero` |
| Linux | `${XDG_CONFIG_HOME:-~/.config}/scheduler-zero` |
| Windows | `%APPDATA%\scheduler-zero`, with a user-profile fallback |
| Any platform | `SCHEDULER_ZERO_CONFIG_DIR` overrides the directory |

The file is written with owner-only permissions on systems enforcing POSIX modes. Windows access also depends on the operating system's file ACLs. Treat the directory as secret-bearing: do not sync it into source control, paste it into support tickets, or upload it as a CI artifact.

## Switch accounts or change access

When a key is already available through configuration or the environment, `auth login` validates and saves it rather than creating a new browser request. To get a fresh consent screen, remove the local credential and unset an environment key first:

```bash
sz auth logout
unset SCHEDULER_ZERO_API_KEY
sz auth login --no-browser
```

`unset` is a POSIX shell example; use your shell's equivalent on Windows. Select the intended account during browser sign-in and review a new grant. Clearing the local file does not revoke the old key: revoke it separately if it should no longer work.

## Logout and revocation

```bash
sz auth logout
```

Logout removes the saved local key and workspace preference. It does not revoke the server-side key or sign out your web browser. An environment-provided key can still authenticate after local logout.

To disable the key wherever it is used, revoke it in **Settings → Personal → API keys**. Then remove any copies from environment variables, CI secrets and local configuration. Commands using the revoked credential should fail. Cancellation before approval ends that request without issuing a new key; expiry or a consumed request requires starting a fresh login.

For errors, see [CLI troubleshooting](/cli/troubleshooting). For exact command options, see [auth login](/cli/commands/auth-login), [auth status](/cli/commands/auth-status) and [auth logout](/cli/commands/auth-logout). Download [this authentication guide as Markdown](/cli/authentication.md) or the [CLI LLM index](/cli/llms.txt) for agents.

