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

# API keys

> Create, scope, rotate, and revoke API keys for programmatic access to ORCA. Keys are admin-managed, org-scoped, and limited to 10 active keys per organisation.

## Overview

API keys are how you authenticate non-interactive integrations with ORCA — CI pipelines, scheduled jobs, the [CLI](/cli), the [dbt integration](/dbt-integration), and any custom code calling the [public API](/api-reference/public-api).

Keys are managed through the **Settings → API keys** page (admin only) or via the management endpoints. Each key belongs to one organisation, has a fixed scope, and can be revoked at any time without affecting other keys.

This page covers key lifecycle. For how to *use* a key once you have one, see [API reference](/api-reference/overview).

## Key scopes

Every API key is created with one of four scopes. Scope is set at creation and cannot be changed afterward (revoke and recreate if you need to upgrade).

| Scope                  | Permissions                                                      | Typical use                                        |
| ---------------------- | ---------------------------------------------------------------- | -------------------------------------------------- |
| **`read`** *(default)* | Read jobs, files, results, scores, contracts                     | Dashboards, reporting integrations, SIEM ingestion |
| **`scan`**             | Read + trigger scans on existing sources                         | Scheduled re-scans, CI quality gates               |
| **`write`**            | Read + scan + create jobs, upload files, edit contracts          | Data pipelines that ingest new files               |
| **`admin`**            | Everything write can do + manage other keys, users, org settings | Bootstrapping scripts, infrastructure-as-code      |

The principle is least privilege: pick the smallest scope that works for the integration. Most production integrations are `read` or `scan`. `admin` keys should be rare and rotated frequently.

## Creating a key

In **Settings → API keys**, click **Create key**. You'll be asked for:

* **Name** — a human label so you remember what the key is for (e.g. "Airflow prod", "CI quality gate")
* **Scope** — one of the four above
* **Expires at** *(optional)* — set an absolute expiration date for time-limited keys

ORCA returns the raw key **once and only once**. Copy it immediately and store it in your secret manager. After you close the dialog, the raw key is gone — only the key prefix (the first few characters, used for identification in logs) remains visible.

There's a hard limit of **10 active keys per organisation**. Revoke unused keys to make room.

### Via the API

```bash theme={null}
POST /api/v1/api-keys
Authorization: Bearer <admin JWT>
Content-Type: application/json

{
  "name": "Airflow prod ingestion",
  "scope": "write",
  "expires_at": "2027-04-07T00:00:00Z"
}
```

Response (the only time the raw `key` is returned):

```json theme={null}
{
  "data": {
    "id": "8fa1...",
    "name": "Airflow prod ingestion",
    "scope": "write",
    "key": "ok_live_3f8a9d2e_a1b2c3d4e5f6...",
    "created_at": "2026-04-07T09:14:22Z"
  }
}
```

The first segment (`ok_live_3f8a9d2e`) is the **key prefix** — it's safe to log, embed in dashboards, or store alongside the key id for identification.

## Listing keys

```bash theme={null}
GET /api/v1/api-keys
```

Returns every key for the org with name, scope, prefix, last-used timestamp, created-at, and active flag. The full key value is never returned by this endpoint — only by the create endpoint, only once.

The `last_used_at` column is the easiest way to find dead keys to revoke.

## Updating a key

You can change the **name** of a key after creation, but not its scope. To change scope, revoke and create a new key.

```bash theme={null}
PATCH /api/v1/api-keys/{key_id}
{
  "name": "Airflow prod (renamed)"
}
```

## Revoking a key

```bash theme={null}
DELETE /api/v1/api-keys/{key_id}
```

Revocation is immediate — any in-flight request authenticated with the revoked key will continue to its current response, but the next request will fail with `401 Unauthorized`. Revoked keys are kept in the database (for the audit trail) but marked `is_active = false`.

In the UI: click the **Revoke** button on the key row and confirm.

## Authentication

To use a key in a request, send it in the `Authorization` header with the `Bearer` prefix:

```bash theme={null}
curl https://app.orca-klavest.app/api/v1/jobs \
  -H "Authorization: Bearer ok_live_3f8a9d2e_a1b2c3d4e5f6..."
```

The same header format works for both API keys and JWT access tokens — ORCA detects which is which from the prefix.

## Rotation

API keys never auto-rotate. Best practice for production integrations:

<Steps>
  <Step title="Create the new key">
    Create a new key with the same scope and a name that includes a date or version (e.g. "Airflow prod 2026-04").
  </Step>

  <Step title="Deploy alongside the old key">
    Update your secret manager with both keys. Verify the new key works against a non-critical endpoint.
  </Step>

  <Step title="Cut over">
    Switch the integration to the new key. Watch the [audit log](/audit-logs) for `api_key_used` events to confirm traffic moved.
  </Step>

  <Step title="Revoke the old key">
    After 24 hours of clean traffic on the new key, revoke the old one.
  </Step>
</Steps>

Set rotation calendar reminders — quarterly is a reasonable default for `write`/`admin` scopes.

## Audit and observability

Every key action creates an [audit log](/audit-logs) entry:

* `api_key_created` — when a key is issued, with name + scope + key id in metadata
* `api_key_revoked` — when a key is revoked
* `api_key_used` — on each authenticated API request, with the key prefix in metadata

The `api_key_used` events let you reconstruct exactly what an integration did from a security review perspective.

## Limits

* **10 active keys per organisation.** Revoke unused keys to free slots.
* **Admin role required** to create, list, update, or revoke keys.
* **No raw key recovery.** If you lose a key, you must revoke and create a new one. ORCA stores only a hash, not the raw value.

## Tips

* **Name keys after their consumer.** "Airflow prod" beats "key 3" by a mile when you're trying to revoke the right one in an incident.
* **Use expiration dates for time-bound work.** Contractor needs API access for two weeks? Create a key with `expires_at` set to two weeks out and forget about it.
* **Don't share keys between integrations.** One integration per key makes blast-radius small if one leaks.
* **Monitor `last_used_at`.** Anything not used in 60 days is a candidate for revocation.

## What's next?

* [API reference overview](/api-reference/overview) — how to call ORCA endpoints once you have a key
* [Public API](/api-reference/public-api) — the customer-facing endpoint surface
* [Audit logs](/audit-logs) — see what your keys are doing
