---
title: API tokens
description: Mint, scope, and rotate the izri_ tokens the CLI, Action, and MCP server authenticate with.
order: 40
---

# API tokens

Every non-browser client — the CLI, the GitHub Action, the MCP server — authenticates with a bearer token.

## The `izri_` prefix is load-bearing

All tokens start with `izri_`. This is not cosmetic. The API short-circuits to bearer-token validation **only** when it sees that prefix; anything else falls through to cookie-session handling and produces an opaque `401` with no explanation.

If you get an unexplained 401 with a token you believe is valid, check the prefix before anything else. A truncated copy-paste that lost the prefix looks exactly like an expired token.

## Minting a token

From organization settings, create a token and select its scopes. **Copy it immediately** — it is shown once and stored hashed.

A token can hold a subset of your role's scopes, never more. See [organizations and roles](/docs/configure/organizations-and-roles) for the full role-to-scope matrix.

## Scoping

Grant the minimum the client needs.

| Client | Typical scopes |
| --- | --- |
| GitHub Action | `analysis:run`, `tests:run`, `projects:read` |
| CLI (local dev) | `analysis:run`, `tests:run`, `projects:read` |
| MCP server | `projects:read`, `tests:read`, `analysis:read` — add `tests:run` to let the agent trigger runs |
| Read-only dashboards | `projects:read`, `tests:read`, `analysis:read` |

A CI token does not need `tokens:write` or `org:write`. If a leaked CI token can mint more tokens, the blast radius of a leak is unbounded.

## Using a token

```bash
export IZRI_API_TOKEN=izri_xxxxxxxxxxxx
export IZRI_API_URL=https://api.izri.ai
```

```yaml
- uses: legendify-dev/izri/apps/github-action@v1
  with:
    api-token: ${{ secrets.IZRI_API_TOKEN }}
```

Directly against the API:

```bash
curl -H "Authorization: Bearer izri_xxxxxxxxxxxx" \
     https://api.izri.ai/health
```

## Rotation

1. Mint the new token.
2. Update every consumer — CI secrets, local environments, MCP configs.
3. Revoke the old one.

In that order. Revoking first means a window where CI fails on every PR.

Tokens do not expire on their own. Rotate on a schedule you choose, and immediately whenever someone with token-minting rights leaves.

## Tokens outlive role changes

A token's scopes are fixed when it's created. Demoting someone from `ADMIN` to `MEMBER` does not shrink the tokens they already minted. Revoke and reissue as part of any role change that's meant to remove access.

## Never commit a token

Use repository secrets in CI and your environment locally. A token in git history is compromised even after the commit is removed — rotate it rather than rewriting history.

## Related

- [Organizations and roles](/docs/configure/organizations-and-roles) — what scopes you can grant.
- [CLI](/docs/install/cli) — where the token goes.
