# Authentication

The CLI authenticates against the **Frontline Public API** with a Bearer API key. The same key is reused by both `frontline` and `max` binaries.

## Key types

Frontline issues two kinds of API key. Match the key type to what you need to do:

| Type | Scope | Use for |
|  --- | --- | --- |
| `GENERAL` | Account-level. No user identity. | Read-only sync, dashboards, machine-to-machine integrations. |
| `USER` | Bound to a user inside the account. | Anything that mutates state: creating agents, updating settings, building flows, creating tools, etc. The CLI is most useful with a `USER` key. |


If a write command returns `401 Unauthorized`, you most likely logged in with a `GENERAL` key on an endpoint that requires `USER`. See the API [Authentication](/docs/authentication) page for the full breakdown.

## Generate a key

Both kinds of API key are created from inside the Frontline app, but they live in different places. Open the app, click your **user name in the bottom-left of the sidebar**, and choose **Settings** — from there, the flow splits by key type.

### Personal API key (`USER`) — recommended for CLI use

The CLI is most useful with a `USER` key (it carries identity, so writes are attributed to you).

1. In the settings sidebar, under **My settings**, open **Bring your own Agent**.
2. Click **Create personal API key**, name it (per integration / IDE is a sensible split), and confirm.
3. **Copy the key immediately.** Frontline only stores its SHA-256 hash, so it cannot be displayed again.


Each user can hold up to **5 personal keys** at a time; the same screen shows the current count (e.g. `1/5 personal keys used`) and a delete button to free a slot.

### Account API key (`GENERAL`)

Use this only for read-only integrations that don't need to be attributed to a specific user.

1. In the settings sidebar, under **Account settings**, open **Developer**.
2. Click **Create API key**, name it, and confirm.
3. **Copy the key immediately** — same one-time-display rule as above.


`GENERAL` keys do **not** work on endpoints that require `USER` scope (`401 Unauthorized`). See the API [Authentication](/docs/authentication) page for the full breakdown.

## Log in

```bash
frontline auth login <api-key>
```

This persists the key in the CLI's config store (per-OS standard location: `~/.config/@getfrontline/cli/Config` on Linux, `~/Library/Preferences/...` on macOS, `%APPDATA%` on Windows).

The same key is also used by `max`:

```bash
max auth whoami
```

## Verify

```bash
frontline auth whoami
```

Hits `GET /public/v1/me` and prints the account (and user, for `USER` keys) the key represents.

## Rotate or revoke

There is no "rotate in place" command — keys are immutable. To rotate:

1. Create a new key in the dashboard.
2. `frontline auth login <new-key>` (overwrites the active profile).
3. Delete the old key in the dashboard.


To remove a key from the CLI store without touching the dashboard:

```bash
frontline auth logout                    # remove active profile
frontline auth logout --profile staging  # remove a named profile
```

## Per-call override

For scripts and CI where you don't want to persist a key, pass it inline:

```bash
frontline agents list --api-key flk_xxxx
```

`--api-key` takes precedence over the active profile for that single call.

## Multiple environments

Use profiles to keep `prod`, `staging`, and personal-dev keys side-by-side:

```bash
frontline auth login flk_prod_xxxx
frontline auth profiles list      # see what's stored
frontline auth profiles use prod  # switch active

# Or override per-call:
frontline agents list --profile staging
```

## Security notes

- Treat API keys like passwords. Never check them into git or paste them into chat.
- Prefer one key per integration / environment so revocation has minimal blast radius.
- In CI, inject keys via secrets stores (GitHub Actions secrets, Vault, etc.). Use `--api-key` flag rather than `frontline auth login` so nothing is persisted on the runner.
- All transport is HTTPS; the API rejects plain HTTP.


## Read next

- **[API → Authentication](/docs/authentication)** — same key types from the REST API's perspective (which endpoints need which scope).
- **[Errors](/docs/errors)** — full error envelope, including the `401 unauthorized` and `cli_outdated` cases you'll hit during auth troubleshooting.
- For UI questions (where a setting lives, how to invite teammates, billing in-app): [https://help.getfrontline.ai](https://help.getfrontline.ai).