Threat-Framework Mapping
Asqav binds caller-supplied threat-and-control taxonomy mappings into the signed receipt via seven optional wire fields: mitre_techniques, mitre_atlas, owasp_llm_top10, nist_ai_rmf, iso_42001, eu_ai_act_articles, and rfc3161_timestamp. A server-set boolean framework_mappings_self_declared auto-flips to true whenever any of the six list fields is populated, so verifiers can tell self-declared classifications apart from cloud-verified ones.
What it binds: seven optional taxonomy and timestamp fields plus one server-set guard, all inside the same tamper-evident envelope as the action and the policy decision.
What it guarantees: the receipt was issued against THAT mapping, not a later mapping that papered over a missed control.
Where the line sits: the taxonomy ids are caller-supplied and preserved verbatim. Asqav signs the bytes. The producer asserts the semantics.
What is the threat-framework mapping 8-tuple?
Seven OPTIONAL caller-supplied fields plus one server-set guard on POST /api/v1/agents/{id}/sign:
| Field | Type | What it carries |
|---|---|---|
mitre_techniques | list of strings | MITRE ATT&CK technique ids (e.g. ["T1059", "T1078"]). Self-declared. |
mitre_atlas | list of strings | MITRE ATLAS ids for AI-system threats (e.g. ["AML.T0051", "AML.T0043"]). Self-declared. |
owasp_llm_top10 | list of strings | OWASP Top 10 for LLM ids (e.g. ["LLM01", "LLM02"]). Self-declared. |
nist_ai_rmf | list of strings | NIST AI RMF function ids and subcategories (e.g. ["GOVERN-1.1", "MEASURE-2.7"]). Self-declared. |
iso_42001 | list of strings | ISO/IEC 42001 control ids (e.g. ["A.6.2.6"]). Self-declared. |
eu_ai_act_articles | list of strings | EU AI Act article ids (e.g. ["Article-12", "Article-15"]). Self-declared. |
rfc3161_timestamp | string | Caller-supplied base64-encoded TimeStampResp (DER) preserved on the receipt for offline TSA chain verification. |
framework_mappings_self_declared | boolean | Server-set false-attestation guard. Auto-flips to true whenever any of the six list fields is populated. Verifiers display the caller-supplied label prominently. |
All seven caller-supplied fields are OPTIONAL on the wire. None is mandatory on any receipt_type. The cloud accepts each independently. Producers populate whichever taxonomies their compliance pipeline uses.
Why bind threat-framework mappings into the signed receipt?
A signed receipt without taxonomy mappings answers "did the agent perform action X under policy Y?". It does not answer "which regulatory or threat-framework control does this action map to?".
When a regulator or buyer asks for evidence of coverage against the NIST AI RMF or the EU AI Act, the answer must travel inside the audit chain, not in a separate spreadsheet. The 8-tuple keeps both questions inside the same tamper-evident envelope, so the audit chain does not branch.
Industry threat-and-control standards already cover the second question:
- MITRE ATT&CK is the canonical adversary-tactics-and-techniques knowledge base.
- MITRE ATLAS extends ATT&CK with AI-system-specific threats (data poisoning, model inversion, prompt injection).
- OWASP Top 10 for LLM Applications ranks the highest-impact application-level LLM threats.
- NIST AI Risk Management Framework (AI RMF 1.0) defines the GOVERN, MAP, MEASURE, MANAGE functions.
- ISO/IEC 42001:2023 is the international management-system standard for AI.
- EU AI Act establishes the harmonised legal framework for AI systems in the EU.
- RFC 3161 is the IETF time-stamping protocol that produces an independent third-party trusted timestamp.
Asqav's 8-tuple references each of those frameworks by id. The signed receipt becomes the entry point an auditor uses to recover the caller-declared mapping at audit time. The cryptographic binding guarantees the receipt was issued against THAT mapping, not a later mapping that papered over a missed control.
Self-declared, not Asqav-verified
The cloud does NOT validate that an owasp_llm_top10 value is a real OWASP id, that a nist_ai_rmf subcategory exists in the published framework, or that an eu_ai_act_articles entry maps to a real article. The values are caller-supplied and preserved verbatim.
To prevent false-attestation, the cloud auto-flips framework_mappings_self_declared=true whenever any of the six list fields is populated, even if the caller passes false. Verifiers display the self-declared label prominently so a downstream auditor knows the taxonomy entries came from the producer, not from Asqav.
The asymmetry mirrors the wire-evidence pattern already in use for executable_hash (caller-asserts the binary), slsa_provenance_pointer (caller-asserts the URL), and cve_inventory_digest (caller-asserts the inventory). Asqav signs the bytes. The producer asserts the semantics.
How does this combine with the rest of the receipt?
The 8-tuple is orthogonal to every other wire field. A decision receipt with full taxonomy binding looks like:
{
"action_type": "api:call",
"receipt_type": "protectmcp:decision",
"policy_decision": "permit",
"mitre_techniques": ["T1059", "T1078"],
"mitre_atlas": ["AML.T0051", "AML.T0043"],
"owasp_llm_top10": ["LLM01", "LLM02"],
"nist_ai_rmf": ["GOVERN-1.1", "MEASURE-2.7"],
"iso_42001": ["A.6.2.6"],
"eu_ai_act_articles": ["Article-12", "Article-15"],
"rfc3161_timestamp": "MIIGgzADAgEAMIIGegYJKoZIhvcNAQcCoIIGazCCBmcCAQMxDTALBglghkgBZQMEAgE=",
"framework_mappings_self_declared": true
}
The signed envelope binds every wire field. A verifier who later recovers the receipt cannot mutate any of the eight values without breaking the ML-DSA signature.
Field constraints
A malformed value is rejected with HTTP 422 and a machine-readable error code:
- Each of the six taxonomy list fields, when provided, MUST be a non-empty list of strings. Each entry MUST be a non-empty string up to 128 chars. The error codes are
<field>_must_be_non_empty_listand<field>_entry_invalid(e.g.owasp_llm_top10_entry_invalid). rfc3161_timestamp, when provided, MUST be valid base64 and is preserved verbatim. The error code isrfc3161_timestamp_not_base64.
The SDK enforces the same shapes client-side and raises before the HTTP roundtrip. The framework_mappings_self_declared boolean is server-set.
How do I produce a taxonomy-bound receipt?
Python SDK
import asqav
asqav.init()
agent = asqav.Agent.create("threat-fw-emitter")
sig = agent.sign(
"api:call",
{"user": "..."},
compliance_mode=True,
receipt_type="protectmcp:decision",
mitre_techniques=["T1059", "T1078"],
owasp_llm_top10=["LLM01"],
nist_ai_rmf=["GOVERN-1.1", "MEASURE-2.7"],
eu_ai_act_articles=["Article-12"],
)
TypeScript SDK
import { Agent } from "@asqav/sdk";
const agent = Agent.attach({ /* ... */ });
await agent.sign({
actionType: "api:call",
context: { user: "..." },
complianceMode: true,
receiptType: "protectmcp:decision",
mitreTechniques: ["T1059", "T1078"],
owaspLlmTop10: ["LLM01"],
nistAiRmf: ["GOVERN-1.1", "MEASURE-2.7"],
euAiActArticles: ["Article-12"],
});
curl
curl -X POST https://api.asqav.com/api/v1/agents/agt_threat_fw/sign \
-H "X-API-Key: $ASQAV_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"action_type": "api:call",
"compliance_mode": true,
"receipt_type": "protectmcp:decision",
"mitre_techniques": ["T1059", "T1078"],
"owasp_llm_top10": ["LLM01"],
"nist_ai_rmf": ["GOVERN-1.1", "MEASURE-2.7"],
"eu_ai_act_articles": ["Article-12"]
}'
How does an auditor use the 8-tuple?
The auditor holds the receipt (with the 8-tuple) and the producer's compliance documentation (kept by the producer's GRC team). To reconstruct the control coverage, the auditor:
- Reads the six taxonomy lists plus
framework_mappings_self_declaredfrom the signed envelope. - Confirms
framework_mappings_self_declared=truematches the populated lists (cloud-set, so always consistent). - Maps each id against the corresponding canonical framework document (the auditor holds the authoritative MITRE / OWASP / NIST / ISO / EU references).
- Cross-checks the producer's policy artefact (resolved via
policy_digest) against the declared controls. - Verifies the
rfc3161_timestampagainst the issuing TSA chain when present, for an additional independent trusted-timestamp anchor.
Each step is independently verifiable. A mismatch on any step is an audit signal. Matching values across all steps document the producer's declared control coverage for that specific action.
How does this relate to standalone GRC mapping tools?
Standalone GRC tooling maintains a control-coverage spreadsheet separate from the action log. Asqav publishes the mapping as part of the action log itself. The auditor needs one canonical chain, not two.
This subsumption is documented in the IETF Compliance Receipts draft under the optional-extensions section, alongside config_manifest_digest, cve_inventory_digest, executable_hash, sbom_digest, slsa_provenance_pointer, and supply_chain_pointer. Producers MAY maintain a separate GRC system in parallel. The receipt's taxonomy fields then resolve to the same control ids the GRC system tracks.