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

# Authentication

> Create a workspace API key and choose the right header.

The Riftmap API uses **workspace API keys** for all programmatic access. Keys are scoped to a single workspace, bypass role checks (they're owner‑equivalent within their workspace), and never require a `workspace_id` parameter.

## Create a key

In the app:

1. Pick the workspace from the user menu.
2. Navigate to **Settings → API keys**.
3. Click **Create new key**, give it a label (e.g. `claude-code-laptop`, `ci-staging`), and copy the raw key.

The plaintext key is shown **once** at creation time. After that, only the SHA‑256 hash and a short prefix (`rfm_live_xxxx…`) are stored. If you lose it, revoke the old key and mint a new one.

A workspace can have multiple keys — best practice is one per environment or per agent, so revocation is granular.

## Header conventions

Riftmap accepts the API key on either of two headers. Use whichever is more natural for your client.

### Canonical: `X-API-Key`

```bash theme={null}
curl "https://api.riftmap.dev/api/v1/repositories/lookup?url=https://github.com/myorg/repo" \
  -H "X-API-Key: rfm_live_xxx"
```

### Convenience alias: `Authorization: Bearer`

The `Authorization` header is checked **only** when the value starts with `rfm_` — this avoids collision with user JWTs that share the same header in browser sessions.

```bash theme={null}
curl "https://api.riftmap.dev/api/v1/repositories/lookup?url=https://github.com/myorg/repo" \
  -H "Authorization: Bearer rfm_live_xxx"
```

### Priority order

Within a single request the server checks, in order: `X-API-Key` → `Authorization: Bearer rfm_*` → session cookie → 401. Mixing two methods is fine; the first to match wins.

### 401 body

```json theme={null}
{
  "detail": "Authentication required. Provide X-API-Key, Authorization: Bearer <key>, or log in."
}
```

## Cross‑workspace isolation

Every authenticated response is scoped to the workspace that owns the API key. Attempts to reach another workspace's resources return **404**, not 403 — we deliberately don't leak whether the resource exists.

## Rate limits

| Surface                                                       | Limit                               | Notes                                                                                                    |
| ------------------------------------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Read endpoints                                                | Generous (no per-request cap today) | `GET /repositories`, `GET /context`, `GET /impact`, `GET /graph`, etc. Subject to change as usage grows. |
| Authenticated mutations (`POST` / `PUT` / `PATCH` / `DELETE`) | 60 / minute per key                 | Keyed by API key prefix. Configurable via `RATELIMIT_AUTHENTICATED_MUTATIONS`.                           |

On limit exceeded, the response is `429` with `{ "detail": "...", "retry_after": N }` and a `Retry-After: N` header. Both `Retry-After` and `X-Request-ID` are exposed via CORS, so browser `fetch()` can read them directly.

## Revoking a key

`DELETE /workspaces/{id}/api-keys/{key_id}` — or click the trash icon in **Settings → API keys**. Revocation is immediate; subsequent requests with the revoked key return 401.

## Storing keys safely

* Do **not** check API keys into git. Treat them like any other production secret.
* Do **not** ship them in client‑side bundles — workspace keys are owner‑equivalent within their workspace and must stay server‑side.
* For local development against the production API, use a `.env.local` file (or your shell's secret manager) and reference the key as `RIFTMAP_API_KEY`.
