# div login

> Signs this machine in through the browser and saves the API key it is given. RFC 8628's device flow, and nothing more.

```bash
div login
div login --no-browser
```

`div login` prints a code like `QZHR-LVKG` and opens the dashboard at `/cli` with it. Check that the code on the page matches the one in the terminal, then approve. The terminal collects an API key on its next poll and saves it.

```text
Code: QZHR-LVKG
Opened https://divergentlabs.xyz/cli?code=QZHR-LVKG — approve it there if the code matches.
Waiting for the browser…
Signed in to Divergent as founder@divergentlabs.xyz.
The key is "div on MacBook-Pro.local", saved to /Users/you/.config/divergent/config.json. Revoke it under Settings to sign this machine out.
```

## Flags

| Flag | What it does |
| --- | --- |
| `--no-browser` | print the link instead of opening it |
| `--api-url <url>` | sign in to a different control plane, and keep using it |

Over SSH, or with `--no-browser`, it prints the link for you to open wherever your browser is.

## Where the key goes

The key is saved to `~/.config/divergent/config.json` — or under `XDG_CONFIG_HOME`, when that is set. The file is readable only by its owner, and it is written beside itself and renamed over, so a CLI killed halfway leaves the old file rather than half of a new one. Anything else in the file is left alone.

`--api-url` is saved with the key, so a login against a local control plane keeps talking to it. A login against production leaves no URL behind to go stale.

If `DIVERGENT_API_KEY` is set in the shell, it wins over the saved key, and `div login` prints:

```text
DIVERGENT_API_KEY is set in this shell and wins over the saved key; unset it to use this one.
```

## What the key can do

The key is named `div on <hostname>`, belongs to whoever approved it, and carries `runs:read runs:write storage:read storage:write` — enough to place runs, read their logs and move files.

Revoke it under Settings in the dashboard to sign that machine out. A key that needs other scopes is made there by hand.

## How it works

This is [RFC 8628](https://www.rfc-editor.org/rfc/rfc8628)'s device flow. The terminal polls with a device code that never leaves it, and the API stores only that code's digest. The key is minted when the terminal collects it, so no raw token sits in a row waiting. A code lasts ten minutes and works once.

Approving takes a dashboard session, never an API key.
