# API tokens

> API tokens act for the member who creates them, with a role no higher than theirs, an optional domain or client scope and an expiry of 1 to 365 days.

An API token lets a script, a CI pipeline, the [CLI](https://developers.openwaf.dev/cli/) or an [AI assistant](https://developers.openwaf.dev/mcp/) use the OpenWAF API on your
behalf. Tokens look like `owf_…` and are sent as a bearer token:

```http
GET /v1/orgs HTTP/1.1
Host: dash.openwaf.dev
Authorization: Bearer owf_…
```

`GET /v1/orgs` returns the organization the token belongs to, with its `id`: the `{org}` of every other API path.

## What a token is made of

| Property | Values | Notes |
|---|---|---|
| Name | 1–200 characters | Where it is used, for example “CI deploy”. |
| Role | `owner`, `admin`, `tech`, `readonly` | At most your own role. Defaults to your role. |
| Scope | Whole organization, one domain, or one client | Limit each token to what it needs. |
| Expiry | 1–365 days | Defaults to 90 days. There are no tokens without expiry. |
| Purge only | On or off | The token can only purge the cache of one domain. |

The secret is shown **once**, when the token is created. OpenWAF stores only a hash of it and shows a short prefix in
the token list. If you lose a token, revoke it and create a new one.

## Owner and effective role

Every token belongs to the member who created it and never does more than that member can do **now**:

- Its effective role is the lower of the token's role and the member's current role.
- If the member is limited to a client, the token is limited to that client too.
- If the member leaves or is removed from the organization, all their tokens are revoked.

See [Effective role](https://developers.openwaf.dev/fundamentals/organizations-and-roles/#effective-role).

## Scopes

- **Whole organization**: every domain of the organization, within the token's role.
- **One domain**: the token only sees that zone. It cannot add or delete domains, manage clients or create other
  tokens.
- **One client**: the token sees only the domains assigned to that client, and can only have the `tech` or
  `readonly` role. Domains it adds are assigned to that client.
- **Purge only**: a domain-scoped `tech` token that can only call the cache purge endpoints of its domain, for example
  from CI after a deploy. Any other call is refused with `403 token_scope`. See [Cache](https://developers.openwaf.dev/cache/).

## Create a token

**Dashboard**

Open **API tokens › Create token**. Enter a name, choose the role, the scope and **Expires in (days)**, and select
**Create token**. Copy the secret from the dialog: it is not shown again.
**API**

```sh
curl -X POST "https://dash.openwaf.dev/v1/orgs/$ORG/tokens" \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "CI deploy", "role": "tech", "zone_id": "'"$ZONE"'", "expires_in_days": 90}'
```
The answer includes `secret`. Use `client_id` instead of `zone_id` to limit the token to a client, and
`"purge_only": true` with a `zone_id` for a purge-only token.


Any member can create tokens for themselves. A domain-scoped token cannot create tokens.

## List and revoke tokens

Admins of the whole organization see every active token in **API tokens**, with its scope, creator, expiry and last
use, and can revoke any of them. Any token can revoke itself.

```sh
curl -X DELETE "https://dash.openwaf.dev/v1/orgs/$ORG/tokens/$TOKEN_ID" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

Revocation is immediate. Expired, revoked and unknown tokens get `401 unauthorized`.

## Tokens created by OAuth

When you connect an AI assistant to the [MCP server](https://developers.openwaf.dev/mcp/) with OAuth, OpenWAF creates a token for that connection.
It appears in **API tokens** with the **OAuth app** badge; revoke it to disconnect the application.

## Good practice

- Give each integration its own token, with the lowest role and the narrowest scope that works.
- Keep tokens in a secret store or an environment variable, never in a repository, a ticket or a command line. The
  CLI reads them from `OPENWAF_TOKEN` or a file in `OPENWAF_TOKEN_FILE` (readable only by you).
- Prefer short expiries and rotate tokens before they expire.
