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

# API key authentication

> Configure the Sentinel to verify Unkey API keys on incoming requests and forward the authenticated identity and metadata to your app.

<Info>
  Unkey Deploy is in public beta. To try it, open the product switcher in the
  top-left of the dashboard and select **Deploy**. During beta, deployed
  resources are free. We're eager for feedback, so let us know what you think
  on [Discord](https://unkey.com/discord), [X](https://x.com/unkeydev), or
  email [support@unkey.com](mailto:support@unkey.com).
</Info>

The API key authentication policy verifies Unkey API keys before requests reach your app. On success, it produces a [Principal](/platform/sentinel/principal/overview) containing the key's identity, metadata, roles, and permissions.

## Configure API key authentication

To enable API key authentication for your deployment:

1. Navigate to your project's **Sentinel Policies** page from the sidebar.
2. Click **Add policy**.
3. Select **Key Auth** as the policy type.
4. Choose one or more keyspaces to verify against.
5. Optionally configure [match conditions](/platform/sentinel/policies/overview#match-expressions), a custom [key location](#key-location), or a [permission query](#permission-query).
6. Select which environments (production, preview, or both) to enable the policy for.
7. Save the policy.

Once configured, the Sentinel verifies every incoming request that matches the policy's conditions against the selected keyspaces. Requests without a valid API key receive a `401` response and never reach your app.

## How verification works

The Sentinel extracts the API key from the `Authorization` header (as a Bearer token) and verifies it against your configured keyspaces. The following checks run in order:

1. **Existence.** The key must belong to one of the configured keyspaces.
2. **Status.** The key must not be disabled or revoked.
3. **Expiration.** The key must not have passed its expiration timestamp.
4. **Credits.** If remaining credits are configured, at least one credit must be available. Verification deducts one credit.
5. **Rate limits.** All rate limit configurations attached to the key are evaluated. See [rate limiting](/platform/sentinel/policies/rate-limiting) for details on response headers and behavior.
6. **Permissions.** If a permission query is configured, the key must satisfy it.

If all checks pass, the Sentinel produces a [Principal](/platform/sentinel/principal/overview) and forwards the request with the `X-Unkey-Principal` header. See the [API key source](/platform/sentinel/principal/sources/api-key) for the full list of fields your app receives, including roles, permissions, and key metadata.

## Key location

By default, the Sentinel extracts the API key from the `Authorization` header as a Bearer token. You can override this by adding a custom key location when creating or editing a policy:

| Location    | Description                                                     | Example                        |
| ----------- | --------------------------------------------------------------- | ------------------------------ |
| Bearer      | Extract from the `Authorization: Bearer <key>` header (default) | `Authorization: Bearer sk_123` |
| Header      | Extract from a custom header, with an optional prefix to strip  | `X-API-Key: sk_123`            |
| Query param | Extract from a URL query parameter                              | `?api_key=sk_123`              |

## Permission query

You can enforce Unkey RBAC permissions directly in the Sentinel by setting a permission query on a policy. If the authenticated key lacks the required permissions, the request receives a `403` response before reaching your app.

Permission queries support `AND` and `OR` operators:

* `api.read AND api.write` requires both permissions
* `api.read OR api.write` requires either permission

## Error responses

| Scenario                          | Status | Description                        |
| --------------------------------- | ------ | ---------------------------------- |
| No credentials provided           | 401    | The request is missing an API key  |
| Invalid, disabled, or expired key | 401    | The API key failed verification    |
| Insufficient permissions          | 403    | The key lacks required permissions |
| Rate limit exceeded               | 429    | The key's rate limit was exceeded  |
