> ## 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.

<Note>
  **Keys exist for the authoring tier, which is invite-only.** Evaluating
  published public rulesets needs no key and no signup — start with
  [your first decision](/getting-started/first-decision). To author and publish
  your own rules, [request access](https://aethis.ai/developer-access). The
  boundary between the two tiers, and what a `401` or `403` is telling you:
  [Capabilities and access](/reference/capabilities).
</Note>

## 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, **including rulebooks**: the
engine treats `rulesets:read` as satisfying `rulebooks:read`, and `rulesets:write` as
satisfying `rulebooks:write`. A login key can create, activate and archive rulebooks
today. See [the scope aliases](#scope-aliases-and-why-you-should-still-mint-the-full-set)
for why you should not rely on that forever.

## `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.

## Scope aliases, and why you should still mint the full set

`rulebooks:read` and `rulebooks:write` were added after many keys had already been
minted. Rather than rewrite those keys, the engine carries **transition aliases**: a key
holding the legacy scope implicitly satisfies the newer one.

| Canonical scope | Also satisfied by |
| - | - |
| `rulebooks:read` | `rulesets:read` |
| `rulebooks:write` | `rulesets:write` |
| `projects:read` | `projects:write` |

The direction is one-way by design: the legacy scope implies the new one, **never** the
reverse. A key minted with `rulebooks:write` alone gains no authority over rulesets.

So a login key authors rulebooks today, and `aethis rulebooks create` / `activate` will
not return `403 denied_missing_permission`. But each alias is a **tombstone**, to be
removed once every key carries the canonical scope natively — at which point a key
without `rulebooks:*` stops working against rulebook endpoints, with no warning beyond
this page. If you are minting a key you intend to keep, list the scopes explicitly.
`--scope`/`-s` *replaces* the default set, so name every scope you want:

```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
```

`aethis whoami` should then show all eight scopes.

## 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 '{...}'
```

## Model-provider credentials

Aethis authentication and model-provider authentication are separate.
Generation requires an Aethis API key with authoring scopes plus your own
key for the selected model provider.

| Generation model | REST header | CLI environment variable |
| - | - | - |
| `claude-sonnet-5` (default) | `X-Anthropic-Key` | `ANTHROPIC_API_KEY` |
| `deepseek-flash` | `X-DeepSeek-Key` | `DEEPSEEK_API_KEY` |

Select the model per request with the API's `model` field or, with
aethis-cli 0.41.0 or later, per CLI invocation with `generate --model` /
`refine --model`. The CLI reads a custom DeepSeek variable name from
`deepseek_key_env` in `aethis.yaml` when configured.

Only the selected provider's key is sent by the CLI for generation. External
callers must supply that provider's key; a missing key does not use a platform
credential. Provider keys are used for the request and are not stored. Keep
them in your server environment and supply them in headers, never in request
JSON or browser code. Field discovery and other Anthropic-backed authoring
operations still require `X-Anthropic-Key`.

## 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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.