> ## Documentation Index
> Fetch the complete documentation index at: https://docs.runcomfy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

The CLI supports two authentication paths: an interactive **device-code OAuth flow** for humans, and a **token env var** for CI / containers.

Both produce the same kind of token: a row in the `user_tokens` table tied to your RunComfy account, sent as `Authorization: Bearer <token>` to the [Model API](/model-apis/quickstart) and other RunComfy services.

***

## Device-code flow (`runcomfy login`)

The everyday path for human users. Standard [OAuth 2.0 device authorization grant](https://datatracker.ietf.org/doc/html/rfc8628) — same shape as `gh auth login` or `stripe login`.

```bash theme={null}
runcomfy login
```

The CLI:

1. Calls `POST https://www.runcomfy.com/api/cli-auth/start` and receives a short `user_code` (e.g. `ABCD-1234`).
2. Prints the code prominently in your terminal.
3. Opens `https://www.runcomfy.com/cli-auth` in your browser.
4. Polls `POST .../cli-auth/poll` every two seconds.

In the browser:

1. Sign in (magic link or any other configured provider).
2. **Type or paste the code from the terminal** into the form. The page deliberately doesn't accept a `?code=…` query string, so a stranger can't send you a pre-filled link to phish your token.
3. Click **Authorize**.

The CLI saves the resulting token to `~/.config/runcomfy/token.json` (Unix `mode 0600`).

```bash theme={null}
runcomfy whoami     # confirms it worked
runcomfy logout     # remove the local token
```

Tokens are minted fresh on every `runcomfy login` (`token_type='cli'` in `user_tokens`) and can be revoked independently of any other API tokens you have on your Profile page.

***

## CI / container env var (`RUNCOMFY_TOKEN`)

In a non-interactive environment, set `RUNCOMFY_TOKEN` to bypass the device-code flow entirely:

```bash theme={null}
export RUNCOMFY_TOKEN=<your-api-token>
runcomfy whoami
runcomfy run openai/gpt-image-2/text-to-image --input '{"prompt": "..."}'
```

The env var **takes precedence** over `~/.config/runcomfy/token.json`. Get the token from your [Profile](https://www.runcomfy.com/profile) page (the "API Token" section) — that token is interchangeable with one minted by `runcomfy login`, just with a different `token_type`.

For GitHub Actions:

```yaml theme={null}
- run: runcomfy run ${{ inputs.model_id }} --input '${{ inputs.body }}'
  env:
    RUNCOMFY_TOKEN: ${{ secrets.RUNCOMFY_TOKEN }}
```

***

## Where the token lives

| Source                   | Location                                                                  | When used                               |
| ------------------------ | ------------------------------------------------------------------------- | --------------------------------------- |
| `RUNCOMFY_TOKEN` env var | n/a                                                                       | Always wins if set                      |
| `runcomfy login`         | `$XDG_CONFIG_HOME/runcomfy/token.json` or `~/.config/runcomfy/token.json` | Default location on Linux/macOS/Windows |
| Override                 | `RUNCOMFY_CONFIG_DIR=<path>`                                              | Useful for tests / sandboxes            |
| Legacy macOS             | `~/Library/Application Support/runcomfy/token.json`                       | Read-only fallback for older builds     |

The file is `mode 0600` (only your user can read), and `runcomfy login` writes it atomically (temp file + `rename(2)`) so a crash mid-write can't corrupt it.

***

## Revoking a token

* **Local logout**: `runcomfy logout` removes the token file. The token is still valid server-side until you also revoke it.
* **Server-side revoke**: rotate or delete the row from your [Profile](https://www.runcomfy.com/profile) page.

***

## Security notes

* The token is **plaintext** in `user_tokens.token` server-side. (Token-at-rest hashing is on the roadmap but does not change CLI behavior.)
* Don't commit `token.json` or echo `$RUNCOMFY_TOKEN` in CI logs.
* The CLI never logs the token: `runcomfy -v ...` and `RUST_LOG=reqwest=trace ...` redact the `Authorization` header.
* If you suspect a token leak: rotate immediately on the Profile page, then `runcomfy logout && runcomfy login`.
