> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aethis.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication & API keys

> When you need a key, what a key can do, and how to diagnose a 403 before you hit one.

Aethis uses a single API key per identity. What the key can *do* is governed by its
**scopes** — not by your account role. This page is the one place that explains the
scope model, so a permission error is a lookup, not a surprise.

## Do you even need a key?

No — not for evaluation. Public rulesets are discoverable, inspectable, and decidable
anonymously:

```bash theme={null}
aethis rulesets list --public
aethis decide -b aethis/uk-fsm/child-eligibility \
  -i '{"child.age": 10, "child.school_type": "state_funded"}'
```

You need a key for **tenant projects, private rulesets, composed rulebooks, and all
authoring commands** (`generate`, `publish`, `rulebooks create`, …).

## Sign in

`aethis login` runs a browser sign-in and caches a key locally. This is the whole of
first-time setup:

```bash theme={null}
aethis login
```

`aethis init` runs the same flow for you the first time, so if you're scaffolding a
project you don't need a separate `login` step.

<Note>
  **No browser?** For CI or a headless box, mint a key on a machine that *does* have a
  browser (`aethis account generate`, below), then set `AETHIS_API_KEY` on the headless
  host. `aethis login` needs a browser to complete the OAuth round-trip.
</Note>

## What `login` mints — and the scopes model

A key from `aethis login` (and from `aethis account generate` with **no** `--scope`)
carries exactly these six scopes:

| Scope              | Grants                                      |
| ------------------ | ------------------------------------------- |
| `decide`           | Evaluate rulesets and rulebooks             |
| `projects:read`    | List and show your authoring projects       |
| `projects:write`   | Create, generate into, and archive projects |
| `rulesets:read`    | List and show your tenant rulesets          |
| `rulesets:explain` | Human-readable rule explanations            |
| `rulesets:write`   | Author, test, and publish rulesets          |

That covers project + ruleset authoring end-to-end. It does **not** include
`rulebooks:read` / `rulebooks:write` — see the trap below.

## `whoami` — check before you hit a 403

`aethis whoami` prints the identity, tier, scopes, and — the useful part — whether
authoring is available on this key:

```bash theme={null}
aethis whoami
```

```
Key:         key_3a1b2c…
Tenant:      tenant_9f8e…
Tier:        internal
Scopes:      decide, projects:read, projects:write, rulesets:explain, rulesets:read, rulesets:write
✓ Authoring enabled — you can create and publish rulesets.
```

Run this first whenever a command returns `403 denied_missing_permission` — it tells you
which scopes you're actually carrying.

## The rulebook trap (and the fix)

Because a login key omits `rulebooks:*`, the **first** `aethis rulebooks create` or
`aethis rulebooks activate` on a fresh key fails:

```
403 denied_missing_permission — key is missing scope 'rulebooks:write'
```

This is not an account-level block — it's a missing scope. Mint a rulebook-capable key
with the **full** scope list. `--scope`/`-s` *replaces* the default set, so you must list
every scope you want, not just the new one:

```bash theme={null}
aethis account generate --name rulebook-authoring \
  -s decide -s projects:read -s projects:write \
  -s rulesets:read -s rulesets:explain -s rulesets:write \
  -s rulebooks:read -s rulebooks:write
```

Then `aethis whoami` should show all eight scopes, and rulebook authoring works.

## Rotating and adding keys

`aethis account generate` mints an **additional** key — for rotation, a second machine,
or a narrower scope set. It does not revoke your existing key.

```bash theme={null}
# A second key for a build box, decision-only, named so you can find it later:
aethis account generate --name ci-decide -s decide

# List keys (masked) and revoke one:
aethis account keys
aethis account revoke <key_id>
```

| Flag             | Meaning                                                     |
| ---------------- | ----------------------------------------------------------- |
| `--name` / `-n`  | Human label for the key (default `cli-generated`)           |
| `--scope` / `-s` | A scope to grant, repeatable. **Replaces** the default set. |
| `--tier` / `-t`  | Rate-limit tier: `free` (default), `starter`, `pro`         |
| `--no-save`      | Print the key but don't cache it locally                    |

## Multiple identities: profiles

If you switch between personas (e.g. an admin key and a dev key), store each as a named
profile rather than swapping env vars:

```bash theme={null}
aethis profile add dev --api-key <key>          # or omit to prompt
aethis profile use dev                            # sticky default
aethis --profile admin whoami                     # one-off override
aethis profile list                               # see all + which is active
```

Pass `--profile anonymous` to force unsigned mode for a single command.

## Where a key is read from (precedence)

For any command, the key is resolved in this order — first hit wins:

1. `--api-key <key>` on the command line
2. `AETHIS_API_KEY` in the environment
3. The active profile / cached credentials (keychain)

`--base-url` (or `AETHIS_BASE_URL`) selects the server the key is used against; it
defaults to the active profile's `base_url`, or `https://api.aethis.ai`.

## CI and background jobs (non-interactive)

Automation must never hang on a prompt. Two ambient switches make every command
non-interactive:

| Variable                | Effect                                                                                                                                                                            |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AETHIS_NONINTERACTIVE` | Truthy (`1`/`true`/`yes`) bypasses every confirmation prompt; destructive commands proceed instead of hanging on `[y/N]`. Prints a one-line notice so it's never silently active. |
| `CI`                    | Same effect when truthy.                                                                                                                                                          |

Combine with `--no-prompt` to *fail fast* rather than fall back to a browser sign-in when
no key is cached:

```bash theme={null}
AETHIS_API_KEY=$KEY aethis --no-prompt decide -b aethis/uk-fsm/child-eligibility -i '{...}'
```

## See also

* [CLI reference](/interfaces/cli) — every command, grouped.
* [Errors](/reference/errors) — `denied_missing_permission` and other failure shapes.
* [REST API](/interfaces/rest-api) — passing the key as `X-API-Key` over HTTP.
