---
icon: material/key-outline
title: "API Keys"
description: "The account API key for the MCP and REST control surface, and how to rotate it"
---

An API key authenticates the **control surface**: the [MCP server](../apps/mcp/)
and the [REST API](../api/manage.md), sent as the `X-10X-Auth` header. It is
distinct from the [license token](license.md) the engine verifies to run.

One key belongs to the account, not to an environment. It reaches every
[environment](environments.md) the account can see, and the header decides which
one a call targets: `X-10X-Auth: <API_KEY>` uses the default environment,
`X-10X-Auth: <API_KEY>/<ENV_ID>` names one. Permission level (`OWNER`, `WRITE`,
`READ`) is resolved per environment, so one key can own one and only read
another.

## Lifecycle

| Step | What happens |
|------|--------------|
| **Sign in** | Authenticate through the Auth0 device flow via [MCP sign-in](../apps/mcp/tools/account/signin.md). |
| **Generate** | A key is issued for the environment and stored on the account. Treat it as a secret. |
| **Use** | Pass it to the MCP host and to REST calls in the `X-10X-Auth: <API_KEY>/<ENV_ID>` header. |
| **Rotate** | Replace it on demand. The previous key is invalidated immediately, everywhere. |

## Rotating

Two equivalent paths:

- **MCP.** `log10x_rotate_api_key` mints a new key, writes it to
  `~/.log10x/credentials`, and the running MCP server picks it up without a
  restart. Confirm explicitly; rotation is destructive.
- **REST.** `POST /api/v1/user/api-key` mints and returns the replacement; see [Manage API](../api/manage.md).

The old key stops working the instant the new one is minted. The new key may
need a few seconds before it is accepted on every request, so wrap the first
post-rotation call in a brief retry if a transient `401` or `403` appears.
After that, update every other holder of the old key (other MCP hosts,
scripts, CI secrets, forwarder configs) or they start returning
`401 Unauthorized`.

## Good practice

- Keep keys out of version control; use Kubernetes Secrets or a secrets manager.
- Use a separate environment for dev, staging, and prod. That separates the data,
  not the credential: the same account key reaches all three, with a permission
  level per environment.
- Rotation is account-wide. Every holder of the old key stops working at once,
  in every environment, so plan it as one change rather than per stage.
- Rotate on a schedule and whenever a key may have leaked.

## Troubleshooting

??? tenx-troubleshoot "API key not working"
    | Cause | Fix |
    |-------|-----|
    | Key rotated or expired | Generate a new key and update every holder |
    | Wrong environment | Confirm the `ENV_ID` in the header matches the key's environment |
    | Network or firewall | Confirm the engine can reach the metrics endpoint |

??? tenx-troubleshoot "Metrics not appearing in your TSDB"
    | Cause | Fix |
    |-------|-----|
    | Wrong remote-write endpoint | Verify the metric-output URL in the engine config |
    | Authentication failed | Check the API key in the engine config |
    | Environment mismatch | Confirm the environment label matches what your dashboards filter on |

:material-arrow-right: [Authentication](authentication.md) covers identity.
[License](license.md) covers the engine token.
