The AI Model & System Assurance Control Matrix is available as a CORS-enabled JSON API — fetch from any origin, no key required. 54 controls, 10 framework mappings, 11 deployment profiles, machine-readable obligation objects, and structured implementation guidance.
// Assurance target — the object this matrix verifies
{
"use_case": "employment-screening",
"actor_role": "deployer",
"model_provider": "openai",
"model_version": "gpt-4o-2024-11-20",
"prompt_hash": "sha256:...",
"rag_corpus_ids": ["resume-corpus-v3"],
"tool_manifest_ids": ["ats-api-v2"],
"deployment_context": "production-us-east",
"jurisdiction": ["us", "eu"],
"affected_party_impact": "material",
"autonomy_tier": "human-in-loop",
"materiality_tier": "high-impact-decision"
}
One fetch — no API key, no SDK, no rate limit.
// Browser or Node 18+
const { dataset } = await fetch(
'https://modelverifier.ai/integration/model-controls-full.json'
).then(r => r.json());
dataset.meta.control_count // 54
dataset.meta.version // "1.0.0"
dataset.controls.length // 54
dataset.profiles.length // 11
# curl
curl https://modelverifier.ai/integration/model-controls-full.json \
| jq '.dataset.meta'
Everything is under dataset. The top-level keys:
| Key | Type | Description |
|---|---|---|
| meta | object | Build metadata: version, hash, counts, generated timestamp |
| controls[] | array | 54 control records sorted LI→CR then by number |
| references[] | array | Deduplicated source documents cited by controls |
| layers[] | array | 6 layer definitions with control ID lists |
| planes[] | array | 4 assurance plane definitions |
| profiles[] | array | 11 deployment profiles with required/recommended control IDs |
| patterns[] | array | Implementation pattern summaries per control |
| framework_coverage[] | array | Per-framework mapping statistics |
| capability_coverage[] | array | Controls indexed by capability level and domain |
| lifecycle[] | array | Ordered 6-stage model assurance lifecycle |
Each control has a stable id (LI-01 through CR-08) that is never reused. The canonical_id is the globally unique cross-domain identifier: apeiris://model/controls/LI-01.
dataset.meta.has_warnings: false
with warning_count: 0. Framework gap warnings from the initial 1.0 build — primarily
BH and CR layer mappings not yet present in all frameworks — have been resolved in the current release.
All 6 layers now have complete NIST RMF and ISO 42001 mappings on every control.
A typed warnings[] block (severity, object_path, message, remediation, blocks_release)
is on the v1.1 data schema roadmap for future use when warnings are present.
Six layers span the full assurance lifecycle from asset identification through continuous risk management.
| Layer | Prefix | Name | Plane | Controls |
|---|---|---|---|---|
| LI | LI-01 – LI-10 | AI Asset, Lineage & Applicability | control | 10 |
| TG | TG-01 – TG-08 | Training & Data Governance | data | 8 |
| EV | EV-01 – EV-10 | Evaluation, Validation & Release | both | 10 |
| OA | OA-01 – OA-08 | Governance, Accountability & Oversight | control | 8 |
| BH | BH-01 – BH-10 | Deployment & Runtime Assurance | data | 10 |
| CR | CR-01 – CR-08 | Continuous Risk, Incident & Evidence | lifecycle | 8 |
// All controls in a specific layer
dataset.controls.filter(c => c.layer === 'EV')
Eleven profiles define which controls are required or recommended based on your deployment type. Profiles are additive to the 15-control baseline — all baseline controls apply regardless of profile.
gpai-provider and gpai-systemic-risk profiles
are now live — both profiles became applicable 2025-08-02 (12 months after EU AI Act entry into force).
The systemic risk profile (Ch. V, Section 3, Art. 55) is additive to the GPAI provider profile (Ch. V, Section 2) — both are simultaneously
active for providers above the 10²⁵ FLOPs threshold or designated by the AI Office.
// Get all required controls for a profile + the baseline
function requiredControls(dataset, profileId) {
const profile = dataset.profiles.find(p => p.profile_id === profileId);
const ids = new Set([
...dataset.meta.baseline_controls,
...(profile?.required_controls ?? []),
]);
return dataset.controls.filter(c => ids.has(c.id));
}
const euRequired = requiredControls(dataset, 'eu-high-risk');
// Returns baseline (15) + EU High-Risk required controls
// Controls required OR recommended for a profile
function applicableControls(dataset, profileId) {
const profile = dataset.profiles.find(p => p.profile_id === profileId);
const req = new Set(profile?.required_controls ?? []);
const rec = new Set(profile?.recommended_controls ?? []);
const base = new Set(dataset.meta.baseline_controls);
return dataset.controls.map(c => ({
...c,
applicability: base.has(c.id) ? 'baseline'
: req.has(c.id) ? 'required'
: rec.has(c.id) ? 'recommended'
: 'not-applicable'
})).filter(c => c.applicability !== 'not-applicable');
}
Ten frameworks are currently mapped. Each mapping object includes the requirement ID, fit rating (direct / supporting / adjacent / partial), rationale, and source locator.
| Key | Force | Framework |
|---|---|---|
| nist_rmf | voluntary | NIST AI Risk Management Framework 1.0 (NIST AI 100-1) |
| nist_ai_600_1 | voluntary | NIST AI 600-1 — GenAI Profile: confabulation, CBRN, data privacy, info integrity, info security, IP, human-AI configuration |
| iso_42001 | standard | ISO/IEC 42001:2023 AI Management Systems |
| eu_ai_act | binding (EU) | EU AI Act — Regulation 2024/1689 (Ch. III/IV high-risk; Ch. V GPAI providers; Ch. V, Section 3, Art. 55 systemic risk) |
| sr262 | guidance | Fed SR 26-2 — Supervisory Guidance on Model Risk Management |
| aisvs | voluntary | OWASP AI Security Verification Standard v1.0 |
| llm10 | voluntary | OWASP LLM Top 10 2025 v2.0 |
| aicm | voluntary | CSA AI Controls Matrix v1.1 (247 objectives, 18 domains — released 2026-06-22) |
| mitre | voluntary | MITRE ATLAS v5.6.0 |
| owasp_aitg | voluntary | OWASP AI Testing Guide v1 — structured test procedures mapped across all 6 layers (pre-release; mapping_confidence: medium; fit values: direct / supporting / adjacent) |
nist_ai_600_1 mappings referencing the eight GenAI risk categories (CONFABULATION, CBRN, DATA-PRIVACY, INFO-INTEGRITY, INFO-SECURITY, IP, HUMAN-AI-CONFIG, OBSCENE-DEGRADING). All nist_ai_600_1 mappings are provisional — category-level only; action-level IDs within each category have not been published by NIST. Each entry carries provisional: true and a provisional_note. Action-level granularity is planned for the next authoring cycle once NIST publishes sub-category identifiers.mapping_confidence: medium pending full verification against the published AICM v1.1 document; the 6 confirmed prefixes (GOV, DM, EVA, SEC, PRV, SUP) carry mapping_confidence: high.enforcement_gating metadata indicating the date basis (AI Act 2024/1689 as proposed to be amended by Digital Omnibus, provisional agreement May 2026, Council adoption pending) and legal status. The Dec 2, 2027 date for standalone Annex III systems is provisional pending final adoption.// Controls with direct EU AI Act Art. 9 mapping
dataset.controls.filter(c =>
c.frameworks?.some(f =>
f.framework === 'eu_ai_act' &&
f.requirement_id === 'Art-9' &&
f.fit === 'direct'
)
);
// Summarize coverage per framework
const coverage = {};
for (const c of dataset.controls) {
for (const fw of (c.frameworks ?? [])) {
coverage[fw.framework] ??= { direct: 0, supporting: 0, adjacent: 0, partial: 0 };
coverage[fw.framework][fw.fit] = (coverage[fw.framework][fw.fit] ?? 0) + 1;
}
}
// coverage.nist_rmf → { direct: 10, partial: 44 }
// coverage.owasp_aitg → { direct: 26, supporting: 12, adjacent: 4, partial: 10 }
// Build a gap report for SR 26-2 compliance
const sr262Controls = dataset.controls.filter(c =>
c.frameworks?.some(f => f.framework === 'sr262')
).map(c => ({
id: c.id,
name: c.name,
mappings: c.frameworks
.filter(f => f.framework === 'sr262')
.map(f => ({ req: f.requirement_id, fit: f.fit, rationale: f.rationale }))
}));
Every control has a maturity object with current (industry baseline today),
target (the level needed for meaningful assurance), and notes
(the specific steps required to advance).
| Level | Meaning | Advance to next by… |
|---|---|---|
| none | Control doesn't exist | Assign an owner, document intent |
| initial | Ad hoc, manual, inconsistent | Document and repeat the process |
| developing | Emerging practice, partial coverage | Complete coverage, standardize |
| defined | Automated, enforced as a pipeline gate | Add metrics and alert thresholds |
| managed | Quantitatively tracked, alerts on deviation | Close the feedback loop |
| optimizing | Continuous improvement from metrics | Maintain and evolve |
Use the matrix UI's Assess mode (⊕ Assess in the header) to self-rate each control and export a JSON assessment. Or query the maturity data directly:
// Find controls where your org might be at initial but target is defined+
const MATURITY = ['none','initial','developing','defined','managed','optimizing'];
dataset.controls
.filter(c => MATURITY.indexOf(c.maturity?.target) >= MATURITY.indexOf('defined'))
.map(c => ({
id: c.id,
name: c.name,
target: c.maturity.target,
steps: c.maturity.notes,
}));
// Assessment export schema (from UI export)
{
"schema": "apeiris://model/assessment/v1",
"generated_at": "2026-06-26T...",
"summary": {
"total_controls": 54,
"assessed": 42,
"pct_complete": 78,
"controls_at_target": 8
},
"controls": [{
"id": "LI-01",
"industry_baseline": "initial",
"target": "defined",
"self_assessed": "developing",
"gap_to_target": 1,
"advance_note": "Achieving 'defined' requires integrating hash..."
}]
}
Controls reference related controls in other Apeiris domains via
cross_domain.references[] using stable apeiris:// URIs.
These URIs are permanent and never reused.
// Resolve an apeiris:// URI to find the domain
function parseApeiriUri(uri) {
const m = uri.match(/^apeiris:\/\/([^/]+)\/controls\/([A-Z]{2}-\d{2})$/);
if (!m) return null;
return { domain: m[1], id: m[2] };
}
// Cross-domain links for a control
const li01 = dataset.controls.find(c => c.id === 'LI-01');
const refs = li01.cross_domain?.references ?? [];
refs.forEach(uri => {
const loc = parseApeiriUri(uri);
console.log(`Related: ${loc?.id} in ${loc?.domain}`);
});
apeiris-control-core/namespace-registry.json.
model domain owns prefixes LI, TG, EV, OA, BH, CR.
security domain owns IA, EC, PT, GV, RT, AS.
Short IDs are display-only; canonical IDs are the durable reference.
This matrix is a knowledge domain and evidence framework, not a runtime interceptor. It documents what must be evaluated, by which method, with what evidence — it does not execute the evaluation. The Apeiris platform executes against these controls; the controls define what counts as evidence.
apeiris:// URIs, so they compose without duplication.
What this matrix does not do: It does not intercept model outputs in real time, run a Z3 theorem prover, host an adversarial red-teaming pipeline, or enforce access controls. Those are Apeiris platform capabilities. The controls document what those capabilities must verify and what evidence they must produce — that is the contract between the matrix and the platform.
The shared evidence architecture uses apeiris:// URIs so one verifier's
evidence artifacts can be consumed by another without re-running the same control.
Every production build is signed with an Ed25519 key. The manifest at
/integration/release-manifest.json carries a SHA-256 content hash of the
dataset and an Ed25519 signature over that hash. The public key is published at
/.well-known/apeiris-release.pub. Local and CI builds without the private
key produce an unsigned manifest (signature: null).
Verification is a three-step chain: (1) verify the Ed25519 signature
over content_hash using the published public key,
(2) trust the content_hash value, and
(3) compare dataset.meta.content_hash to the manifest's
content_hash to confirm the downloaded dataset has not been altered.
// Full verification — browser (Web Crypto API) or Node.js equivalent
async function verifyDataset() {
// Step 1 — fetch manifest and (optionally) the public key in parallel
const [manifest, pubKeyPem] = await Promise.all([
fetch('https://modelverifier.ai/integration/release-manifest.json').then(r => r.json()),
fetch('https://modelverifier.ai/.well-known/apeiris-release.pub').then(r => r.text()),
]);
// Step 2 — verify Ed25519 signature (fails closed on any error)
if (!manifest.signature?.value) {
throw new Error('Manifest is unsigned — reject for high-assurance use');
}
const pemBody = pubKeyPem.replace(/-----[^-]+-----/g, '').replace(/\s+/g, '');
const spkiBuf = Uint8Array.from(atob(pemBody), c => c.charCodeAt(0));
const sigBuf = Uint8Array.from(atob(manifest.signature.value), c => c.charCodeAt(0));
const msgBuf = new TextEncoder().encode(manifest.artifacts[0].content_hash);
const key = await crypto.subtle.importKey(
'spki', spkiBuf, { name: 'Ed25519' }, false, ['verify']
);
const valid = await crypto.subtle.verify('Ed25519', key, sigBuf, msgBuf);
if (!valid) throw new Error('Ed25519 signature verification failed');
// Step 3 — fetch dataset and compare hash
const artifact = manifest.artifacts.find(a => a.artifact_id === 'model-controls-full.json');
const { dataset } = await fetch(artifact.url).then(r => r.json());
if (artifact.content_hash !== dataset.meta.content_hash) {
throw new Error(
`Hash mismatch: manifest=${artifact.content_hash} dataset=${dataset.meta.content_hash}`
);
}
console.log('✓ Signature valid. ✓ Dataset integrity confirmed.', {
signed_at: manifest.signature.signed_at,
content_hash: artifact.content_hash,
controls: dataset.controls.length,
version: dataset.meta.version,
});
return dataset;
}
Public key (Ed25519 SPKI/PEM):
https://modelverifier.ai/.well-known/apeiris-release.pub
Browser compatibility: Ed25519 in Web Crypto is supported
in Chrome 113+, Firefox 130+, and Safari 17+. For Node.js verification, replace
crypto.subtle calls with the node:crypto
verify(null, msgBuf, pubKey, sigBuf) API.
The private key is stored as GitHub Actions secret MODEL_VERIFIER_SIGNING_KEY
and is never committed to the repository.
CC BY-NC 4.0 — non-commercial use, attribution required. Commercial licensing: apeiris.ai.
apeiris://model/claims/v1) is an open format for AI assurance attestation. Claim objects produced using this schema are owned by the producing organization and not subject to this dataset's CC BY-NC 4.0 license.
An evidence claim is a machine-readable attestation object that links a specific assertion about a deployed AI model — "this model blocks 97% of adversarial injection attempts" — to the test that produced it, the artifacts that prove it, and the regulatory obligations it satisfies. Claims are produced by the model operator, deployer, or an independent auditor; consumed by the Apeiris verifier to construct an attestation graph across all controls.
The claim graph is what turns the Control Matrix from a checklist into an attestation platform.
Each claim record binds a control_ref (e.g., EV-04) to an
observed_result, a structured decision, one or more
evidence_artifacts with content hashes, and an obligation_links
array that maps directly to EU AI Act provisions, SR 26-2 sections, or other regulatory
requirements. Claims expire (expires_at) and must be re-validated on a defined
cadence — enabling automated compliance freshness checks.
| Field | Type | Description |
|---|---|---|
| schema | string (const) | Always apeiris://model/claims/v1 |
| claim_id | string (URI) | Globally unique apeiris:// URI for this claim, e.g. apeiris://model/claims/EV-04/injection-resistance |
| claim | string | Human-readable, falsifiable statement of what is being claimed |
| control_ref | string | Control ID this claim tests (e.g., EV-04, TG-01) |
| control_name | string | Human-readable name of the control |
| layer | enum | LI / TG / EV / OA / BH / CR |
| test_method | string | How the test was conducted (e.g., adversarial_probe_suite, independent_audit) |
| test_method_version | string (opt.) | Version of the test methodology or tooling |
| threshold | string | Pass criterion against which the result is evaluated |
| observed_result | string | What the test actually found |
| confidence | enum | high | medium | low |
| evidence_artifacts[] | array | Each artifact carries: artifact_id, artifact_type, description, location, hash (sha256:…), collected_at |
| obligation_links[] | array | Each entry: obligation_instrument, provision, jurisdiction, actor_role — maps the claim to the regulatory obligation it helps satisfy |
| assurance_target | object | model_provider, model_id, deployment_context, use_case — identifies what is being attested |
| tested_by | enum | internal | independent-auditor | automated-pipeline |
| tested_at | date-time | When the test was performed |
| expires_at | date-time | When this claim must be re-validated |
| decision | enum | pass | fail | inconclusive | conditional-pass |
| decision_rationale | string | Why this decision was reached, referencing the threshold and observed result |
| claim_version | string | Version of this claim record (increment on re-evaluation) |
| produced_by | string | Tool or system that produced this claim |
Claims link to controls via control_ref: the value must match a control
id in the dataset (e.g., EV-04). The canonical cross-domain identifier
apeiris://model/controls/EV-04 can be used in claim_id paths to make
the linkage machine-navigable. Claims link to regulatory obligations via obligation_links[]
using the same framework keys as the matrix (eu_ai_act, sr262, nist_rmf,
etc.) plus explicit provision references — enabling automated gap analysis against an obligation inventory.
Claims are produced by the operator or auditor and consumed by the verifier. The verifier does not produce claims itself — it evaluates whether existing claims are current, sufficient, and consistent with the matrix's control definitions and evidence requirements.
Fetch the 5-claim example file:
https://modelverifier.ai/integration/model-claims-example.json
Fetch the JSON Schema (Draft-07):
https://modelverifier.ai/integration/claim.schema.json
// Fetch and validate a claim graph
const { claims } = await fetch(
'https://modelverifier.ai/integration/model-claims-example.json'
).then(r => r.json());
// Find all passing EV-layer claims that cover eu_ai_act obligations
const evEuPassing = claims.filter(c =>
c.layer === 'EV' &&
c.decision === 'pass' &&
c.obligation_links.some(o => o.obligation_instrument === 'eu_ai_act')
);
// Check for expired claims that need re-validation
const now = new Date();
const expired = claims.filter(c => new Date(c.expires_at) < now);
if (expired.length) {
console.warn(`${expired.length} claim(s) require re-validation`,
expired.map(c => c.claim_id));
}
Full example — EV-04 injection resistance claim:
{
"schema": "apeiris://model/claims/v1",
"claim_id": "apeiris://model/claims/EV-04/injection-resistance",
"claim": "The model blocks >= 95% of adversarial prompt injection attempts across the approved probe suite.",
"control_ref": "EV-04",
"control_name": "Adversarial Testing & Red-Team Evaluation",
"layer": "EV",
"test_method": "adversarial_probe_suite",
"test_method_version": "apeiris-probe-suite-v3.1.0",
"threshold": ">= 95% block rate over minimum 1,000 adversarial probes",
"observed_result": "97.2% block rate over 1,000 adversarial probes",
"confidence": "high",
"evidence_artifacts": [{
"artifact_id": "ev04-probe-report-2026-q2",
"artifact_type": "test_report",
"description": "Adversarial probe report: 1,000 injection attempts, per-category breakdown.",
"location": "s3://acme-ai-evidence/ev04/probe-report-2026-q2.json",
"hash": "sha256:a3f8c1d94e2b57f0...",
"collected_at": "2026-06-01T14:30:00Z"
}],
"obligation_links": [
{ "obligation_instrument": "eu_ai_act", "provision": "Article 9", "jurisdiction": "eu", "actor_role": "deployer" },
{ "obligation_instrument": "eu_ai_act", "provision": "Article 15", "jurisdiction": "eu", "actor_role": "deployer" },
{ "obligation_instrument": "aisvs", "provision": "LLM-2.1", "jurisdiction": "global", "actor_role": "deployer" }
],
"assurance_target": {
"model_provider": "anthropic",
"model_id": "claude-sonnet-4-20260601",
"deployment_context": "production-eu-west-1 — customer support automation",
"use_case": "Enterprise customer support with CRM read API access"
},
"tested_by": "independent-auditor",
"tested_at": "2026-06-01T17:45:00Z",
"expires_at": "2026-12-01T00:00:00Z",
"decision": "pass",
"decision_rationale": "97.2% exceeds 95% threshold across all attack categories. Independent auditor confirmed.",
"claim_version": "1.0.0",
"produced_by": "modelverifier.ai"
}