# Log in and authenticate

> Log in with your password and 2FA, grant write scopes, import tokens, and use the CLI on headless systems and in CI.

Source: https://managerunners.com/docs/cli/authentication/

The CLI authenticates with a [personal access token](https://managerunners.com/docs/manual/access-tokens/) (PAT). It never stores your password or your 2FA secret.

## The API address

The CLI stores API addresses in named *profiles*. The `default` profile, used when you don't pass `--profile`, points at `https://api.managerunners.com`, so there is nothing to configure. Other profiles get their address from `config set-api`, which accepts only HTTPS addresses. See [Profiles and organizations](https://managerunners.com/docs/cli/profiles-and-organizations/) for more than one profile.

## Log in interactively

```sh
manage-runners setup
```

`setup` logs in to the active profile. It asks for your username (your email address), your password and a 2FA code from your authenticator app. It then creates a PAT named `manage-runners-cli`, valid for 30 days, and stores it in your system's credential store: the Secret Service keyring on Linux, Keychain on macOS, Credential Manager on Windows.

`auth login` does the same for a profile you name, and can add scopes:

```sh
manage-runners auth login --profile default
```

### Scopes

By default the CLI's token can only read. It gets the scopes `profile:read`, `runners:read`, `schedules:read`, `products:read`, `providers:ssh-keys:read` and `subscriptions:read`.

To change runners or schedules, log in again and request the scopes you need, repeating `--scope`:

```sh
manage-runners auth login --profile default --scope runners:write --scope schedules:write
```

| Scope | Needed for |
| --- | --- |
| `runners:write` | `runner create`, `update`, `pause`, `resume`, `duplicate` (`update` and `--wait` also need `runners:read`) |
| `runners:delete` | `runner delete` |
| `runners:forget` | `runner forget` |
| `schedules:write` | `schedule set`, `enable`, `disable`, `delete` |

Logging in interactively again replaces the profile's previous token and tries to revoke the old one. If the revocation cannot be confirmed, the login still succeeds with the warning `PREVIOUS_PAT_REVOCATION_UNCONFIRMED`; revoke the old token in the dashboard. Your role in the organization still applies: a viewer cannot change runners, whatever the token's scopes.

### Check and end a session

```sh
manage-runners auth status --profile default
manage-runners auth logout --profile default --revoke
```

`auth status` shows who you are logged in as, the token's scopes and expiry, and where the token comes from. It never prints the token. `auth logout` removes the stored token; with `--revoke` it also revokes the token in Manage Runners first. You can also revoke it in the dashboard under **Settings** > **Personal access tokens**.

When the 30 days are over, log in again.

## Use a token you created in the dashboard

You can create a PAT in the dashboard with exactly the scopes and expiry you want, and give it to the CLI.

**Store it** in the credential store. Pipe it in, so it does not appear in your shell history or the process list:

```sh
your-secret-manager read manage-runners-pat | manage-runners auth login --profile default --token-stdin
```

`--token-env NAME` reads it from the environment variable `NAME` instead. An imported token keeps the scopes it was created with; `--scope` cannot be combined with an import.

**Or use it without storing it**, for example in CI. If `MANAGE_RUNNERS_TOKEN` is set, commands use it for that invocation:

```sh
export MANAGE_RUNNERS_TOKEN   # set by your CI or secret manager
manage-runners runner list
```

The global `--token-env NAME` uses another variable for one invocation and takes precedence over `MANAGE_RUNNERS_TOKEN`, which takes precedence over the credential store:

```sh
manage-runners --token-env CI_MANAGE_RUNNERS_PAT runner list
```

Never pass a token as a command-line argument.

## Headless systems without a keyring

SSH sessions, containers and servers often have no unlocked keyring. You have two options:

- **Environment token:** use `MANAGE_RUNNERS_TOKEN` or `--token-env` as shown above.
- **File credential store:** pass `--credential-store file` or set `MANAGE_RUNNERS_CREDENTIAL_STORE=file`. The CLI then keeps the token in `manage-runners/credentials.json` in your user configuration directory, readable only by you (mode 0600). It refuses to use the file if others can read it or if it is a symbolic link. The file store is available on Linux and macOS.

```sh
export MANAGE_RUNNERS_CREDENTIAL_STORE=file
manage-runners auth login --profile default
```

The CLI never falls back to the file store on its own.

## Diagnose problems

```sh
manage-runners doctor
```

`doctor` checks the configuration, the credential store, the stored token, its expiry and scopes, and whether the API is reachable. It changes nothing.
