Regulatory APIs
A regulator with a court order, an auditor with a SOC 2 scope, an internal compliance officer doing quarterly review: each one needs a way to read the receipt log without changing it. The Phase 19.3 regulatory API is the read-only export surface for those use cases. Every response is a signed envelope; the schema is stable; the backing store is whatever receipt store the operator uses.
Use this page when
API Surface
The endpoint is implemented as a substrate-agnostic handler in chio-http-core/src/regulatory_api.rs. It does not embed an HTTP server: substrate adapters wire the handler into their framework's router (Axum, Actix, Fastly Compute@Edge, whatever) and forward query-string fields throughRegulatoryReceiptsQuery.
The query shape:
pub struct RegulatoryReceiptsQuery {
/// Filter by agent subject (hex-encoded Ed25519 public key).
pub agent: Option<String>,
/// Include only receipts with timestamp >= after.
pub after: Option<u64>,
/// Include only receipts with timestamp <= before.
pub before: Option<u64>,
/// Maximum rows to return (capped at 200).
pub limit: Option<usize>,
}And the response body, wrapped in a SignedExportEnvelope:
pub const REGULATORY_RECEIPT_EXPORT_SCHEMA: &str =
"chio.regulatory.receipt-export.v1";
pub const MAX_REGULATORY_EXPORT_LIMIT: usize = 200;
pub struct RegulatoryReceiptExport {
pub schema: String,
pub agent_id: Option<String>,
pub after: Option<u64>,
pub before: Option<u64>,
pub matching_receipts: u64,
pub generated_at: u64,
pub receipts: Vec<ChioReceipt>,
}The envelope is signed with the kernel's receipt-signing keypair. Regulators verify against ChioKernel::public_key() using verify_regulatory_export.matching_receipts is the full count pre-limit; receipts contains up to limit_or_default() rows for paging.
Read-only by construction
RegulatoryReceiptSource) only exposes query_receipts. There is no write path through this API.Error Surface
Four error variants, mapped onto stable HTTP statuses:
| Variant | Status | Code | Cause |
|---|---|---|---|
BadRequest | 400 | bad_request | Malformed query (e.g. after > before). |
Unauthorized | 401 | unauthorized | Caller lacked an authorized regulator token. |
StoreUnavailable | 503 | store_unavailable | Backing receipt store could not respond. |
Signing | 500 | signing_error | Canonical-JSON signing failed (unexpected). |
Authorization
The handler will not return data unless the substrate adapter has already validated the caller and handed in an authorized RegulatorIdentity:
pub struct RegulatorIdentity {
/// Stable identifier for audit logging
/// (e.g. regulator name, agency id).
pub id: String,
}Operators typically validate a long-lived X-Regulatory-Token header against a small allowlist (each entry mapped to a RegulatorIdentity) and log every successful query. The kernel does not impose a token format; that is left to the substrate adapter so operators can use whatever auth mechanism their security review demands.
Tax and Billing Hooks
Receipt-driven tax reporting is a downstream consumer of the same billing pipeline that powers ordinary reconciliation. The regulatory export gives auditors the canonical receipts; the billing export (chio.billing-export.v1 from chio-metering) gives finance the per-receipt cost rollup. Each is signed; each is independently verifiable.
For tax reporting specifically, the typical pattern is:
- Run the billing export at jurisdiction-relevant cadence (monthly for VAT, annually for income, quarterly for sales tax).
- Filter records by agent, tool, or jurisdiction tag carried in the receipt's rail metadata.
- Cross-reference against the regulatory export for any periods under audit; the receipt ids appear in both, so the tax filing is backed by signed receipts and matching billing records.
See Reconciliation & Watchdog for the cycle that produces these records and Export Billing Records for the operator workflow.
Compliance Framework Mappings
Chio receipts and policy primitives map onto external compliance frameworks at well-defined points. The mappings are documented per framework on dedicated pages:
- NIST AI RMF: control-id mapping for the GOVERN, MAP, MEASURE, MANAGE functions.
- EU AI Act: article-level mapping for high-risk system obligations (Articles 9-15) and transparency requirements (Article 13).
- ISO 42001: clause-level mapping for AI Management System requirements.
- Compliance Frameworks, the synthesis page with SOC 2 trust-service-criteria mappings and cross-framework references.
Code-Level Claim Labels
Each chio primitive that participates in a control has a stable identifier the framework page can reference. Examples:
| Primitive | Maps to |
|---|---|
| Receipt signature + checkpoint inclusion | SOC 2 CC7.2 (system monitoring), NIST AI RMF MEASURE 2.7 (logging) |
| Capability scope and authority chain | SOC 2 CC6.1 (logical access), NIST AI RMF GOVERN 1.5 (accountability) |
| Settlement watchdog automation outcomes | SOC 2 CC7.4 (incident response), ISO 42001 8.3 (operational controls) |
| Regulatory export envelope | EU AI Act Article 12 (record-keeping), ISO 42001 9.1 (monitoring) |
| Compliance certificates and bilateral peer attestations | EU AI Act Article 28 (third-party conformity), NIST AI RMF GOVERN 6.1 |
The framework pages carry the full mappings. This page is the protocol-level view: what the API surface looks like, what every export contains, and how to use it.
HIPAA, PCI, GDPR Considerations
HIPAA
Protected Health Information (PHI) must never appear in an unredacted receipt. Operators handling PHI use chio's data guards (see Data Layer) to redact prompts and responses before the receipt is sealed. The regulatory export then contains the redacted form by construction; unredacted PHI never ends up in the signed envelope, so the export itself is never a HIPAA-covered artifact.
PCI DSS
For card payment flows on the Api rail, the receipt carries only the rail's opaque identifier (Stripe charge id, Adyen pspReference, etc.), never the PAN. The regulator can cross-reference the rail's own logs through the operator's PCI-scoped systems; chio is out of PCI scope by design because it does not handle cardholder data directly.
GDPR
Three GDPR-relevant facts about the regulatory API:
- Data minimization. The export filters by agent, time window, and limit. There is no“return everything” call; even an authorized regulator can only pull the slice their query targets.
- Audit trail. Every export carries
generated_atand the regulator id is logged by the substrate adapter. The export is itself a discoverable artifact for the data subject's right of access. - Right to erasure. Receipts are append-only and signed; erasure operates by tombstone (a tombstone receipt that supersedes the original) rather than deletion. The regulatory export will return the original plus the tombstone, preserving auditability while honoring the erasure intent.
For breach notification (Article 33 GDPR), the operator joins the receipt log against access logs to establish whose data was affected; the regulatory API is the read-side that auditors use to verify the operator's claim post-incident.
Auditor Workflow
End-to-end, what an auditor does with this API:
- Receive credentials. The operator provisions a regulator token bound to a
RegulatorIdentity. - Issue a query.
GET /regulatory/receipts?after=…&before=…&agent=…&limit=…with the token in the configured header. - Verify the envelope. The response is a
SignedExportEnvelope. Runverify_regulatory_export(or its substrate-adapter equivalent) against the operator's published kernel public key. Verification covers schema, signer key, and canonical-JSON integrity. - Read inclusion proofs. Each receipt carries a
Web3ReceiptInclusionfield with the merkle root and proof path. Verify that proof against the published checkpoint root inChioRootRegistryif the receipt is on a Web3 rail. - Cross-reference billing. Pull the billing export over the same window. Receipt ids appear in both; the rolled-up cost in the billing export must reconcile to the per-receipt amounts in the regulatory export.
Worked Example: 90-Day EU AI Act Audit
An EU regulator issues a request for all high-risk decisions issued by a deployed agent over the last 90 days. The agent's subject key is a1b2c3...; the window is after=1740000000 through before=1747776000.
Step 1: Query
curl -s 'https://kernel.example.com/regulatory/receipts?\
agent=a1b2c3...&after=1740000000&before=1747776000&limit=200' \
-H 'X-Regulatory-Token: <regulator-token>' \
> export.jsonThe response body (saved to export.json) is a SignedExportEnvelope:
{
"schema": "chio.regulatory.receipt-export.v1",
"agent_id": "a1b2c3...",
"after": 1740000000,
"before": 1747776000,
"matching_receipts": 142,
"generated_at": 1747776123,
"receipts": [/* up to 200 ChioReceipt records */],
"signature": "<ed25519-hex>"
}Step 2: Verify
use chio_http_core::regulatory_api::{
verify_regulatory_export, SignedRegulatoryReceiptExport,
};
let envelope: SignedRegulatoryReceiptExport =
serde_json::from_reader(File::open("export.json")?)?;
let kernel_public_key = load_kernel_public_key();
let verified = verify_regulatory_export(&envelope, &kernel_public_key)?;
assert!(verified, "envelope signature did not match kernel key");Step 3: Page If Needed
matching_receipts in the envelope tells the auditor whether the result is complete. MAX_REGULATORY_EXPORT_LIMIT = 200; if the matching count exceeds 200, the auditor narrows the time window or filters by tool to page through.
Step 4: Filter by Decision Class
The query does not natively filter by decision class; that is a client-side filter against the receipt stream. For each returned receipt, the auditor inspects the decision field on the receipt body and retains only the variants matching the audit scope (e.g. high-risk classifications, denials, or human-overridden approvals).
Step 5: Archive
The signed envelope is the primary audit artifact. The auditor retains it alongside the kernel public key fingerprint that was used to verify it; future re-verification works from the same envelope without needing the live kernel to remain online.
Limits
Three limits operators should be explicit about when they expose this API:
- Read-only. The handler cannot mutate, supersede, or amend a receipt. Erasure happens through tombstoning in the underlying receipt store; the regulatory API surfaces tombstones but does not create them.
- Jurisdiction-scoped. The operator's authorization rules decide which regulators see which slices of the receipt log. Chio does not enforce jurisdiction at the kernel level; that is policy in the substrate adapter (the same way capability scoping handles cross-tenant isolation elsewhere).
- Pagination is via window narrowing. There is no cursor. The 200-row cap forces regulators with large queries to either narrow the time window or filter by agent. This is intentional: it keeps the API stateless and the export deterministic.
See Also
- Compliance Certificates for the per-deployment certification artifact that participates in regulatory exports.
- Bilateral Receipts for cross-operator receipt sharing under federation peering.
- Compliance Frameworks for the framework-by-framework mappings.
- Query Audit Receipts for the operator-side query patterns that mirror the regulator API.
- Reconciliation & Watchdog for how receipts get to a state worth exporting.