Compliance
Package compliance is your KYC/KYB onboarding, accreditation records, and the evidence trail behind them.
Package compliance is your KYC/KYB onboarding, accreditation records, and the evidence trail behind them.
| Base URL | https://api.hanzo.ai |
| Operations | 17 |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Specification
HIP-1115 · Compliance — Verification of Record — Draft · read the specification →
/v1/compliance is an org's verification records: subjects (the people and
entities being verified), verification checks and their decisions,
accreditation, and the org-scoped record and audit reads that prove what was
decided and when. It is implemented in hanzoai/cloud apps/compliance. This
HIP states what the capability owns — a sealed store of subject PII and
decisions — and the two fail-closed seams that keep a verification honest: the
provider and its webhook.
Motivation
A verification that cannot be replayed is not a compliance record; it is a checkbox. The record has to survive the provider that produced it, carry the decision beside the evidence reference, and be readable only by the org it belongs to — which makes it a store of its own, not a relay to a vendor dashboard.
Specification
The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.
§1 The store
One SQLite file — the system namespace's compliance — born encrypted, so
subject PII (name, email) is encrypted at rest (apps/compliance/store.go:19-22).
Tenant isolation is physical in the schema: org is a column on every table
and every read and write filters by it; a record belonging to another tenant is
indistinguishable from one that does not exist, so there is no cross-tenant
probe (apps/compliance/store.go:14-16).
§2 The provider seam, fail-closed
Verification runs through the idv.Provider seam: Manual by default, a real
provider when configured — and a named-but-misconfigured provider MUST fail the
mount rather than silently downgrade to Manual
(apps/compliance/compliance.go:50-64). The optional provider webhook receiver
is authenticated by signature rather than by a principal, and it follows the
same rule: a named-but-unresolvable secret fails the mount rather than serving
an unauthenticated endpoint; nil means no webhook path is served at all
(apps/compliance/compliance.go:66-70).
§3 The addresses
Everything is under /v1/compliance: subjects (create, list, detail),
verifications (create, list, detail, decision, refresh, and the
signature-authenticated webhook), accreditation (create, list, detail,
decision), plus the reads records, status, audit and health. The
prefix is written once and composed onto every op
(apps/compliance/compliance.go:25-29). Operations are typed
(apps/compliance/typed_wire_test.go); the webhook is declared for what it is
— a provider-signed callback, not a principal-authenticated method.
§4 Tenancy, money, events, telemetry, stage, upstreams
Every handler resolves the org through principal.Acting (HIP-0026)
(apps/compliance/compliance.go:281); no principal, no answer. The capability
is METERED (plugin/compliance/main.go:28, Price: cloud.Metered), and the
billed act is exactly one: starting a verification opens an inquiry at the
provider on the deployment's own key, so the caller's ledger is charged the
inquiry fee — CLOUD_COMPLIANCE_FEE_CENTS[_INQUIRY], resolved through the
fleet's ordinary provision default, authorized BEFORE the provider is asked
and debited only after an inquiry actually opened
(apps/compliance/meter.go:29-55). Everything else on the surface reads the
org's own rows and is free. It publishes no events
on the bus. Beyond the request span, compliance-relevant actions are recorded
on the shared audit plane under the compliance. action prefix
(apps/compliance/compliance.go:31-32), which is how /v1/compliance/audit
can answer. Its stage is the one its manifest row declares, which HIP-0139 §8
keeps as the single copy; this text carried beta after the row had become
ga. It derives from no
upstream; the provider integration is a configuration of the idv seam, and
storage is the hanzoai/sqlite facade.
Rationale
Fail-closed at mount, rather than at first use, is the deliberate choice in both seams. A provider that silently degrades to Manual passes every health check and quietly stops verifying — the operator finds out during an audit, which is the most expensive possible moment. Failing the mount converts a misconfiguration into a deploy failure, which is cheap and immediate.
The alternative to owning a store is relaying to the provider's records. That couples the org's compliance history to a vendor contract: cancel the vendor, lose the history. The store keeps the decision and its reference; the provider keeps the evidence it is contractually the custodian of.
Security Considerations
This store is PII plus regulatory decisions — the two things with the highest
disclosure cost per row. The wrong implementation leaks a tenant's customer
list with names and emails attached, or lets a forged webhook flip a
verification to approved. The defenses are stated above because they are the
design: encryption at rest, org on every row with not-found aliasing, and a
webhook that either verifies a signature or does not exist. The decision
endpoints are the residual surface: they accept a human judgment, and the
audit trail under the compliance. prefix is what makes such a judgment
attributable after the fact.
Four surfaces
| Surface | Reaches this capability as | Coverage |
|---|---|---|
| REST | compliance at its own prefix | 17 operations |
| CLI | hanzo compliance … | 17 of 17 |
| SDK | ComplianceApi in every published client | 17 methods |
| MCP | tool compliance on https://api.hanzo.ai/v1/mcp | 17 operations, 5 under the document's own id — ask describe for the rest |
Quickstart
export HANZO_API_KEY=sk-... # console.hanzo.ai → API keysThen the first call — a read that needs nothing but the key. GET /v1/compliance/audit, operation get_compliance_audit:
hanzo compliance auditimport { Configuration, ComplianceApi } from 'hanzoai';
const api = new ComplianceApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.getComplianceAudit();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ComplianceApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ComplianceApi(client).get_compliance_audit()cfg := cloud.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := cloud.NewAPIClient(cfg)
resp, _, err := client.ComplianceAPI.GetComplianceAudit(context.Background()).Execute()
if err != nil {
return err
}use hanzo_cloud::apis::{configuration::Configuration, compliance_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = compliance_api::get_compliance_audit(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ComplianceApi;
ApiClient client = new ApiClient();
client.setRequestInterceptor(b -> b.header("Authorization", "Bearer " + System.getenv("HANZO_API_KEY")));
var result = new ComplianceApi(client).getComplianceAudit();curl https://api.hanzo.ai/v1/compliance/audit \
-H "Authorization: Bearer $HANZO_API_KEY"Tool compliance, op get_compliance_audit — POST the JSON-RPC envelope to https://api.hanzo.ai/v1/mcp.
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "compliance",
"arguments": {
"op": "get_compliance_audit",
"input": {}
}
}
}'Answers 200 with object — ok.
Endpoints
| Endpoint | What it does |
|---|---|
POST /v1/compliance/accreditation/{id}/decision | Records an org reviewer's decision on an accreditation record — a reviewer confirmation, a provider verification the reviewer has evidence of (a… |
GET /v1/compliance/accreditation/{id} | Returns one tracked accreditation record. |
GET /v1/compliance/accreditation | Returns the org's tracked accreditation-state records, newest first — evidence entries the org keeps, never a platform certification. |
POST /v1/compliance/accreditation | Records an ASSERTED accreditation state for a subject — the subject's own assertion, with no verifier. |
GET /v1/compliance/audit | AuditRead is the compliance read of the SHARED tamper-evident audit plane — the SOC 2 posture surface (privileged actions: who started/decided what,… |
GET /v1/compliance/health | Health reports subsystem liveness and the wired verification provider. |
GET /v1/compliance/records | ListRecords is the unified compliance-record view for the org: its verifications and accreditation records together, each provider-reported or… |
GET /v1/compliance/status | Status is the org's honest posture read: the wired provider and the per-status tally of its verifications. |
GET /v1/compliance/subjects/{id} | Returns one subject WITH its contact PII — the only surface that returns it, and only to the owning org. |
GET /v1/compliance/subjects | Returns the org's subjects as PII-MINIMIZED summaries — no name or email, only whether an email is on file. |
POST /v1/compliance/subjects | Records a party the org is verifying as part of its own onboarding/compliance — a team member, vendor, customer, or counterparty. |
POST /v1/compliance/verifications/{id}/decision | Records a privileged reviewer's MANUAL decision on a verification — the human-in-the-loop path, and the ONLY route to a passing status when no real… |
POST /v1/compliance/verifications/{id}/refresh | Polls the wired provider for its current decision and records it, ATTRIBUTED to the provider — the internal PULL reconcile. |
GET /v1/compliance/verifications/{id} | Returns one verification — its opaque subject reference and provider-reported status, no subject PII. |
POST /v1/compliance/verifications/webhook | Provider push that settles a verification, authenticated by HMAC signature |
GET /v1/compliance/verifications | Returns the org's KYC/KYB verifications, newest first — opaque subject references and provider-reported statuses only, no subject PII. |
POST /v1/compliance/verifications | Begins a KYC/KYB verification of a subject through the wired provider — an existing subject by id, or one created inline from the request. |
How is this guide?