---
title: "Compliance rule packs"
---

# Compliance rule packs

Subscribe to framework rule packs, run checks, record evidence, GDPR Article 22 decision records and break-glass overrides, and what each check actually looks at.

The compliance engine keeps a catalogue of framework rule packs, lets an organisation subscribe to them, runs checks against the organisation's state and records the findings, and stores evidence and decision records for your assessor.

Everything here is **evidence toward** a framework's controls: a pass means a check found what it looks for, not that a control is met or that an assessor would accept it. Neural Inverse holds no certification on your behalf.

## Rule packs

Rule packs are a global catalogue shared by every organisation. Only platform operators publish packs and rules.

| Method | Path | Permission | What |
|---|---|---|---|
| `GET` | `/api/v1/compliance/rule-packs` | `compliance:read` | Packs by name, with `subscribed` for the caller's organisation |
| `GET` | `/api/v1/compliance/rule-packs/{id}` | `compliance:read` | One pack |
| `GET` | `/api/v1/compliance/rule-packs/{id}/rules` | `compliance:read` | The pack's rules by control |
| `POST` | `/api/v1/compliance/rule-packs` | `compliance:manage`, platform operators | Publish a pack: `name`, `version` (default `1.0`), `description` |
| `POST` | `/api/v1/compliance/rule-packs/{id}/rules` | `compliance:manage`, platform operators | Add a rule |

A rule has a `framework` (`SOC2`, `ISO42001`, `EU_AI_Act`, `GDPR`, `HIPAA`, `PCI_DSS`, `FedRAMP`, `NIST_AI_RMF`), a `control_id`, a `description`, a `check_fn_type` (`policy_check`, `data_check` or `config_check`; default `config_check`) and a `severity` (`critical`, `high`, `medium`, `low`; default `medium`).

## Subscribe and check

```http
POST /api/v1/compliance/subscriptions
{"pack_id": "<pack id>"}

POST /api/v1/compliance/checks
{"framework": "<rule pack name>"}
```

- Subscribing needs `compliance:manage`; subscribing again refreshes the version and keeps the original subscription id. `GET /api/v1/compliance/subscriptions` lists them with `last_checked_at`.
- A check runs every rule of the rule pack **whose name equals** `framework`, and stores one finding per rule with `status` `pass`, `fail` or `warn` and a `details` sentence.
- `GET /api/v1/compliance/findings?framework=` lists findings.

### What each check looks at

| Check type | Passes when | Otherwise |
|---|---|---|
| `policy_check` | The organisation has at least one enabled AI security pattern (AI SOC indicators) | `fail` |
| `data_check` | At least one evidence record exists for the rule's control | `warn` |
| `config_check`, controls `CC6.2` and `164.312(d)` | The audit log has MFA events for the organisation | `warn` |
| `config_check`, controls `CC6.7` and `164.312(a)(2)(iv)` | The organisation has an active signing key | `fail` |
| `config_check`, any other control | Passing evidence is on file for the control | `warn`: the control needs manual verification or evidence |

These are counts of records, not assessments of a control. Most controls report `warn` until someone records evidence for them. Automatic evidence collection exists in the code but no job or route runs it in this release.

## Evidence records

```http
POST /api/v1/compliance/evidence
{"framework": "SOC2", "control_id": "CC7.2", "evidence_type": "document",
 "content": "Quarterly access review completed; ticket SEC-118", "collected_at": "2026-10-01T00:00:00Z"}
```

- Needs `compliance:manage`. Each record gets `signed_hash`, which is a SHA-256 of its content: it detects a change to the stored content, but it is not a signature.
- `GET /api/v1/compliance/evidence?framework=&from=&to=` lists records.
- `GET /api/v1/compliance/audit-package?framework=` bundles the findings and evidence of a framework into one JSON document; see [Exports](https://neuralinverse.com/docs/evidence/exports/) for what its hash does and does not prove.

## GDPR Article 22 decision records

Records of automated decisions about people, with the legal basis and whether a human reviewed them:

```http
POST /api/v1/compliance/gdpr/decision-records
{"decision_id": "loan-77812", "affected_user": "<user id>", "decision_type": "credit_limit",
 "basis": "contract", "human_review_confirmed": true}
```

Records cannot be changed. `GET /api/v1/compliance/gdpr/decision-records` lists them, newest first.

## Break-glass overrides

A time-boxed record that a compliance rule was overridden in an emergency:

```http
POST /api/v1/compliance/break-glass
{"rule_id": "<rule id>", "reason": "INC-4410: restore access for on-call", "activation_id": "<your activation>", "duration_minutes": 60}
```

- `activation_id` must be the caller's own active break-glass activation in Keystone Access (`403 break_glass_activation_required` otherwise). The override ends with the activation, or sooner.
- It is a record for auditors only: **it changes no enforcement**. Nothing outside the compliance engine reads it.
- `GET /api/v1/compliance/break-glass` lists overrides (`active` is false once revoked, expired or its activation ended); `DELETE /api/v1/compliance/break-glass/{id}` revokes one.

## Audit of every change

Creating a pack, a rule, a subscription, a GDPR decision record or a break-glass override, and revoking an override, write the audit record in the same transaction as the change. If the record cannot be written the change is rolled back and the call answers `500`; on a server without an audit trail these calls answer `503` and change nothing. The audit record is the only record of who created or revoked an override.

## Console

The console has pages for rule packs, subscriptions, GDPR decision records and break-glass overrides. Evidence records and the audit package have no console page yet.

## Not available

Evidence packs generated from live system state (`/api/v1/audit/packs`) are partial: several of their collectors query the wrong columns, so those controls always record zero and fail. They are not described here as working.
