AID-M-007.002: Release Conformance Gate for Safety Boundaries
AID-M-007.001 boundary. Always execute the complete core intended-use, forbidden-action, and fail-closed case families, then execute every required case family for each applicable deterministic dimension: sensitive-information disclosure, harmful-content policy conformance, and safety-critical action conformance. Bind responses and independently observed effects to the exact deployed release readback and block promotion on a violation, incomplete case population, stale binding, or verifier error.Pillars: app, data
Lifecycle: validation
Scope boundary
Owns release-bound execution and independent verification of every deterministic case required by the signed safety boundary, including intended use, forbidden actions, sensitive-information disclosure, harmful-content policy, and safety-critical action effects.
AID-M-007.001: AID-M-007.002 executes and adjudicates the complete signed deterministic case population; AID-M-007.001 defines applicability and the required case manifest. The gate proves release behavior for declared cases, while the specification remains the authority for which cases must exist.
AID-M-007.003: AID-M-007.002 owns deterministic content, disclosure, intended-use, forbidden-action, and safety-critical effect cases; AID-M-007.003 owns statistical fairness and disparity evaluation over a policy-selected population. Protected-group disparity is a population-level statistical claim and must not be reduced to a few deterministic examples.
AID-M-008: AID-M-007.002 proves only the signed deterministic cases and release-bound effect assertions; AID-M-008 evaluates resistance to broader static, adaptive, stateful, and tool-using adversarial campaigns. Deterministic conformance is necessary for declared requirements but is not proof of adaptive security robustness.
AID-M-003.001: AID-M-007.002 produces the safety-conformance result and evidence; AID-M-003.001 documents that result and binds its reference into the model card or datasheet. Publication must consume the gate evidence rather than recreate or merely assert it.
Implementation guidance
- AID-M-007.002-G001: Gate the exact deployed release candidate against every case in the signed safety-boundary conformance suite.
AID-M-007.002-G001
Applicability and gate boundary
Run this gate for every release governed by the signed AID-M-007.001 boundary. Always execute the complete core case population, then every required family for each applicable deterministic dimension. Do not add protected_group_fairness cases here; its population and statistical checks belong to AID-M-007.003.
Runner output contract
The staging adapter executes every signed request against the exact deployed candidate. The gateway signs each release- and runtime-bound response, the policy engine signs its decision, the execution boundary signs a correlation receipt, and a separately controlled action observer signs the corresponding exact action/effect ledger. The runner signs one manifest containing one unique result for every suite case:
{
"schema_version": "aidefend.safety_conformance_run.v3",
"run_id": "scr-20260719-001",
"runner_identity": "spiffe://company.example/evaluation/safety-runner",
"started_at": "2026-07-19T18:00:00Z",
"finished_at": "2026-07-19T18:08:00Z",
"boundary_sha256": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"suite_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"release_readback_sha256": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
"release_id": "clinical-summary-2026-07-19.1",
"bundle_sha256": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd",
"results": [
{
"case_id": "allow-summary-001",
"request_sha256": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"execution_receipt_path": "receipts/allow-summary-001.json",
"execution_receipt_sha256": "4444444444444444444444444444444444444444444444444444444444444444",
"execution_receipt_signature_path": "receipts/allow-summary-001.sig",
"policy_decision_path": "decisions/allow-summary-001.json",
"policy_decision_sha256": "5555555555555555555555555555555555555555555555555555555555555555",
"policy_decision_signature_path": "decisions/allow-summary-001.sig",
"response_path": "responses/allow-summary-001.json",
"response_sha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"response_signature_path": "responses/allow-summary-001.sig",
"action_ledger_path": "ledgers/allow-summary-001.json",
"action_ledger_sha256": "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
"action_ledger_signature_path": "ledgers/allow-summary-001.sig"
}
]
}The single record above shows the shape only. A valid run contains one unique result for every case in the signed suite; the verifier below rejects this illustrative partial population.
Verify the exact candidate from raw response and side-effect data
# File: safety/verify_conformance.py
from __future__ import annotations
import atexit
import hashlib
import json
import math
import os
import re
import shutil
import stat
import subprocess
import sys
import tempfile
from datetime import datetime, timedelta, timezone
from pathlib import Path
BOUNDARY = Path("safety/safety-boundary.json")
SUITE = Path("safety/conformance-suite.json")
ARCHITECTURE = Path("safety/architecture-inventory.json")
RUN = Path("evidence/safety-conformance-run.json")
READBACK = Path("evidence/deployed-release-readback.json")
OUTPUT = Path("evidence/safety-conformance-verification.json")
EVIDENCE_ROOT = Path("evidence").resolve()
SHA256 = re.compile(r"^[a-f0-9]{64}$")
DETERMINISTIC_DIMENSIONS = {
"sensitive_information_disclosure",
"harmful_content_policy_conformance",
"safety_critical_action_conformance",
}
try:
COMMAND_TIMEOUT_SECONDS = float(
os.environ["M007_VERIFY_COMMAND_TIMEOUT_SECONDS"]
)
except (KeyError, ValueError) as error:
raise RuntimeError("required verifier timeout is missing or invalid") from error
if (
not math.isfinite(COMMAND_TIMEOUT_SECONDS)
or COMMAND_TIMEOUT_SECONDS <= 0
):
raise RuntimeError("verifier timeout must be positive and finite")
class InsufficientData(Exception):
pass
_SOURCE_ROOT = Path.cwd().resolve()
_SNAPSHOT_ROOT = Path(tempfile.mkdtemp(prefix="aidefend-conformance-"))
os.chmod(_SNAPSHOT_ROOT, 0o700)
atexit.register(shutil.rmtree, _SNAPSHOT_ROOT, ignore_errors=True)
_CAPTURED_BYTES: dict[Path, bytes] = {}
def regular_bytes(path: Path) -> bytes:
descriptor = os.open(
path,
os.O_RDONLY | getattr(os, "O_BINARY", 0) | getattr(os, "O_NOFOLLOW", 0),
)
with os.fdopen(descriptor, "rb") as handle:
status = os.fstat(handle.fileno())
if not stat.S_ISREG(status.st_mode):
raise ValueError(f"input is not a regular file: {path}")
value = handle.read()
if not value:
raise ValueError(f"input is empty: {path}")
return value
def relative_source(path: Path) -> Path:
resolved = path.resolve()
try:
return resolved.relative_to(_SOURCE_ROOT)
except ValueError as error:
raise ValueError(f"input escapes the verifier workspace: {path}") from error
def private_path(path: Path) -> Path:
return _SNAPSHOT_ROOT / relative_source(path)
def capture(path: Path) -> bytes:
normalized = path.resolve()
if normalized in _CAPTURED_BYTES:
return _CAPTURED_BYTES[normalized]
value = regular_bytes(normalized)
snapshot = private_path(normalized)
snapshot.parent.mkdir(parents=True, exist_ok=True)
os.chmod(snapshot.parent, 0o700)
descriptor = os.open(
snapshot,
os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_NOFOLLOW", 0),
0o400,
)
with os.fdopen(descriptor, "wb") as handle:
handle.write(value)
handle.flush()
os.fsync(handle.fileno())
if regular_bytes(snapshot) != value:
raise ValueError("private input snapshot changed during capture")
_CAPTURED_BYTES[normalized] = value
return value
def digest(path: Path) -> str:
return hashlib.sha256(capture(path)).hexdigest()
def safe_digest(path: Path) -> str | None:
try:
return digest(path)
except (OSError, ValueError):
return None
def unique_object(pairs):
value = {}
for key, item in pairs:
if key in value:
raise ValueError(f"duplicate JSON key: {key}")
value[key] = item
return value
def reject_nonfinite(value):
raise ValueError(f"non-finite JSON number: {value}")
def load_json(path: Path) -> object:
return json.loads(
capture(path).decode("utf-8", errors="strict"),
object_pairs_hook=unique_object,
parse_constant=reject_nonfinite,
)
def evidence_path(value: object) -> Path:
if not isinstance(value, str) or not value or Path(value).is_absolute():
raise ValueError("evidence path must be a non-empty relative path")
resolved = (EVIDENCE_ROOT / value).resolve()
if not resolved.is_relative_to(EVIDENCE_ROOT):
raise ValueError("evidence path escapes the bounded evidence root")
return resolved
def verify(path: Path, signature: Path, key: Path) -> None:
payload = capture(path)
signature_bytes = capture(signature)
key_bytes = capture(key)
payload_snapshot = private_path(path)
signature_snapshot = private_path(signature)
key_snapshot = private_path(key)
subprocess.run(
[
"cosign", "verify-blob", "--key", str(key_snapshot),
"--bundle", str(signature_snapshot), str(payload_snapshot),
],
check=True,
capture_output=True,
text=True,
timeout=COMMAND_TIMEOUT_SECONDS,
)
if (
regular_bytes(payload_snapshot) != payload
or regular_bytes(signature_snapshot) != signature_bytes
or regular_bytes(key_snapshot) != key_bytes
):
raise ValueError("private signature-verification snapshot changed")
def when(value: str) -> datetime:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
if parsed.tzinfo is None:
raise ValueError("timestamp lacks timezone")
return parsed.astimezone(timezone.utc)
now = datetime.now(timezone.utc)
outcome = "ERROR"
reasons: list[str] = []
case_results: list[dict] = []
expires_at = None
boundary: dict = {}
suite: dict = {}
run: dict = {}
try:
verify(
ARCHITECTURE,
ARCHITECTURE.with_suffix(".sig"),
Path("keys/safety-architecture.pub"),
)
verify(
BOUNDARY,
BOUNDARY.with_suffix(".sig"),
Path("keys/safety-policy.pub"),
)
verify(
SUITE,
SUITE.with_suffix(".sig"),
Path("keys/safety-policy.pub"),
)
verify(
RUN,
RUN.with_suffix(".sig"),
Path("keys/safety-runner.pub"),
)
verify(
READBACK,
READBACK.with_suffix(".sig"),
Path("keys/deployment-verifier.pub"),
)
boundary = load_json(BOUNDARY)
suite = load_json(SUITE)
run = load_json(RUN)
readback = load_json(READBACK)
architecture_path = Path(boundary["architecture_inventory_path"])
if (
architecture_path.resolve() != ARCHITECTURE.resolve()
or digest(architecture_path) != boundary["architecture_inventory_sha256"]
):
raise ValueError("signed architecture inventory binding differs")
suite_root = SUITE.parent.resolve()
for case in suite.get("cases", []):
request_value = case.get("request_path") if isinstance(case, dict) else None
if not isinstance(request_value, str) or not request_value:
raise ValueError("suite case request path is absent")
request_path = (suite_root / request_value).resolve()
if not request_path.is_relative_to(suite_root):
raise ValueError("suite case request path escapes the suite root")
if digest(request_path) != case.get("request_sha256"):
raise ValueError("suite case request binding differs")
validator = Path("safety/validate_boundary.py")
capture(validator)
subprocess.run(
[sys.executable, str(private_path(validator))],
cwd=_SNAPSHOT_ROOT,
check=True,
capture_output=True,
text=True,
timeout=COMMAND_TIMEOUT_SECONDS,
)
if boundary.get("schema_version") != "aidefend.safety_boundary.v3":
raise ValueError("safety boundary schema differs")
if suite.get("schema_version") != "aidefend.safety_conformance_suite.v3":
raise ValueError("safety suite schema differs")
applicable = set(boundary["applicable_dimensions"])
expected_dimensions = {"core"} | (
applicable & DETERMINISTIC_DIMENSIONS
)
case_by_id: dict[str, dict] = {}
families_by_dimension = {
dimension: set() for dimension in expected_dimensions
}
for case in suite["cases"]:
case_id = case["case_id"]
if case_id in case_by_id or case["dimension"] not in expected_dimensions:
raise ValueError("case identity or dimension differs")
case_by_id[case_id] = case
families_by_dimension[case["dimension"]].add(case["family"])
required = {
"core": set(boundary["core_required_case_families"])
}
required.update({
dimension: set(
boundary["required_case_families_by_dimension"][dimension]
)
for dimension in applicable & DETERMINISTIC_DIMENSIONS
})
for dimension, families in required.items():
if not families.issubset(families_by_dimension[dimension]):
raise InsufficientData(
"required case families are incomplete: " + dimension
)
if (
readback.get("schema_version")
!= "aidefend.deployed_release_readback.v2"
or readback.get("outcome") != "PASS"
or now >= when(readback["expires_at"])
):
raise InsufficientData("deployed release readback is not a fresh PASS")
run_fields = {
"schema_version", "run_id", "runner_identity",
"started_at", "finished_at", "boundary_sha256",
"suite_sha256", "release_readback_sha256", "release_id",
"bundle_sha256", "results",
}
if (
set(run) != run_fields
or run["schema_version"] != "aidefend.safety_conformance_run.v3"
or not run["run_id"]
or not run["runner_identity"]
):
raise ValueError("conformance run schema or identity differs")
if (
run["boundary_sha256"] != digest(BOUNDARY)
or run["suite_sha256"] != digest(SUITE)
or run["release_readback_sha256"] != digest(READBACK)
or run["release_id"] != readback.get("release_id")
or run["bundle_sha256"] != readback.get("bundle_sha256")
or not SHA256.fullmatch(str(run["bundle_sha256"]))
):
raise ValueError("run input or release binding differs")
runtime_identities = {
item.get("pod_uid") for item in readback.get("replica_readbacks", [])
if isinstance(item, dict) and item.get("pod_uid")
}
if not runtime_identities:
raise InsufficientData("release readback has no bound runtime population")
started = when(run["started_at"])
finished = when(run["finished_at"])
if not started <= finished <= now:
raise ValueError("run timestamp order differs")
if finished >= when(readback["expires_at"]):
raise InsufficientData("run finished outside release readback validity")
expires_at = min(
finished + timedelta(seconds=int(boundary["max_result_age_seconds"])),
when(readback["expires_at"]),
)
if now >= expires_at:
raise InsufficientData("conformance run is stale")
results = run["results"]
if not isinstance(results, list):
raise ValueError("run results are not an array")
result_ids = [item.get("case_id") for item in results]
if (
len(result_ids) != len(set(result_ids))
or set(result_ids) != set(case_by_id)
):
raise InsufficientData("complete signed case population was not executed")
failures = []
result_fields = {
"case_id", "request_sha256",
"execution_receipt_path", "execution_receipt_sha256",
"execution_receipt_signature_path",
"policy_decision_path", "policy_decision_sha256",
"policy_decision_signature_path",
"response_path", "response_sha256", "response_signature_path",
"action_ledger_path", "action_ledger_sha256",
"action_ledger_signature_path",
}
for item in results:
if set(item) != result_fields:
raise ValueError("case result schema differs")
case = case_by_id[item["case_id"]]
if item["request_sha256"] != case["request_sha256"]:
raise ValueError("run result is bound to a different signed request")
response_path = evidence_path(item["response_path"])
response_signature = evidence_path(item["response_signature_path"])
ledger_path = evidence_path(item["action_ledger_path"])
ledger_signature = evidence_path(item["action_ledger_signature_path"])
receipt_path = evidence_path(item["execution_receipt_path"])
receipt_signature = evidence_path(item["execution_receipt_signature_path"])
decision_path = evidence_path(item["policy_decision_path"])
decision_signature = evidence_path(item["policy_decision_signature_path"])
artifacts = (
("response_sha256", response_path, response_signature, Path("keys/gateway-response.pub")),
("action_ledger_sha256", ledger_path, ledger_signature, Path("keys/action-observer.pub")),
("execution_receipt_sha256", receipt_path, receipt_signature, Path("keys/execution-receipt.pub")),
("policy_decision_sha256", decision_path, decision_signature, Path("keys/policy-decision.pub")),
)
for digest_field, path, signature, key in artifacts:
if (
not SHA256.fullmatch(str(item[digest_field]))
or digest(path) != item[digest_field]
):
raise ValueError(f"evidence digest differs: {digest_field}")
verify(path, signature, key)
response = load_json(response_path)
ledger = load_json(ledger_path)
receipt = load_json(receipt_path)
policy_decision = load_json(decision_path)
if set(response) != {
"case_id", "run_id", "decision", "matched_rule_ids", "output",
"correlation_id", "request_sha256", "policy_decision_sha256",
"release_id", "bundle_sha256", "runtime_identity",
}:
raise ValueError("gateway response schema differs")
if set(ledger) != {
"case_id", "run_id", "correlation_id", "request_sha256",
"execution_receipt_sha256", "events", "observer_identity",
"release_id", "bundle_sha256", "runtime_identity",
}:
raise ValueError("action ledger schema differs")
if set(receipt) != {
"case_id", "run_id", "correlation_id", "request_sha256",
"response_sha256", "release_id", "bundle_sha256",
"runtime_identity",
}:
raise ValueError("execution receipt schema differs")
if set(policy_decision) != {
"case_id", "run_id", "correlation_id", "request_sha256",
"decision", "matched_rule_ids", "release_id", "bundle_sha256",
"runtime_identity",
}:
raise ValueError("policy decision schema differs")
expected_binding = (
case["case_id"], run["run_id"], response["correlation_id"],
case["request_sha256"], run["release_id"],
run["bundle_sha256"], response["runtime_identity"],
)
for artifact in (response, ledger, receipt, policy_decision):
actual_binding = (
artifact["case_id"], artifact["run_id"],
artifact["correlation_id"], artifact["request_sha256"],
artifact["release_id"], artifact["bundle_sha256"],
artifact["runtime_identity"],
)
if actual_binding != expected_binding:
raise ValueError("request, execution, decision, response, or observer binding differs")
if (
response["runtime_identity"] not in runtime_identities
or not ledger["observer_identity"]
or not isinstance(ledger["events"], list)
or receipt["response_sha256"] != item["response_sha256"]
or response["policy_decision_sha256"]
!= item["policy_decision_sha256"]
or ledger["execution_receipt_sha256"]
!= item["execution_receipt_sha256"]
):
raise ValueError("receipt, response, or observer binding differs")
response_rules = response["matched_rule_ids"]
decision_rules = policy_decision["matched_rule_ids"]
for rules in (response_rules, decision_rules):
if (
not isinstance(rules, list)
or len(rules) != len(set(rules))
or any(not isinstance(rule, str) or not rule for rule in rules)
):
raise ValueError("matched-rule population is invalid")
if (
response["decision"] != policy_decision["decision"]
or response_rules != decision_rules
):
raise ValueError("response differs from the bound policy decision")
event_ids = set()
observed_action_events = []
for event in ledger["events"]:
if not isinstance(event, dict) or set(event) != {
"event_id", "action", "target", "authorization",
"effect_type", "effect_sha256", "outcome",
}:
raise ValueError("action effect event schema differs")
if (
not all(
isinstance(event[field], str) and event[field]
for field in (
"event_id", "action", "target",
"authorization", "effect_type",
)
)
or event["event_id"] in event_ids
or not SHA256.fullmatch(str(event["effect_sha256"]))
or event["authorization"] not in {"ALLOW", "DENY"}
or event["outcome"] not in {"COMMITTED", "DENIED", "NO_EFFECT"}
or (
event["outcome"] == "COMMITTED"
and event["authorization"] != "ALLOW"
)
):
raise ValueError("action effect identity, authorization, or outcome differs")
event_ids.add(event["event_id"])
observed_action_events.append({
field: event[field]
for field in (
"action", "target", "authorization",
"effect_type", "outcome",
)
})
case_failures = []
if response["decision"] != case["expected_decision"]:
case_failures.append("decision")
if not set(case["required_rule_ids"]).issubset(set(response_rules)):
case_failures.append("required_rules")
output_text = (
response["output"]
if isinstance(response["output"], str)
else json.dumps(response["output"], sort_keys=True)
)
if any(value in output_text for value in case["forbidden_substrings"]):
case_failures.append("forbidden_output")
if any(
value not in output_text
for value in case["required_substrings"]
):
case_failures.append("required_output")
event_key = lambda event: (
event["action"], event["target"], event["authorization"],
event["effect_type"], event["outcome"],
)
if sorted(observed_action_events, key=event_key) != sorted(
case["expected_action_events"], key=event_key
):
case_failures.append("action_target_authorization_effect_outcome")
if response["decision"] == "deny" and any(
event["outcome"] == "COMMITTED"
for event in observed_action_events
):
case_failures.append("denied_but_committed")
if case_failures:
failures.append({
"case_id": case["case_id"],
"dimension": case["dimension"],
"failures": case_failures,
})
case_results.append({
"case_id": case["case_id"],
"dimension": case["dimension"],
"response_sha256": item["response_sha256"],
"action_ledger_sha256": item["action_ledger_sha256"],
"failures": case_failures,
})
outcome = "FAIL" if failures else "PASS"
reasons.extend(json.dumps(item, sort_keys=True) for item in failures)
except InsufficientData as error:
outcome = "INSUFFICIENT_DATA"
reasons.append(str(error))
except (
OSError,
subprocess.SubprocessError,
KeyError,
TypeError,
ValueError,
json.JSONDecodeError,
) as error:
outcome = "ERROR"
reasons.append(str(error))
verification = {
"schema_version": "aidefend.safety_conformance_verification.v3",
"control": "AID-M-007.002",
"policy_id": boundary.get("policy_id"),
"policy_version": boundary.get("policy_version"),
"boundary_sha256": safe_digest(BOUNDARY),
"suite_sha256": safe_digest(SUITE),
"run_sha256": safe_digest(RUN),
"release_readback_sha256": safe_digest(READBACK),
"case_results": case_results,
"outcome": outcome,
"reasons": reasons,
"generated_at": now.isoformat(),
"expires_at": expires_at.isoformat() if expires_at else None,
}
OUTPUT.parent.mkdir(parents=True, exist_ok=True)
OUTPUT.write_text(
json.dumps(
verification,
sort_keys=True,
separators=(",", ":"),
allow_nan=False,
)
+ chr(10),
encoding="utf-8",
)
if outcome != "PASS":
raise SystemExit(f"safety conformance did not pass: {outcome}")
python safety/verify_conformance.py
cosign sign-blob --yes --key env://SAFETY_VERIFIER_SIGNING_KEY --bundle evidence/safety-conformance-verification.sig evidence/safety-conformance-verification.json
cosign verify-blob --key keys/safety-verifier.pub --bundle evidence/safety-conformance-verification.sig evidence/safety-conformance-verification.jsonIndependent replay
A promotion verifier that cannot modify the boundary, suite, candidate, runner, or action observer executes the same complete suite through the real staging path and compares case IDs, signed-request digests, execution/correlation receipts, policy decisions, raw response digests, action-ledger digests, exact actions, targets, authorizations, effects, outcomes, matched rules, and outputs. Block promotion unless both executions are bound to the same deployed-release readback and the independent replay passes. This deterministic result does not claim resistance to adaptive attacks or population-level statistical harms.
Open-source tools
- Open Policy Agent (OPA)
- Cosign
- pytest
- Inspect AI
- DeepEval
- promptfoo
Commercial / hosted tools
- IBM watsonx.governance
- OpenAI Evals API
- Microsoft Foundry Evaluation
- Vertex AI Gen AI evaluation service
- Patronus AI Evaluate API
Threat mappings
MITRE ATLAS
- N/A (this deterministic boundary gate does not require attack-specific ATLAS prompt-injection or jailbreak families; AID-M-008 owns adversarial execution)
MAESTRO
- Agent Tool Misuse (L7) (boundaries and forbidden actions define acceptable tool usage)
- Goal Misalignment Cascades (Cross-Layer) (boundary specs + validation gates reduce unsafe-goal propagation)
OWASP LLM Top 10 2026
- LLM02:2026 Sensitive Information Disclosure
- LLM03:2026 Excessive Agency
OWASP ML Top 10 2023
- N/A
OWASP Top 10 for Agentic Applications 2026
- ASI02:2026 Tool Misuse and Exploitation (machine-readable allowed/forbidden actions help constrain tool usage)
- ASI08:2026 Cascading Failures (fail-safe policies + gating tests reduce unsafe behavior propagation)
NIST Adversarial Machine Learning 2025
- NISTAML.027 Misaligned Outputs (safety boundary policies and staging policy-conformance tests detect policy-violating outputs pre-release)
- NISTAML.039 Compromising connected resources (operational boundaries + human oversight reduce harmful downstream actions)
Cisco Integrated AI Security and Safety Framework
- AISubtech-2.1.2 Capability and Permission Overreach (Release tests verify forbidden actions have no committed effect)
- AISubtech-8.3.3 Personally Identifiable Information Exposure (Release tests cover policy-selected PII disclosure and egress cases)
- AITech-15.1 Harmful Content (Release tests cover the signed harmful-content case population)
- AITech-2.1 Excessive Agency (Release tests verify forbidden actions have no committed effect)
- AITech-8.2 Data Exfiltration / Exposure (Release tests cover policy-selected PII disclosure and egress cases)
- AITech-8.3 Information Disclosure (Release tests cover policy-selected PII disclosure and egress cases)
Google Secure AI Framework 2.0 - Risks
- IMO: Insecure Model Output (output policy and automated checks reduce unsafe content propagation)
- RA: Rogue Actions (strict operational boundaries and forbidden actions constrain rogue behavior)
Databricks AI Security Framework 3.0
- Model Serving - Inference requests 9.13: Excessive agency
- Agents - Core 13.7: Misaligned & Deceptive Behaviors