# Authentication

Every request carries a credential in the `Authorization` header:

```http
Authorization: Bearer fwk_…
```

There are two kinds of credentials:

| Credential | Looks like | For |
|---|---|---|
| API key | `fwk_` + 40 letters and digits | Your own scripts, CI jobs and integrations |
| OAuth access token | `fwa_` + 40 letters and digits | Apps connected through OAuth ([OAuth apps](/oauth)) |

## API keys

Owners and admins create keys in **Settings → API access → API keys**, with a current code from their authenticator app. A workspace can have 10 working keys at a time.

A key:

- **acts as the person who created it**, within the access it was given. It can never do more than that person could in the dashboard;
- **stops working at once** when it is revoked, when it expires, or when its creator is removed from the workspace or is no longer an owner or admin;
- **is shown once**. FortWatch keeps only a fingerprint of it. Lost it? Create a new one and revoke the old one.

## Access (scopes)

When you create a key you choose, for each area, **no access**, **read** or **read & write**. Reading (`GET`) needs the area's read access; anything else needs write. Write includes read.

| Area | What it covers | Scopes |
|---|---|---|
| Assets | Assets, projects, discovered hostnames | `assets:read`, `assets:write` |
| Scans | Scans and scan schedules | `scans:read`, `scans:write` |
| Issues | Issues, findings, open ports, comments | `issues:read`, `issues:write` |
| Reports | Reports, assessment reports | `reports:read`, `reports:write` |
| Audit log | The audit log | `audit:read`, `audit:write` |

A request outside the key's access answers `403` with the code `SCOPE_REQUIRED` and the scope it needed.

Some parts of FortWatch are **dashboard only** and answer a key with `403 SESSION_REQUIRED`: sign-in and account, FortWatch AI, billing, the team, workspace settings, notifications, integrations, ticket links, the dashboard page's own numbers (read reports instead) and API access itself. A key can never create or revoke keys.

## Keeping keys safe

- Send keys only in the `Authorization` header. A key in a URL is refused (`400 CREDENTIAL_IN_URL`) because URLs end up in logs; revoke a key you sent that way.
- `X-API-Key` is not read: it answers `401 API_KEY_HEADER`.
- Give each tool its own key with only the access it needs, so you can revoke one without touching the others.
- Rotate by creating a new key, switching the tool to it, then revoking the old one.
- Every key expires (30 days, 90 days or 1 year), so a forgotten key stops by itself.

## The audit log

Everything a key changes is recorded in the workspace's audit log under the key's creator, "via API key ‘<name>’", with the address it came from. Reads are not recorded.
