# How AutoCISO Works
URL: https://docs.autociso.io/developers/architecture/
Description: The data flow from employee list and access imports to findings and evidence, how an API request is checked, how SBOM uploads are processed, and how tenants are isolated.

This page explains, at the level an integrator or a security reviewer needs, how data moves through AutoCISO and how
each request is checked. It does not describe internal infrastructure.

## From raw lists to findings

Everything starts from two inputs: your **employee list** (who works here) and the **user lists of your
applications** (who has an account where). AutoCISO matches every account to an employee and builds the
[access inventory](https://docs.autociso.io/console/access/inventory/); every report, finding and piece of access evidence is derived from that inventory.

```mermaid
flowchart LR
  EMP["Employee list<br/>CSV import · manual"]
  ACC["Application user lists<br/>CSV · spreadsheet · screenshot · manual"]
  LC["Lifecycle cases<br/>joiners · leavers"]
  MATCH["Matching<br/>email first, then name"]
  INV["Access inventory<br/>employee × asset"]
  OUT["Findings & reports<br/>review queue · CISO reports · leaver checks · evidence"]

  EMP --> MATCH
  ACC --> MATCH
  MATCH --> INV
  LC --> INV
  INV --> OUT
```

_Inputs are matched into the access inventory; everything else is derived from it._

Matching treats an exact email address as decisive. When only a name is available and it fits several employees,
the row is held for review instead of being guessed — see
[Correct an employee match](https://docs.autociso.io/product/access/correct-employee-match/). Screenshots and PDFs are read with AI; which
provider sees what is described in [AI providers](https://docs.autociso.io/product/admin/ai-providers/).

## How an API request is checked

Every request made with an [API token](https://docs.autociso.io/developers/api-tokens/) passes the same checks before any data is read. The organisation always comes
from the token itself, never from the request.

```mermaid
sequenceDiagram
  actor Client
  participant API as AutoCISO API
  Client->>API: Request + Authorization: Bearer aci_…
  API->>API: Token valid, not expired or revoked?
  alt No
    API-->>Client: 401 INVALID_TOKEN
  end
  API->>API: Path on the token allowlist?
  alt No
    API-->>Client: 403 FORBIDDEN
  end
  API->>API: Scope on the token, feature in the plan?
  alt Scope missing
    API-->>Client: 403 INSUFFICIENT_SCOPE
  else Feature not in plan
    API-->>Client: 402 FEATURE_GATED
  end
  API-->>Client: 200 / 201 with data from the token's organisation only
```

_The checks an API-token request passes, in order._

The order of the scope and plan checks differs by surface; the [Access model](https://docs.autociso.io/developers/access-model/) has the details.

## What happens to an SBOM upload

An upload ([`POST /sscs/sboms/upload`](https://docs.autociso.io/api/reference/sboms/upload/)) is parsed and stored in the
request; vulnerability matching runs afterwards, so the response returns quickly and findings appear a little later in
[Vulnerability Findings](https://docs.autociso.io/console/supply-chain/findings/). To wire this into a pipeline, see
[Upload an SBOM from CI](https://docs.autociso.io/api/upload-sbom/).

```mermaid
flowchart TB
  UP["POST /sscs/sboms/upload<br/>go.sum · pom.xml · Gradle · package.json · requirements.txt"]
  PARSE["Parse the manifest<br/>parser chosen by file name"]
  STORE["Store the SBOM and its components"]
  RESP["201 Created"]
  MATCH["Background: match components<br/>against vulnerability feeds"]
  FIND["Findings by severity<br/>console and /sscs/findings"]

  UP --> PARSE --> STORE --> RESP
  STORE --> MATCH --> FIND
```

_An SBOM upload: synchronous parsing, background matching._

## Tenant isolation

Each organisation's data is isolated from every other organisation's. Every record belongs to exactly one
organisation, and every request — from the console, the REST API or MCP — is scoped to the organisation bound to
its verified credentials:

- The console takes the organisation from your signed-in session and membership.
- An API token is bound to the organisation that created it. No endpoint or MCP tool accepts an organisation
  identifier, so a token cannot be pointed at another tenant.
- A person who belongs to several organisations switches between them explicitly; their
  [role](https://docs.autociso.io/getting-started/roles-and-permissions/) can differ in each.

## Evidence over time

Evidence for an ISO 27001 control is kept as a history in the [Evidence Vault](https://docs.autociso.io/console/iso/evidence/). The newest item for a control is the current one; older items
stay as history, and anything older than the freshness window is flagged as stale so it can be refreshed before an
audit.

```mermaid
stateDiagram-v2
  [*] --> Fresh : uploaded or collected
  Fresh --> Stale : newer evidence added for the control
  Fresh --> Stale : older than the freshness window
  Stale --> [*] : kept as history
```

_Evidence for one control: the newest item is current, older items become history._

See [Upload evidence for a control](https://docs.autociso.io/product/iso/upload-evidence/) for how this looks in the console.
