# Access Model & Scopes
URL: https://docs.autociso.io/developers/access-model/
Description: What an AutoCISO API token can reach, the eight original scopes, the nine newer read scopes, who may grant each, and what each grants, how the plan gates every call, and which actions stay human-only — with the full REST and MCP scope matrices.

AutoCISO API tokens are **deny-by-default**. A token is not a general-purpose key to your workspace: it opens four
specific surfaces, each guarded by its own scopes, and only for the features your organisation's
[plan](https://docs.autociso.io/getting-started/plans-and-features/) includes. This
page is the single reference for all three gates.

## Three gates on every call

Every request made with an API token passes three checks:

1. **Allowlist.** Is the path one of the four surfaces below? If not: `403 FORBIDDEN`, whatever the token carries.
2. **Scope.** Does the token carry the scope the route needs? If not: `403 INSUFFICIENT_SCOPE`, naming the scope.
3. **Plan.** Does your organisation's plan include the feature? If not: `402 FEATURE_GATED`, naming the lowest plan
   that does. Over MCP, tools for features outside your plan are simply not listed.

The allowlist is always checked first. The scope and plan checks run in a surface-specific order: on the
supply-chain and questionnaire routes the plan is checked before the scope, on the lifecycle routes the scope comes
first. A request that fails both therefore gets `402` on the former and `403` on the latter.

A few actions inside an allowlisted surface additionally refuse every token with `403 HUMAN_APPROVAL_REQUIRED` —
see [Human-only actions](#human-only-actions). No scope, plan or role widens any of these gates.

## The four surfaces

| Surface | Path | What it is | Plan |
|---------|------|-----------|------|
| Supply chain security | `/api/v1/sscs/*` | 13 REST endpoints — SBOMs, components, findings, vendors | The Growth |
| Supplier questionnaire authoring | `/api/v1/supplier-assessment-templates/*` | 22 REST endpoints — read, create, clone, translate and edit a questionnaire draft up to submitting it | The Growth |
| Employee lifecycle (read-only) | `/api/v1/jml/*` | 8 REST endpoints — leaver and joiner cases and their reconciled items | The Seed |
| MCP | `/mcp` | The Model Context Protocol endpoint for AI clients — 66 tools (61 read-only, 5 write) | Per tool |

**Every other path returns `403 FORBIDDEN`** when called with an API token:

```json
{
  "data": null,
  "error": {
    "code": "FORBIDDEN",
    "message": "API tokens are not permitted on this endpoint"
  }
}
```

The check runs during authentication, before routing and before scopes are evaluated.

### What stays closed, and why

Interactive endpoints — employees, access reviews, ISO projects, evidence, billing, settings — answer only to a
signed-in user, so that every change carries a real person's identity in the audit trail. In particular:

- The lifecycle and employee endpoints (`/api/v1/lifecycle/*` and `/api/v1/employees/*`) stay closed to tokens.
  Off-boarding and on-boarding data reaches a token only through the purpose-built `/api/v1/jml/` endpoints, which
  never return the raw employee record.
- **Tokens cannot manage tokens.** `GET`, `POST` and `DELETE` on `/api/v1/tokens`
  ([endpoint reference](https://docs.autociso.io/developers/api-tokens/)) reject API-token authentication, so a
  leaked token cannot mint replacements for itself.
- `/api/v1/payloadlog/*` explicitly denies API tokens.

For programmatic **read** access to risk, ISO, access intelligence, supplier, compliance, monitoring, privacy or audit
data, use [MCP](https://docs.autociso.io/developers/mcp/overview/) — not REST.

## The eight scopes

These eight are the original scopes: they reach the supply-chain, MCP, supplier-questionnaire and lifecycle surfaces described below. Nine newer read scopes are covered in [Read scopes for platform data](#read-scopes-for-platform-data).

| Scope | Grants | Implies | Expiry |
|-------|--------|---------|--------|
| `sbom:read` | Read SBOMs, components, findings, vendors | — | Optional |
| `sbom:write` | Create, upload, update and delete supply-chain records | `sbom:read` | Optional |
| `mcp:read` | The 56 general read-only MCP tools — those your plan includes | — | Optional |
| `mcp:write` | Everything `mcp:read` grants, plus the `risk_create_draft` and `iso_audit_simulate` MCP tools | `mcp:read` | Optional |
| `supplier_template:read` | Supplier-questionnaire templates over REST and the 3 MCP read tools (`supplier_questionnaire_list`/`get`/`validate`), including scoring fields (weight, risk value, finding severity) no other scope exposes | — | Optional |
| `supplier_template:write` | Create, clone, translate, edit, submit and withdraw a questionnaire draft over REST, and the 3 MCP write tools (`supplier_questionnaire_clone`/`update_question`/`update_option`) | `supplier_template:read` | Required |
| `jml:read` | Read-only off-boarding and on-boarding reconciliation over REST (`/api/v1/jml/`): leaver and joiner cases and their items, without names or emails. Created by an [Owner or Manager](https://docs.autociso.io/getting-started/roles-and-permissions/) | — | Required, at most 365 days |
| `pii:read` | The `employee_resolve` MCP tool — real names and emails for explicitly requested employee IDs — and, on a token that also holds `jml:read`, the `name` and `email` fields of the off-boarding and on-boarding case endpoints. **Owner only**, every use audited | — | Required, at most 90 days |

Implication is one-directional: a token with `sbom:write` can read, but a token with `sbom:read` cannot write. The
families are independent:

- `sbom:write` grants nothing over MCP, and `mcp:write` grants nothing over REST.
- `mcp:write` grants **neither** `supplier_template:read` nor `supplier_template:write`. The questionnaire tools return
  scoring fields no other tool exposes, so they sit behind their own scope pair.
- `mcp:write` does not imply `pii:read`, and `pii:read` implies nothing. On its own `pii:read` grants nothing over REST
  and unlocks exactly two MCP tools; a token with only `pii:read` sees two tools in `tools/list`. Combined with
  `jml:read` it adds names and emails to the case endpoints — see [Employee identity](https://docs.autociso.io/developers/employee-identity/).
- `jml:read` implies nothing and grants nothing over MCP. A token holding `jml:read` together with `pii:read` must
  expire within 90 days.

**Tip — Grant the narrowest scope that works**

A CI job that only uploads SBOMs needs `sbom:write` alone. An AI assistant that only answers questions needs
`mcp:read` alone. Issue one token per integration so you can revoke one client without disrupting the others.

Scopes are fixed when a token is created. To change them, create a new token and revoke the old one — see
[Rotating a token](https://docs.autociso.io/developers/api-tokens/#rotating-a-token).

## Read scopes for platform data

Nine more scopes give a token read-only access to platform data over REST. They are live: a token that holds one
can call the operations listed below, and nothing else. The create-token dialog marks a scope *Not live for your
organisation yet* only if its endpoints are switched off for your organisation, and you can still select it.

| Scope | Data | Operations | Who may grant it | Longest expiry |
|-------|------|------------|------------------|----------------|
| `asset:read` | Assets, their owners, classification and status | [List assets](https://docs.autociso.io/api/reference/assets/list/) | Owner or Manager | 365 days |
| `risk:read` | The risk register and its statuses | [List risk records](https://docs.autociso.io/api/reference/risk-records/list/), [get one](https://docs.autociso.io/api/reference/risk-records/get/) | Owner or Manager | 365 days |
| `supplier:read` | Suppliers, their agreements and assessments | [List suppliers](https://docs.autociso.io/api/reference/suppliers/list/), [get one](https://docs.autociso.io/api/reference/suppliers/get/), [agreements](https://docs.autociso.io/api/reference/suppliers/list-agreements/), [assessments](https://docs.autociso.io/api/reference/suppliers/list-assessments/) | Owner or Manager | 365 days |
| `iso:read` | ISO 27001 projects, gap controls, policies, readiness, roadmap and Statement of Applicability | [List ISO projects](https://docs.autociso.io/api/reference/iso-projects/list/) and the project operations under it | Owner or Manager | 365 days |
| `compliance:read` | Compliance posture, control reliability states and continuous monitoring status | [Compliance overview](https://docs.autociso.io/api/reference/compliance/get-overview/), [control states](https://docs.autociso.io/api/reference/compliance/list-states/), [project monitoring](https://docs.autociso.io/api/reference/iso-projects/get-monitoring/) | Owner or Manager | 365 days |
| `evidence:read` | Evidence metadata collected for a project's controls | [List evidence](https://docs.autociso.io/api/reference/iso-projects/list-evidence/) | Owner or Manager | 365 days |
| `access_review:read` | The access inventory, one row per grant | [List the access inventory](https://docs.autociso.io/api/reference/access/list/) | **Owner only** | 365 days |
| `employee:read` | Employee records and their access history | [List employees](https://docs.autociso.io/api/reference/employees/list/), [access history](https://docs.autociso.io/api/reference/employees/get-access-history/) | **Owner only** | 180 days |
| `audit_log:read` | Audit trail entries: ids, codes and chain fields only | [List audit trail entries](https://docs.autociso.io/api/reference/audit-trail/list/) | **Owner only** | 180 days |

Employee names and emails are not part of `employee:read`. They are returned only to a token that also holds
`pii:read`, which is a separate Owner-granted scope with its own limits (see above). Every read that discloses
identities, and every read of the audit trail, is recorded in your organisation's Audit Trail.

Rules that apply to every scope in this table:

- **Always read-only.** None of them implies another scope, and none can write.
- **An expiry is required.** Pick a date no later than the longest expiry in the table. If the token also holds
  another scope with a shorter ceiling, the lowest ceiling wins: `jml:read` is 365 days, and any token that holds
  `pii:read` is 90 days. See [Expiry rules](https://docs.autociso.io/developers/api-tokens/#expiry-rules).
- **Granting is checked when the token is created.** Owner-only scopes are refused for a Manager with
  `403 OWNER_REQUIRED`; a scope your role may not grant gets `403 INSUFFICIENT_ROLE`.
- **The creator must stay qualified.** If the person who created a token later loses the role the token's scopes
  need, or leaves the organisation, AutoCISO suspends the token. A suspended token is refused like a revoked one and
  is not resumed; the token list shows `suspendedAt` and `suspendedReason`. Create a replacement.
- **A plan can still say no.** A scope never unlocks a feature your [plan](https://docs.autociso.io/getting-started/plans-and-features/) lacks;
  the call returns `402 FEATURE_GATED` naming the lowest plan that includes it.
- **At most 40 scopes** per token, as explicit names. A wildcard such as `asset:*`, or a preset name, is refused
  with `400 SCOPE_INVALID`.

### Audit trail integrity: `audit_log:verify`

One more read-only scope lets a token run the Audit Trail integrity check
([Verify the audit trail hash chain](https://docs.autociso.io/api/reference/audit-trail/verify/)) and nothing else: it does not read audit
entries, implies no other scope and is implied by none. Reading the entries needs `audit_log:read`, above.

| Scope | What it grants | Who may grant it | Longest expiry | Plan |
|-------|----------------|------------------|----------------|------|
| `audit_log:verify` | Run the audit chain integrity check | **Owner only** | 180 days | The Growth and above (Audit Trail) |

The expiry rules and the other rules above apply. What the result shows a token, and how fresh it is, is described in
[Audit Trail Integrity](https://docs.autociso.io/product/admin/audit-trail-integrity/#running-the-check-with-an-api-token).

### Presets

The create-token dialog offers two presets that only tick boxes for you; the token stores the individual scope
names, never the preset. Neither preset includes `pii:read` or any of the original eight scopes. **BI read-only** does not include `audit_log:verify`.

| Preset | What it selects |
|--------|-----------------|
| **Read everything** | All nine scopes in the table above, plus `audit_log:verify` |
| **BI read-only** | The six scopes a Manager may grant: `asset:read`, `risk:read`, `supplier:read`, `iso:read`, `compliance:read`, `evidence:read` |

To see exactly which scopes your role may grant, and whether their endpoints are live, open **API Tokens** and click
**Create Token**; the dialog reads the same list from `GET /api/v1/tokens/scopes`
([reference](https://docs.autociso.io/api/reference/token-scopes/list/)).

### Suspended organisations

While an organisation is suspended, a token of that organisation is refused with `403 ORG_SUSPENDED` on every
surface a token can reach: supply chain, supplier templates, lifecycle, the MCP endpoint and the read endpoints for
the scopes above once they are published. The token itself is unchanged: calls work again as soon as the
organisation is reactivated. The refusal carries no plan or organisation details. The suspension can take up to
30 seconds to take effect.

## REST scope matrix

All paths are relative to `https://api.autociso.io/api/v1`.

### Supply chain — `sbom:*`

Requires the Supply Chain Security feature (The Growth plan or higher). Reference:
[Supply chain API](https://docs.autociso.io/api/reference/); per-endpoint pages for
[SBOMs](https://docs.autociso.io/api/reference/sboms/list/), [findings](https://docs.autociso.io/api/reference/findings/list/) and
[vendors](https://docs.autociso.io/api/reference/vendors/list/).

| Method | Path | Scope |
|--------|------|-------|
| `GET` | `/sscs/sboms` | `sbom:read` |
| `GET` | `/sscs/sboms/{sbomId}` | `sbom:read` |
| `GET` | `/sscs/sboms/{sbomId}/components` | `sbom:read` |
| `POST` | `/sscs/sboms` | `sbom:write` |
| `POST` | `/sscs/sboms/upload` | `sbom:write` |
| `DELETE` | `/sscs/sboms/{sbomId}` | `sbom:write` |
| `GET` | `/sscs/findings` | `sbom:read` |
| `GET` | `/sscs/findings/summary` | `sbom:read` |
| `PATCH` | `/sscs/findings/{findingId}/status` | `sbom:write` |
| `GET` | `/sscs/vendors` | `sbom:read` |
| `GET` | `/sscs/vendors/risk-summary` | `sbom:read` |
| `POST` | `/sscs/vendors` | `sbom:write` |
| `PUT` | `/sscs/vendors/{vendorId}` | `sbom:write` |

### Supplier questionnaires — `supplier_template:*`

Requires the Supply Chain Security feature (The Growth plan or higher). Reference:
[Supplier questionnaires API](https://docs.autociso.io/api/reference/supplier-templates/list/).

| Method | Path | Scope |
|--------|------|-------|
| `GET` | `/supplier-assessment-templates` | `supplier_template:read` |
| `GET` | `/supplier-assessment-templates/{templateId}` | `supplier_template:read` |
| `GET` | `/supplier-assessment-templates/{templateId}/versions/{version}` | `supplier_template:read` |
| `GET` | `/supplier-assessment-templates/{templateId}/versions/{version}/diff/{otherVersion}` | `supplier_template:read` |
| `POST` | `/supplier-assessment-templates/{templateId}/validate` | `supplier_template:read` |
| `POST` | `/supplier-assessment-templates/{templateId}/publish/preview` | `supplier_template:read` |
| `POST` | `/supplier-assessment-templates` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/clone` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/translate` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/{templateId}/draft` | `supplier_template:write` |
| `PATCH` | `/supplier-assessment-templates/{templateId}/meta` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/{templateId}/sections` | `supplier_template:write` |
| `PATCH` | `/supplier-assessment-templates/{templateId}/sections/{sectionId}` | `supplier_template:write` |
| `DELETE` | `/supplier-assessment-templates/{templateId}/sections/{sectionId}` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/{templateId}/questions` | `supplier_template:write` |
| `PATCH` | `/supplier-assessment-templates/{templateId}/questions/{questionId}` | `supplier_template:write` |
| `DELETE` | `/supplier-assessment-templates/{templateId}/questions/{questionId}` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/{templateId}/questions/{questionId}/options` | `supplier_template:write` |
| `PATCH` | `/supplier-assessment-templates/{templateId}/questions/{questionId}/options/{optionId}` | `supplier_template:write` |
| `DELETE` | `/supplier-assessment-templates/{templateId}/questions/{questionId}/options/{optionId}` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/{templateId}/submit` | `supplier_template:write` |
| `POST` | `/supplier-assessment-templates/{templateId}/withdraw` | `supplier_template:write` |

### Employee lifecycle — `jml:read`

Read-only. Requires the Employee lifecycle feature (The Seed plan or higher). Limited to 5 requests per second per
token, burst of 30 — see [Errors & rate limits](https://docs.autociso.io/developers/errors-and-limits/). References:
[Off-boarding API](https://docs.autociso.io/api/reference/offboarding-cases/list/), [On-boarding API](https://docs.autociso.io/api/reference/onboarding-cases/list/).

| Method | Path | Scope | Employee name and email |
|--------|------|-------|-------------------------|
| `GET` | `/jml/offboarding/cases` | `jml:read` | With `pii:read` |
| `GET` | `/jml/offboarding/cases/{caseId}` | `jml:read` | With `pii:read` |
| `GET` | `/jml/offboarding/cases/{caseId}/items` | `jml:read` | Never (employee ID only) |
| `GET` | `/jml/offboarding/items` | `jml:read` | Never (employee ID only) |
| `GET` | `/jml/onboarding/cases` | `jml:read` | With `pii:read` |
| `GET` | `/jml/onboarding/cases/{caseId}` | `jml:read` | With `pii:read` |
| `GET` | `/jml/onboarding/cases/{caseId}/items` | `jml:read` | Never (employee ID only) |
| `GET` | `/jml/onboarding/items` | `jml:read` | Never (employee ID only) |

The lifecycle API is switched on per deployment; where it is not enabled, these paths answer `403 FORBIDDEN`.

## MCP scope matrix

Over `/mcp`, scope decides which tools appear in `tools/list`. A tool the token may not use is filtered out of the
listing rather than failing at call time. The server registers 66 tools in total (61 read-only, 5 write); which of
them a token sees depends on its scopes **and** on the organisation's plan — a scope never unlocks a feature the plan
does not include (see [Scope is not entitlement](https://docs.autociso.io/developers/mcp/authentication/#scope-is-not-entitlement)). Counts
below are for an organisation on The Scale:

| Scope | Tools visible |
|-------|--------------|
| `mcp:read` | 56 read-only tools (Free 3, Seed 10, Growth 44, Scale 56) |
| `mcp:write` | 57 tools (adds `risk_create_draft` and `iso_audit_simulate`) |
| `supplier_template:read` | 3 supplier-questionnaire read tools |
| `supplier_template:write` | 6 supplier-questionnaire tools (adds the 3 write tools) |
| `pii:read` | 2 tools, `employee_resolve` and `employee_lookup` — absent from `tools/list` for every token without the scope |

A token needs `mcp:write` and `supplier_template:write` together to see all 5 write tools, and `pii:read` on top to
see all 66. Every write tool has a second gate: it is hidden unless MCP writes are enabled for the deployment. A token
holding every write scope against a deployment with writes disabled sees only the
61 read tools (59 without `pii:read`). `employee_resolve` and `employee_lookup` are likewise registered only where employee identity access is enabled.

## Human-only actions

Inside the questionnaire-authoring surface, a `supplier_template:write` token can open a draft, edit it and call
`submit`, moving it to **Awaiting approval**. It cannot go further: `publish`, `reject` (the "send back" action in the
console), `archive`, `unarchive`, `default` and `DELETE /{templateId}` refuse every API token with
`403 HUMAN_APPROVAL_REQUIRED`, whatever scope it holds. Publishing changes how every new supplier assessment is scored,
with no recall, so it always needs a person — there is no `supplier_template:publish` scope.

Edits made through a token count as edits by the person who created the token, so a token cannot be used to get
around the second approver. See [Supplier questionnaires](https://docs.autociso.io/product/suppliers/questionnaires/).

Access revocation follows the same rule. Marking an audit upload as a **complete snapshot** of an asset
(`is_complete_snapshot=true` on the console upload) is accepted from a signed-in person only: an API token that sends it
gets `403 HUMAN_APPROVAL_REQUIRED`. A complete snapshot never revokes anything by itself. Once it has no pending review
tasks and is large enough (at least 3 rows and at least 20% of the asset's current active grants), active grants that it
does not list become *possible revocations*, and an Owner or Manager approves or keeps each one in the console, on the
Access page. This review is available to signed-in people only, never to API tokens.

## When a gate refuses

| Status | Code | Meaning | Fix |
|------|------|---------|-----|
| `403` | `FORBIDDEN` | The path does not accept API tokens, or the lifecycle API is not enabled for your deployment | Use a signed-in session or MCP. Adding scopes will not help. |
| `403` | `INSUFFICIENT_SCOPE` | The path accepts tokens, but this token lacks the scope named in the message | Create a token with that scope |
| `403` | `HUMAN_APPROVAL_REQUIRED` | The action is human-only | Do it in the console |
| `403` | `OWNER_REQUIRED` | A Manager tried to create a `pii:read` token | Ask an Owner |
| `402` | `FEATURE_GATED` | Your plan does not include the feature; `error.args.minTierName` names the plan that does | Upgrade in user menu → [**Billing & Subscription**](https://docs.autociso.io/console/settings/billing/) |

```json
{
  "data": null,
  "error": {
    "code": "INSUFFICIENT_SCOPE",
    "message": "this API token does not have the required scope: sbom:write"
  }
}
```

The full list of status codes and rate limits is in [Errors & rate limits](https://docs.autociso.io/developers/errors-and-limits/).
