Governance framework control map
Mapping date: 2026-10-27. This page maps the controls mcp-devtools already
implements to three external AI governance frameworks: the NIST AI Risk
Management Framework 1.0, ISO/IEC 42001:2023 Annex A, and the EU AI Act
(Regulation (EU) 2024/1689). Each row names the requirement, the mechanism
that serves it, the test that locks the mechanism, and what the gateway
leaves to someone else.
The gateway is a technical control, not an AI system and not a management system. It governs requests between agents, tools and model providers. It helps an organization meet a requirement; it never meets one alone. A row here is evidence for an auditor or an assessor, not a certification, a conformity assessment, or legal advice. Whether the EU AI Act applies, and in which role, depends on how the deployer’s own AI system is classified.
Rows cover only requirements the gateway contributes to. Requirements it cannot serve, such as fairness testing, model validation and training-data governance, are listed under What this map does not claim.
Read this with the OWASP MCP Top 10 assessment, which maps the same controls to MCP security risks, and the threat model, which explains each mechanism. Controls are “implemented” in the assessment’s sense: code and regression evidence exist. A control is active only in a deployment that turns it on; the shared deployment checklist lists the settings.
How the evidence is kept honest
Section titled “How the evidence is kept honest”Every test name in backticks on this page, in the OWASP assessment, the threat
model, the best-practices map, the shared deployment checklist and the
incident response runbook must resolve to a test in the repository. docs_evidence_tests::cited_tests_resolve_in_the_security_documents
fails CI when a cited test is renamed or removed, so a claim the code no
longer backs cannot stay on this page silently.
docs_evidence_tests::every_framework_map_row_names_a_locking_test fails
when a row in the tables below has no test in its test column.
Write a test reference as its suite and name, for example
revocation_tests::revoke_all_refuses_tokens_issued_before_the_cutoff_and_closes_their_sessions.
A following ::a_revoked_subject_is_refused_within_a_poll_and_the_refusal_is_journaled
reuses the suite named before it in the same document. Unit tests take their
module path, for example
telemetry::otlp::tests::spans_carry_verbatim_ids_and_flattened_attributes.
A bare suite name such as flow_policy_tests must name a test target or
module. A bare name of five or more words must still exist in the source; a
repository path must exist.
NIST AI RMF 1.0
Section titled “NIST AI RMF 1.0”Subcategory text is from the NIST AI RMF Playbook. The four functions are Govern, Map, Measure and Manage.
| Subcategory | Mechanism | Locking test | Residual and owner |
|---|---|---|---|
| GOVERN 1.1: legal and regulatory requirements are understood, managed and documented | This map and the OWASP assessment pair each requirement with a control and its test; the evidence test keeps the pairing current | docs_evidence_tests::cited_tests_resolve_in_the_security_documents |
Legal interpretation of each requirement belongs to the organization’s counsel |
| GOVERN 1.4: risk management is established through transparent policies and controls | Signed policy-as-code (YAML or native Cedar) with default deny; under an enforcing policy an unclassified call is always denied; signed generations bind policy and revocation together; policy explain names the deciding rule |
policy_signing_tests::a_verifying_key_refuses_unsigned_and_missigned_documents, policy_engine_tests::golden_decision_table, authorization_generation_tests::a_replayed_older_generation_cannot_unrevoke_anyone, policy_explain_tests::explain_names_the_decisive_rule_and_the_first_key_every_other_rule_fails |
Policy content is the policy author’s; a broad allow rule grants broad authority |
| GOVERN 1.5: ongoing monitoring and periodic review of the risk management process | Every policy change is journaled before it takes effect; the access review report lists every rule that applies to every member | policy_signing_tests::a_change_is_journaled_before_it_takes_effect_and_rejections_once, audit_report_tests::access_review_lists_every_rule_that_applies_to_every_member |
Review cadence and the reviewers are the organization’s. Group membership comes from supplied snapshots, not a live identity-provider fetch |
| GOVERN 1.6: mechanisms to inventory AI systems | Inventory of what this server fronts: the golden-locked tool surface, live sessions, and the models rules that name each reachable model |
tool_surface_parity_tests::tool_surface_matches_golden, admin_api_tests::session_inventory_lists_and_closes_real_rmcp_sessions, policy_engine_tests::schema_v3_models_rules_decide_inference_requests |
Inventory of other servers and shadow AI across the estate is organizational (OWASP MCP09) |
| GOVERN 1.7: decommissioning and phasing out AI systems safely | Revoking a subject, or every token issued before a cutoff, closes their sessions; artifact purge removes stored results; withdrawing a models rule removes model access |
revocation_tests::revoke_all_refuses_tokens_issued_before_the_cutoff_and_closes_their_sessions, admin_api_tests::artifact_purge_uses_real_pin_aware_backend_and_fails_closed |
Vendor credential rotation and model provider contract termination are the organization’s |
| GOVERN 2.1: roles, responsibilities and lines of communication are documented | Separation of duties in code: a policy publish and a held call each need a second person of the same tenant, with a fresh token; scopes separate administration, tool calls and inference | unified_approvals_tests::required_defers_a_generation_publish_until_a_second_administrator_approves, unified_call_approvals_tests::self_approval_other_tenants_rejection_and_stale_tokens_are_refused |
Needs MCP_ADMIN_APPROVALS=required and MCP_CALL_APPROVALS=required; both default to off. The operator roles table names eight roles and what the gateway enforces for each; author, approvers and online revoker share mcp:admin, so keeping them with different people, and assigning people at all, is organizational |
| GOVERN 3.2: roles for human-AI configurations and oversight are defined | require_approval rules state which actions need a human; the call approval gate holds them until a second person approves the exact call |
unified_call_approvals_tests::held_call_runs_once_after_approval_and_reissue_in_journal_order, policy_explain_tests::explain_labels_approval_explicitly |
Which actions warrant oversight is the policy author’s choice |
| GOVERN 4.3: practices enable AI testing, incident identification and information sharing | Content findings, denials and holds are journal records; SIEM forwarding gives a second copy in real time; adversarial tests cover steered follow-up calls and multi-step workflows across sessions and paths. Evaluation-only: the pinned SDK smoke checks one workflow through both gateway paths with isolated credentials/configuration, bounded processes, content-addressed trial manifests and explicit terminal evidence before destination-based verdicts; incomplete trials never contribute negative attack results (runtime_tests::runtime_refusal_requires_terminal_gateway_and_destination_evidence, runtime_tests::cancelled_trial_has_a_manifest_and_no_negative_attack_result). |
audit_report_tests::content_findings_export_without_text, audit_forwarding_tests::a_tool_calls_intent_and_outcome_reach_a_splunk_collector_from_the_real_journal, prompt_injection_tests::injected_instructions_cannot_make_a_denied_slack_write_reach_slack, adversarial_workflow_tests::prod_logs_read_in_one_session_cannot_leave_through_another, runtime_tests::runtime_routes_both_paths_under_one_owner_with_isolated_credentials_and_tools, runtime::tests::cancellation_timeout_and_leader_exit_kill_owned_descendants |
No live-model baseline: the provider is scripted; D2–D5 remain open. The incident response runbook maps each signal to a first step and a containment action; running it is organizational. Whether an agent follows injected instructions is assessed by the agent harness owner. Linux host permission is scoped to a root-owned runner-group helper; SDK qualification remains pending, and jobs sharing that account share the permission. |
| GOVERN 6.1: policies address AI risks from third-party entities | Model providers are reached only under models rules with the server’s own credential; the caller’s bearer never reaches them. Dependencies are exact-pinned and gated by cargo deny, including the fuzz and evaluation crates’ lockfiles, and Dependabot proposes weekly updates; cryptography, TLS and zstd advisories are remediated and Askama config parsing is disabled to remove unmaintained basic-toml; the WAF image is pinned by digest on every deployment path |
inference_role_tests::client_bearer_never_reaches_upstream, inference_role_tests::model_rule_denies_before_any_upstream_request, operations_tests::every_deployment_path_pins_the_same_waf_image, binary_tests::fuzz_lock_resolves_shared_crates_to_root_versions, binary_tests::eval_lock_resolves_shared_crates_to_root_versions |
Provider terms, intellectual-property risk and vendor permissions are the organization’s. The gateway image and the Dockerfile base images are pinned by tag, not digest |
| GOVERN 6.2: contingency processes for failures in third-party AI systems | A provider failure mid-stream is one failed attempt, never replayed; a guard that cannot inspect follows the rule’s on_error, deny by default |
inference_role_tests::partial_stream_failure_is_one_failed_attempt_not_a_replay, content_guard_tests::guard_error_denies_by_default_and_labels_when_configured |
No failover to an alternate provider |
| MAP 4.2: internal risk controls for components, including third-party AI, are documented | Per-vendor resource rules, the egress chokepoint that re-authorizes the actual outbound request, and environment classes on each upstream | egress_hold_tests::later_denial_outranks_an_earlier_hold, policy_engine_tests::contractors_prod_deny_matches_database_operations |
Extractors do not understand every vendor operation; unclassified calls are denied |
| MEASURE 2.4: functionality and behavior are monitored in production | Usage rollups for allowed, denied and held calls; metadata-only OTLP telemetry; five Grafana dashboards provisioned by the Compose observability overlay in deploy/inference/, not locked by a test; the console usage page |
usage_metrics_tests::usage_rows_reach_the_sqlite_rollups_for_allowed_and_denied_calls, rollup_store_tests::held_calls_are_separate_from_denials_in_every_rollup, telemetry::otlp::tests::spans_carry_verbatim_ids_and_flattened_attributes |
No alert rules are provisioned; rules and thresholds are the operator’s. Model quality and drift are the provider’s |
| MEASURE 2.7: security and resilience are evaluated and documented | The threat model and OWASP assessment; fuzzed parsers over attacker-controlled bytes; the token validator’s negative matrix; multi-step adversarial workflows, each shown to fail without its control; optional local classifier verifies cached artifacts, warms up before readiness, bounds inputs and preserves policy error handling; explicitly selected trained ONNX profile has a curated CPU evaluation. Explicit ONNX CUDA and CPU-node fallback selection refuse provider-loss downgrade and execution retry (test_onnx_gpu.py::test_session_provider_and_fallback_contract); missing CUDA refuses before fetching (test_onnx_gpu.py::test_unavailable_cuda_refuses_before_artifact_fetch). Actual CUDA kernel placement, parity, latency and VRAM require opt-in hardware qualification. Local guard supervision adds liveness/heartbeat readiness, capped lifetime recovery, fresh artifact verification/warmup and cancellation-safe process-group cleanup; no subject replay or error-policy change. The excluded scripted evaluation consumer checks one paired workflow on both paths; its shared dependency lock has a drift test and separate advisory gate. Evaluation-only: the pinned SDK smoke checks one workflow through both gateway paths with isolated credentials/configuration, bounded processes, content-addressed trial manifests and explicit terminal evidence before destination-based verdicts; incomplete trials never contribute negative attack results (runtime_tests::runtime_refusal_requires_terminal_gateway_and_destination_evidence, runtime_tests::cancelled_trial_has_a_manifest_and_no_negative_attack_result). |
token_validator_tests::the_negative_matrix, prompt_text_invariants_tests, sse_scanner_invariants_tests, adversarial_workflow_tests::confluence_injection_cannot_carry_its_planted_credential_into_a_write, test_local_guard.py::test_cache_tampering_refuses_offline_and_repairs_online, test_local_guard.py::test_window_limit_fails_instead_of_truncating, test_real_model.py::test_trained_cold_download_http_and_offline_reuse, inference_guard_tests::trained_local_model_gateway_preserves_policy_actions_and_failures, test_supervision.py::test_idle_crash_recovers_then_exhausts_lifetime_budget, test_supervision.py::test_cancellation_during_spawn_joins_and_reaps_child, inference_guard_tests::supervised_local_guard_failures_preserve_gateway_policy, workflow_tests::paired_runbook_workflow_proves_containment_and_benign_completion, binary_tests::eval_lock_resolves_shared_crates_to_root_versions, runtime_tests::runtime_routes_both_paths_under_one_owner_with_isolated_credentials_and_tools, runtime::tests::cancellation_timeout_and_leader_exit_kill_owned_descendants |
No live-model baseline: the provider is scripted; D2–D5 remain open. This is a source and test review, not a penetration test. Production model quality, GPU execution and native-runtime containment require operator validation; the small curated CPU corpus is not a deployment qualification. The systemd dedicated-account/credential/cgroup example requires host staging qualification, especially supervisor SIGKILL/OOM and escaped descendants. CUDA qualification now binds warmup placement to the actual worker PID and checks no replay under owned-worker faults; host selection and partial-result retention are synthetic-tested (test_onnx_gpu.py::test_qualification_harness_on_synthetic_cpu_graph, test_qualification.py::test_failed_fault_phase_preserves_completed_evidence). NVIDIA hardware and disruptive staging tests remain unverified; see qualification record. Linux host permission is scoped to a root-owned runner-group helper; SDK qualification remains pending, and jobs sharing that account share the permission. |
| MEASURE 2.8: transparency and accountability risks are examined | Every call’s intent is durable before dispatch and names the principal from the validated token; a hash chain and signed checkpoints make edits detectable | audit_journal_tests::intent_with_upstream_identity_is_journaled_before_dispatch_and_outcome_after, inbound_auth_tests::valid_token_reaches_the_tool_and_its_principal_reaches_the_journal, audit_checkpoint_tests::the_verifier_catches_edits_forgeries_wrong_keys_and_a_truncated_tail |
Checkpoints prove nothing against a host that controls every retained copy; keep one off the host |
| MEASURE 2.10: privacy risk is examined and documented | Content rules inspect arguments, results, prompts and completions; journal records hold findings, never text; once an owner has read a data class, flow rules deny that owner the vendors or prompts a rule names; the data map holds classes, never values | inference_guard_tests::sensitive_values_never_reach_storage_or_logs, flow_policy_tests::prod_read_on_mcp_then_prompt_on_v1_is_denied_in_one_process, admin_api_tests::data_map_is_bound_to_the_callers_tenant |
Built-in detectors are credential-shaped; personal-data detection needs an external engine. No field-level masking of query results. Flow marks are per process, in memory and expire (24 hours by default), so a restart forgets them and enforcement assumes a single replica |
| MEASURE 3.1: existing, unanticipated and emergent risks are tracked | Grouped observed activity and policy drafts generated from it; the data map shows which classes reached which subjects and models | activity_groups_tests::a_draft_from_an_observed_group_compiles_and_matches_only_what_was_observed, rollup_store_tests::data_map_groups_classes_per_subject_and_model |
Deciding which drafts become policy is the author’s |
| MANAGE 1.3: responses to high-priority risks are developed and documented | Rule actions deny, hold, label or redact; run budgets reserve at admission and deny or hold when exceeded | content_guard_tests::hold_action_routes_to_approval_and_reissue_must_match_findings, run_budget_tests::token_budget_denies_at_admission_when_the_estimate_does_not_fit |
Accepting or transferring a risk is an organizational decision |
| MANAGE 2.3: procedures respond to and recover from a previously unknown risk | A new signed generation takes effect atomically; a revoked subject is refused within one poll and the refusal is journaled | authorization_generation_tests::both_halves_take_effect_together_and_only_under_a_newer_manifest, revocation_tests::a_revoked_subject_is_refused_within_a_poll_and_the_refusal_is_journaled |
The incident response runbook is the written procedure: detect, triage, contain, preserve evidence, recover, learn, with a drill on the demo stack. Containment that needs revocation waits for the policy key holder; automation cannot revoke (issues #199, #200) |
| MANAGE 2.4: mechanisms to supersede, disengage or deactivate AI systems | Revocation refuses a subject on both /mcp and /v1/* and keeps its taint; removing a models rule stops model access before any upstream request |
revocation_tests::revoked_subject_is_refused_on_both_paths_and_keeps_its_taint, inference_role_tests::model_rule_denies_before_any_upstream_request |
Deactivating the model itself is the provider’s |
| MANAGE 3.1: third-party AI risks are monitored and controls applied | The model provider is an egress destination on every request; provider-reported usage is recorded, or unknown, never zero |
inference_role_tests::inference_upstream_is_an_egress_destination, inference_role_tests::openai_stream_without_usage_records_unknown_not_zero |
Provider-side monitoring is the provider’s |
| MANAGE 4.1: post-deployment monitoring, override, decommissioning, incident response and change management | Monitoring as in MEASURE 2.4; override through approval holds; change management through second-person approval of generations, with a superseded generation refused | unified_approvals_tests::a_superseded_generation_cannot_be_approved, unified_console_tests::console_proposals_enforce_separation_freshness_and_durable_idempotent_apply |
User feedback and appeal channels belong to the application |
| MANAGE 4.3: incidents are communicated and tracked | The activity export and the SIEM forwarder carry every intent and outcome as evidence | audit_report_tests::activity_export_flattens_every_record_and_filters, audit_forwarding_tests::shipper_forwards_every_record_in_order_and_persists_the_cursor |
The incident response runbook produces a verified evidence bundle for the incident record. Communication to affected parties is organizational |
ISO/IEC 42001:2023 Annex A
Section titled “ISO/IEC 42001:2023 Annex A”Control titles are as published in Annex A. The normative text is in the standard itself, available from ISO.
| Control | Mechanism | Locking test | Residual and owner |
|---|---|---|---|
| A.2.2 AI policy; A.2.4 Review of the AI policy | The technical part of the AI policy is a signed policy document; each change is journaled before it applies and can require a second administrator | policy_signing_tests::a_change_is_journaled_before_it_takes_effect_and_rejections_once, unified_approvals_tests::required_defers_a_generation_publish_until_a_second_administrator_approves |
The written AI policy and its review cycle are the organization’s |
| A.3.2 AI roles and responsibilities | Scopes separate administration, tool calls and inference; an approval needs a validated token whose subject differs from the requester’s, in the same tenant | unified_call_approvals_tests::self_approval_other_tenants_rejection_and_stale_tokens_are_refused |
The operator roles table names the roles and maps them to scopes, the policy key and approval settings; staffing them is organizational. The identity provider must issue one subject per person, since a second identity of the same person passes |
| A.4.2 Resource documentation; A.4.4 Tooling resources | The tool surface is golden-locked; every setting is documented and the console catalog is generated from that documentation | tool_surface_parity_tests::tool_surface_matches_golden, configuration::tests::catalog_matches_the_documented_settings |
Documentation of models and compute is the organization’s |
| A.5.2 AI system impact assessment process | Evidence input only: the data map, the access review and grouped activity show what reached whom | rollup_store_tests::data_map_groups_classes_per_subject_and_model, audit_report_tests::access_review_lists_every_rule_that_applies_to_every_member |
The assessment itself is organizational |
| A.6.2.5 AI system deployment | Startup refuses an unsafe configuration: a non-loopback bind without inbound authentication, or a manifest that does not bind its files; optional local classifier requires eligible hardware/format, verified artifacts and model warmup before readiness; the trained ONNX profile pins every artifact with SHA-256. Explicit ONNX CUDA and CPU-node fallback selection refuse provider-loss downgrade and execution retry (test_onnx_gpu.py::test_session_provider_and_fallback_contract); missing CUDA refuses before fetching (test_onnx_gpu.py::test_unavailable_cuda_refuses_before_artifact_fetch). Actual CUDA kernel placement, parity, latency and VRAM require opt-in hardware qualification. Local guard supervision adds liveness/heartbeat readiness, capped lifetime recovery, fresh artifact verification/warmup and cancellation-safe process-group cleanup; no subject replay or error-policy change. Evaluation-only: the pinned SDK smoke checks one workflow through both gateway paths with isolated credentials/configuration, bounded processes, content-addressed trial manifests and explicit terminal evidence before destination-based verdicts; incomplete trials never contribute negative attack results (runtime_tests::runtime_refusal_requires_terminal_gateway_and_destination_evidence, runtime_tests::cancelled_trial_has_a_manifest_and_no_negative_attack_result). |
startup_security_tests::non_loopback_bind_without_auth_is_refused_with_a_clear_reason, authorization_generation_tests::a_starting_gateway_refuses_a_manifest_that_does_not_bind_its_files, test_local_guard.py::test_no_gpu_never_downloads_non_onnx, test_local_guard.py::test_real_onnx_download_warmup_windows_and_offline_restart, test_evaluation.py::test_reviewed_profiles_pin_every_file_with_sha256, test_real_model.py::test_actual_no_gpu_probe_never_fetches_safetensors, test_supervision.py::test_idle_crash_recovers_then_exhausts_lifetime_budget, test_supervision.py::test_cancellation_during_spawn_joins_and_reaps_child, inference_guard_tests::supervised_local_guard_failures_preserve_gateway_policy, runtime_tests::runtime_routes_both_paths_under_one_owner_with_isolated_credentials_and_tools, runtime::tests::cancellation_timeout_and_leader_exit_kill_owned_descendants |
No live-model baseline: the provider is scripted; D2–D5 remain open. Release approval is the organization’s. Trained-model suitability and GPU qualification remain operator validation. The systemd dedicated-account/credential/cgroup example requires host staging qualification, especially supervisor SIGKILL/OOM and escaped descendants. CUDA qualification now binds warmup placement to the actual worker PID and checks no replay under owned-worker faults; host selection and partial-result retention are synthetic-tested (test_onnx_gpu.py::test_qualification_harness_on_synthetic_cpu_graph, test_qualification.py::test_failed_fault_phase_preserves_completed_evidence). NVIDIA hardware and disruptive staging tests remain unverified; see qualification record. Linux host permission is scoped to a root-owned runner-group helper; SDK qualification remains pending, and jobs sharing that account share the permission. |
| A.6.2.6 Operation and monitoring | As NIST MEASURE 2.4. Explicit ONNX CUDA and CPU-node fallback selection refuse provider-loss downgrade and execution retry (test_onnx_gpu.py::test_session_provider_and_fallback_contract); missing CUDA refuses before fetching (test_onnx_gpu.py::test_unavailable_cuda_refuses_before_artifact_fetch). Actual CUDA kernel placement, parity, latency and VRAM require opt-in hardware qualification. Local guard supervision adds liveness/heartbeat readiness, capped lifetime recovery, fresh artifact verification/warmup and cancellation-safe process-group cleanup; no subject replay or error-policy change. |
usage_metrics_tests::usage_rows_reach_the_sqlite_rollups_for_allowed_and_denied_calls, telemetry::otlp::tests::spans_carry_verbatim_ids_and_flattened_attributes, test_supervision.py::test_idle_crash_recovers_then_exhausts_lifetime_budget, test_supervision.py::test_cancellation_during_spawn_joins_and_reaps_child, inference_guard_tests::supervised_local_guard_failures_preserve_gateway_policy |
Alerting is the operator’s. The systemd dedicated-account/credential/cgroup example requires host staging qualification, especially supervisor SIGKILL/OOM and escaped descendants. |
| A.6.2.7 Technical documentation | Threat model, OWASP assessment, configuration reference and this map, kept current by tests | docs_evidence_tests::cited_tests_resolve_in_the_security_documents, configuration::tests::catalog_matches_the_documented_settings |
Documentation of the AI system the gateway fronts is its provider’s |
| A.6.2.8 Recording of event logs | Durable intent before dispatch and outcome after, for tool calls and inference requests, joined by an application event id; hash chain and signed checkpoints | audit_journal_tests::intent_with_upstream_identity_is_journaled_before_dispatch_and_outcome_after, audit_journal_tests::events_carry_application_event_id, audit_checkpoint_tests::the_verifier_catches_edits_forgeries_wrong_keys_and_a_truncated_tail |
Retention and off-host custody are the operator’s |
| A.7.5 Provenance of data | Each read’s upstream, resource and environment class is in its outcome record; a class a content rule labels becomes the owner’s taint | flow_policy_tests::labelled_secret_in_a_result_taints_the_owner_for_prompts, inference_role_tests::inference_upstream_is_an_egress_destination |
Provenance of training data is the model provider’s |
| A.8.2 System documentation and information for users | Tool descriptions are golden-locked; a refusal names the rule; policy explain shows how a call would be decided |
tool_surface_parity_tests::tool_surface_matches_golden, policy_explain_tests::explain_builds_the_context_a_real_call_is_journaled_with |
User-facing disclosure belongs to the application |
| A.8.4 Communication of incidents | The journal and SIEM forwarding are the evidence an incident report draws on | audit_forwarding_tests::shipper_forwards_every_record_in_order_and_persists_the_cursor |
The incident response runbook says which records an incident draws on and how to verify them; reporting is organizational |
| A.9.2 Processes for responsible use | Resource rules, content rules, approvals and flow rules enforce the use policy at every call | content_guard_tests::secret_in_issue_create_is_denied_with_zero_upstream_requests, flow_policy_tests::prod_read_then_jira_write_is_denied_for_the_same_owner |
Which uses are responsible is the organization’s decision |
| A.9.4 Intended use of the AI system | models rules confine which principals reach which models; budgets cap tokens and tool calls per owner or tenant |
policy_engine_tests::schema_v3_models_rules_decide_inference_requests, run_budget_tests::two_owners_cannot_over_reserve_one_tenant_budget |
Defining intended use is the organization’s. Budgets do not price usage: spend_usd is refused |
| A.10.2 Allocating responsibilities | Each row here and in the OWASP assessment names the component responsible for the residual | docs_evidence_tests::every_framework_map_row_names_a_locking_test |
Contracts that allocate responsibility are organizational |
| A.10.3 Suppliers | As NIST GOVERN 6.1 and MANAGE 3.1 | inference_role_tests::client_bearer_never_reaches_upstream, inference_role_tests::inference_upstream_is_an_egress_destination, binary_tests::eval_lock_resolves_shared_crates_to_root_versions |
Supplier selection and terms are the organization’s |
| A.10.4 Customers | Where customers are tenants: sessions, artifacts, caches and the data map are bound to the verified principal and tenant | principal_partitioning_tests::artifact_download_is_owner_only_and_cross_owner_is_404, unified_console_tests::data_map_is_tenant_scoped |
Customer commitments are the organization’s |
EU AI Act (Regulation (EU) 2024/1689)
Section titled “EU AI Act (Regulation (EU) 2024/1689)”Articles 9 to 15 bind providers of high-risk AI systems; Article 26 binds their deployers. The gateway is neither. It is a technical measure a provider can build into, or a deployer can operate around, a high-risk system. Article text is from the Official Journal.
| Article | Mechanism | Locking test | Residual and owner |
|---|---|---|---|
| Art. 9 Risk management system | Risks that the threat model identifies are treated by enforced controls: default-deny policy, content rules, flow rules and budgets; residual risks are stated per OWASP category | policy_engine_tests::flow_rule_denies_prompt_after_prod_read, content_guard_tests::secret_in_issue_create_is_denied_with_zero_upstream_requests |
The system-level risk management process is the provider’s |
| Art. 10 Data and data governance | Inference-time data only: once an owner has read a classified upstream, flow rules can deny that owner’s prompts. Training, validation and testing data never pass the gateway | flow_policy_tests::prod_read_on_mcp_then_prompt_on_v1_is_denied_in_one_process |
Training, validation and testing data governance is the provider’s. Flow marks are per process and expire |
| Art. 12(1) Automatic recording of events over the lifetime | Every tool call and inference request leaves a durable intent before dispatch and an outcome when it completes; a tool call whose intent cannot be journaled is refused, and the inference path refuses the same way | audit_journal_tests::failed_journal_write_refuses_the_call_and_never_contacts_the_vendor, audit_journal_tests::intent_with_upstream_identity_is_journaled_before_dispatch_and_outcome_after |
The gateway records the requests it sees, not the model’s internal events. An intent without an outcome does not prove there was no dispatch. No test yet locks the inference path’s refusal on a failed append |
| Art. 12(2)(a) Events relevant to identifying risk situations | Content findings, denials, approval holds and budget states are journal records with reasons | audit_report_tests::content_findings_export_without_text, run_budget_tests::budget_hold_routes_to_approval |
Deciding which situations present a risk under Art. 79(1) is the provider’s |
| Art. 12(2)(b) Post-market monitoring | The activity export, the metrics report and SIEM forwarding feed the provider’s monitoring | audit_report_tests::export_includes_inference_and_flow_rows, audit_report_tests::metrics_report_the_section_7_figures |
The post-market monitoring plan (Art. 72) is the provider’s |
| Art. 12(2)(c) Monitoring of operation under Art. 26(5) | Usage rollups, telemetry and the provisioned dashboards | usage_metrics_tests::usage_rows_reach_the_sqlite_rollups_for_allowed_and_denied_calls, telemetry::otlp::tests::known_usage_exports_each_count_as_an_integer |
Alert thresholds are the deployer’s |
| Art. 13 Transparency and information to deployers | The configuration reference, threat model and this map; policy explain shows the decision a call would get |
policy_explain_tests::explain_at_the_binary_boundary_builds_the_context_the_gateway_would, configuration::tests::catalog_matches_the_documented_settings |
Instructions for use of the AI system are its provider’s |
| Art. 14(4)(a) Monitor operation and detect anomalies | The console activity page renders journal rows; dashboards show failures, denials and cost | unified_console_tests::activity_page_renders_journal_rows_and_the_stopped_banner_shape, rollup_store_tests::held_calls_are_separate_from_denials_in_every_rollup |
Anomaly detection on model behaviour is not provided |
| Art. 14(4)(d) Decide not to use, disregard or override | require_approval holds an action until a second person approves the exact call; a denial sends nothing upstream |
unified_call_approvals_tests::hold_key_binds_body_and_subject_and_the_current_policy_decides_the_reissue, unified_call_approvals_tests::inference_hold_round_trip |
Holds need MCP_CALL_APPROVALS=required, which defaults to off. Overriding or reversing a model output after it reaches a person belongs to the application |
| Art. 14(4)(e) Intervene or interrupt through a stop procedure | Signed revocation of a subject or of every token before a cutoff, effective within one poll on both paths; session close | revocation_tests::revoked_subject_is_refused_on_both_paths_and_keeps_its_taint, revocation_tests::revoke_all_refuses_tokens_issued_before_the_cutoff_and_closes_their_sessions |
A request already relayed cannot be recalled. Revoke-all is tested on /mcp; on /v1/* only subject revocation is tested |
| Art. 15(4) Resilience to errors and faults | Fail closed: an unwritable journal refuses the call; with no cached keys, an unreachable key set refuses tokens until it recovers; a guard error denies by default; optional local classifier verifies cached artifacts, warms up before readiness, bounds inputs and preserves policy error handling; explicitly selected trained ONNX profile has a curated CPU evaluation. Explicit ONNX CUDA and CPU-node fallback selection refuse provider-loss downgrade and execution retry (test_onnx_gpu.py::test_session_provider_and_fallback_contract); missing CUDA refuses before fetching (test_onnx_gpu.py::test_unavailable_cuda_refuses_before_artifact_fetch). Actual CUDA kernel placement, parity, latency and VRAM require opt-in hardware qualification. Local guard supervision adds liveness/heartbeat readiness, capped lifetime recovery, fresh artifact verification/warmup and cancellation-safe process-group cleanup; no subject replay or error-policy change. |
audit_journal_tests::failed_journal_write_refuses_the_call_and_never_contacts_the_vendor, token_validator_tests::unreachable_jwks_fails_closed_and_recovers, test_local_guard.py::test_cache_tampering_refuses_offline_and_repairs_online, test_local_guard.py::test_window_limit_fails_instead_of_truncating, test_real_model.py::test_trained_cold_download_http_and_offline_reuse, inference_guard_tests::trained_local_model_gateway_preserves_policy_actions_and_failures, test_supervision.py::test_idle_crash_recovers_then_exhausts_lifetime_budget, test_supervision.py::test_cancellation_during_spawn_joins_and_reaps_child, inference_guard_tests::supervised_local_guard_failures_preserve_gateway_policy |
Cached signing keys keep validating during a key-set outage, by design. Model accuracy and robustness are the provider’s. Production model quality, GPU execution and native-runtime containment require operator validation; the small curated CPU corpus is not a deployment qualification. The systemd dedicated-account/credential/cgroup example requires host staging qualification, especially supervisor SIGKILL/OOM and escaped descendants. CUDA qualification now binds warmup placement to the actual worker PID and checks no replay under owned-worker faults; host selection and partial-result retention are synthetic-tested (test_onnx_gpu.py::test_qualification_harness_on_synthetic_cpu_graph, test_qualification.py::test_failed_fault_phase_preserves_completed_evidence). NVIDIA hardware and disruptive staging tests remain unverified; see qualification record. |
| Art. 15(5) Resilience against unauthorized third parties | Validated OIDC tokens, owner-bound sessions and artifacts, content rules on steered follow-up writes, fuzzed parsers, a default-on WAF; scripted paired containment evaluation and a separate dependency lock/advisory gate for that test consumer; the pinned runtime smoke adds credential/configuration isolation, process bounds, versioned trial manifests and corroborated terminal outcomes with a local scripted provider (runtime_tests::runtime_refusal_requires_terminal_gateway_and_destination_evidence) |
principal_partitioning_tests::a_session_is_bound_to_the_principal_that_initialized_it, prompt_injection_tests::injected_secret_in_tool_result_cannot_be_posted_by_follow_up_write, adversarial_workflow_tests::tool_result_secret_cannot_reach_a_model_even_encoded, operations_tests::every_shipped_proxy_runs_the_waf, workflow_tests::paired_runbook_workflow_proves_containment_and_benign_completion, binary_tests::eval_lock_resolves_shared_crates_to_root_versions, runtime_tests::runtime_routes_both_paths_under_one_owner_with_isolated_credentials_and_tools |
No live-model baseline or resistance score; D2–D5 remain open. Data poisoning, model poisoning and adversarial examples target the model and are the provider’s. Linux host permission is scoped to a root-owned runner-group helper; SDK qualification remains pending, and jobs sharing that account share the permission. |
| Art. 26(1) Use in accordance with instructions, with technical measures | Policy confines use to the models, tools and resources named in rules | inference_role_tests::model_rule_denies_before_any_upstream_request, policy_engine_tests::a_grant_naming_a_write_action_must_name_its_risk |
Following the provider’s instructions is the deployer’s |
| Art. 26(2) Human oversight assigned to competent people | The approver presents a validated, fresh token whose subject differs from the requester’s, in the same tenant | unified_call_approvals_tests::self_approval_other_tenants_rejection_and_stale_tokens_are_refused |
Competence, training and authority of overseers are the deployer’s. The identity provider must issue one subject per person; the gateway does not check that an approver is human |
| Art. 26(5) Monitor operation and suspend use | Monitoring as Art. 12(2)(c); suspension through revocation or by withdrawing the models rule |
revocation_tests::a_revoked_subject_is_refused_within_a_poll_and_the_refusal_is_journaled, inference_role_tests::model_rule_denies_before_any_upstream_request |
Serious-incident reporting to the provider and authorities is the deployer’s; the incident response runbook covers suspension (containment) and the evidence a report draws on |
| Art. 26(6) Keep logs for at least six months | The server never prunes the durable journal (MCP_AUDIT_JOURNAL_DIR). Signed checkpoints, which are proofs over the journal and not its records, export off the host; the cloud templates keep them in immutable storage, 365 days by default |
audit_checkpoint_tests::checkpoints_land_every_n_records_signed_and_exported_and_the_close_seals_the_tail, operations_tests::aws_fargate_template_preserves_the_deployment_constraints, operations_tests::azure_container_apps_template_preserves_the_deployment_constraints |
Keeping the journal itself for six months is the operator’s on every path: the AWS template backs it up for 35 days and the Azure template sets no retention. The cited tests check immutability, not the retention period |
What this map does not claim
Section titled “What this map does not claim”A gateway sees requests, not training, evaluation, or the application that shows an output to a person. The frameworks above ask for each function below; the gateway does not provide it, and the owner column says who does. The model provider trains and ships the model. The application is the deployer’s AI system that presents outputs to people. The organization is the deployer’s own policy, people and process. Where the EU AI Act assigns a duty to providers or deployers of high-risk systems, the owner follows that assignment.
| Non-claim | Where the frameworks ask | What the gateway does instead, and where it stops | Owner |
|---|---|---|---|
| Model validation and accuracy | NIST MEASURE 2.3 and 2.5; ISO A.6.2.4; EU AI Act Art. 15(1) and 15(3) | It records provider usage and can inspect content with built-in or optional local detectors; this does not evaluate factual correctness or trained-model accuracy. A denial or hold says nothing about whether an allowed completion is correct | Model provider; Organization for fitness to its own use |
| Model drift and performance monitoring | NIST MEASURE 2.4 and MANAGE 4.1, for model behaviour; ISO A.6.2.6 | It monitors requests: allowed, denied and held calls, latency and tokens (MEASURE 2.4 row). It measures nothing about output quality over time | Model provider |
| Bias and fairness testing | NIST MEASURE 2.11; EU AI Act Art. 10(2)(f) and (g) | Content rules match credential patterns, or what an external engine reports. Nothing examines outputs for demographic or other bias | Model provider; Organization for its impact assessment |
| Model cards and AI system documentation | EU AI Act Art. 11 and Annex IV, Art. 13; Art. 53(1)(a) and (b) for general-purpose AI model providers; ISO A.6.2.7 | It documents only itself (A.6.2.7 row): the threat model, configuration reference and this map | Model provider |
| Training, validation and testing data governance | EU AI Act Art. 10; ISO A.7.2 to A.7.6 for development data | Training data never passes the gateway. Flow rules govern data at inference time only (Art. 10 row); the A.7.5 row covers where a read came from, not training data | Model provider |
| Disclosure that people interact with AI or AI-generated content | EU AI Act Art. 50(1) and 50(4); Art. 50(3) for emotion recognition and biometric categorisation; Art. 26(7) and 26(11) | It is not in the user interface and adds nothing to what reaches a person | Application; Organization for informing workers and people subject to decisions |
| Content provenance and marking of generated output | EU AI Act Art. 50(2) | It relays a completion as the provider sent it, or stops it when a rule denies; completion rules cannot redact (inference path). It adds no watermark or machine-readable mark and removes none | Model provider |
| Explainability and interpretation of outputs | NIST MEASURE 2.9; EU AI Act Art. 13(3)(b)(iv) and (vii), Art. 14(4)(c), Art. 86 | policy explain explains the gateway’s decision on a request, not why the model produced an output |
Model provider for interpretability; Application for presenting it |
| Automation-bias awareness and AI literacy | EU AI Act Art. 14(4)(b) and Art. 4; NIST GOVERN 2.2 | An approval needs a second, verified subject (GOVERN 2.1 row). Whether that person understands the output or over-trusts it is outside the request | Organization; Application for in-product cues |
| Inventory of servers and AI systems it does not front | NIST GOVERN 1.6, for the rest of the estate; OWASP MCP09 | It inventories only what it fronts: its tool surface, sessions and models rules (GOVERN 1.6 row). A client with independently held credentials bypasses it |
Organization |
| Data loss prevention guarantee | NIST MEASURE 2.10 | Content inspection is enforcement with stated limits: probabilistic, credential-shaped by default, blind to base64 blocks and binary artifacts, unable to recall streamed bytes already relayed (data governance spec §10) | Organization, through a DLP or personal-data engine |
| Organizational duties | ISO A.2.2, A.3.3 and A.5; NIST GOVERN 2.3; EU AI Act Art. 27, 43, 49 and 73 | It supplies evidence (journal, export, data map, access review) to the impact assessment and incident report; it writes neither | Organization for the AI policy, impact and fundamental-rights assessments and concern reporting; Model provider for conformity assessment, registration and serious-incident reports (Art. 43, 49(1) and (2), 73), with public-authority deployers registering under Art. 49(3) |
Sources
Section titled “Sources”- NIST, Artificial Intelligence Risk Management Framework (AI RMF 1.0), NIST AI 100-1, January 2023, and its Playbook.
- ISO/IEC 42001:2023, Information technology — Artificial intelligence — Management system, Annex A.
- Regulation (EU) 2024/1689 (Artificial Intelligence Act), Articles 9 to 15 and 26, and for the non-claims Articles 4, 10, 11, 27, 43, 49, 50, 53, 73 and 86 with Annex IV, as originally published.