
# Signing in with keenauth login

`keenauth login` signs you in with your dashboard account, so you can manage your environments from a terminal without creating an API key. For CI jobs and scripts, keep using an API key in `KEENAUTH_API_KEY` (see [Command line interface](/docs/cli)).

## Commands

| Command | What it does |
|---|---|
| `keenauth login` | Signs in with the device flow: the CLI prints an address and a code, you open the address on any device, sign in to the dashboard and enter the code. |
| `keenauth login --web` | Signs in in the browser on this computer. The CLI opens the sign-in page and receives the result on `http://127.0.0.1:<port>/callback` (or `http://[::1]:<port>/callback`); the request is protected with PKCE (S256), `state` and the `iss` parameter. |
| `keenauth whoami` | Shows the signed-in user, the organization and the selected environment. |
| `keenauth env use <environment_id>` | Selects the environment that later commands manage. The control plane checks that you have a dashboard role in it. |
| `keenauth env list` | Lists the environments you can work on, from the control plane. The environment selected with `env use` is marked with `*`. |
| `keenauth logout` | Revokes the session on the server and removes it from this computer. |

```sh
keenauth login
keenauth env use env_01j9z3c0000000000000000000
keenauth users list
```

When `KEENAUTH_API_KEY` is set, it always wins; the stored session is used only when no API key is set.

## Listing environments

`keenauth env list` asks the control plane for the environments of the account you signed in to and in which you have a dashboard role (`GET /v1/environments`, see [List your environments for the CLI](/docs/api/control/environments/list)). It needs a session; without one it asks you to run `keenauth login`.

| Flag | Description |
|---|---|
| `--limit` | Page size, 1 to 100 (default 20). |
| `--after` | The cursor printed by the previous page (`more results: --after <cursor>`). |
| `--all` | Follows the pages and lists every environment. |
| `-o table\|json\|yaml` | Output format; the table marks the selected environment with `*`, and in JSON and YAML each row has `current: true` for it. |

An invalid or foreign `--after` cursor is refused (`invalid_cursor`); run the command again without it.

## How the session works

- Sign-in issues a short-lived access token (5 minutes) and a refresh token (12 hours). Both are bound to a DPoP key (RFC 9449) created on this computer, so a copied token cannot be used from another machine. The refresh token rotates on every use.
- For each command the CLI asks the control plane for a management token of the selected environment. This token lives 10 minutes, is bound to the same DPoP key and is kept **only in memory**; it is never written to disk.
- Requests to your environment carry the management token, a fresh DPoP proof and your dashboard identity. Your environment checks that you still have a role, so removing your dashboard role ends your CLI access within minutes.

## Where the session is stored

| What | Where |
|---|---|
| Issuer, user ID, organization, DPoP key thumbprint, selected environments | `config.json` in `KEENAUTH_CONFIG_DIR`, or in `keenauth` under your user configuration directory (mode 0600) |
| Refresh token and DPoP private key | The OS keychain: macOS Keychain (`security`) or the Secret Service on Linux (`secret-tool`) |

The secrets are passed to the keychain tool on standard input, never as command arguments. If no keychain is available (for example on Windows, or on a Linux server without a Secret Service), `keenauth login` stops with an error. You can then pass `--insecure-storage` to store the refresh token and the DPoP private key unencrypted in `credentials.json` (mode 0600) next to `config.json`. The CLI prints a warning: anyone who can read that file can act as you until the session expires. Prefer an API key on shared machines.

## Settings

| Variable | Default | Description |
|---|---|---|
| `KEENAUTH_LOGIN_ISSUER` | `https://login.keenauth.com` | The sign-in server. Must be an `https` address. |
| `KEENAUTH_CONTROL_URL` | `https://api.keenauth.com/v1` | The control plane that issues management tokens. Must be an `https` address. |
| `KEENAUTH_CONFIG_DIR` | your user configuration directory + `keenauth` | Where `config.json` (and with `--insecure-storage`, `credentials.json`) is kept. |

## Errors

| Message | What to do |
|---|---|
| `you are not signed in` / `your session has expired or was revoked` | Run `keenauth login` again. Exit code 3. |
| `no environment is selected` | Run `keenauth env use <environment_id>`. |
| `environment … does not exist or you have no dashboard role in it` | Check the ID in the dashboard or ask an owner for a role. |
| `no OS keychain is available` | Install a keychain, use `--insecure-storage`, or use an API key. |
