`roar` supports two paths to authenticate with GLaaS. Pick one based on your
environment:

| Path | When |
|---|---|
| **`roar login`** | Interactive — your machine has a browser. One command, one device-code prompt, done. |
| **`roar auth`** | Headless / CI / no-browser — pair a GitHub SSH key with your GLaaS account manually. |

Both write local state that subsequent `roar` commands use, and both surface the
same identity to `roar register`, `roar put`, and GLaaS itself.

## `roar login` — browser / device flow

```bash
roar login
```

Opens a device-code approval flow in your browser: sign in with GitHub, approve
the device, done. The resulting auth state is written to
`~/.config/roar/auth.json` and shared across every `roar` workspace on the
machine — you don't repeat this per project.

Useful options:

- `--force` — replace an existing session without prompting (handy when switching accounts).
- `--token-file <path>` — import a previously exported auth state JSON (e.g., to copy a session to another machine).
- `--glaas-api-url <url>` — point at a non-default GLaaS instance (rare).

Verify the result:

```bash
roar whoami
```

…which prints the identity, GitHub provider, TReqs user id, the auth-store
path, and the token expiry.

## `roar auth` — manual SSH-key setup

For environments where the device flow doesn't fit — headless servers, CI
jobs, anywhere you can't open a browser — pair a GitHub SSH key with your
GLaaS account once, then use it from there:

```bash
roar auth key            # print the public key roar will present
# (sign in at https://glaas.ai → SSH keys → paste the key)
roar auth test           # verify the pairing works
roar auth status         # show current auth status
```

The same SSH key on multiple machines lets all of them authenticate against
GLaaS as you. No browser involved on the machines that use it; the pairing
itself just needs a one-time visit to glaas.ai to register the key.

## After authentication

Logging in (either path) does one more thing besides storing identity: if
your workspace is still at the init default `anonymous` scope, it auto-flips
to `private`. From that point your `roar register` / `roar put` publishes are
access-controlled rather than public-by-default. Override per-workspace with
`roar scope use <…>`. See [Scopes](/docs/scopes) for the full visibility
model.

To clear state:

```bash
roar logout              # clears the global ~/.config/roar/auth.json
```

`roar logout` removes the local auth store written by `roar login`. To revoke
SSH-key auth, remove the key from your GLaaS account at glaas.ai (the
on-disk key is yours; GLaaS just stops accepting it).

## See also

- [Scopes](/docs/scopes) — how authentication interacts with workspace visibility (`anonymous` / `private` / `public` / project).
- [Troubleshooting](/docs/troubleshooting) — the "Registration / scope / auth" section covers `Stored auth state at <path> is not valid JSON`, scope-binding errors, and related failures.
- [roar Guide](/docs/roar-guide) — the wider CLI surface for `register`, `put`, `whoami`, and the other commands that consume auth state.
