AID-I-001.005: Safe Ephemeral Detonation & Attested Raw Observation Reporting
Pillars: infra, app
Lifecycle: operation, validation
Scope boundary
Owns safe artifact-detonation orchestration, complete case execution, attested raw behavioral observations, anti-analysis findings, and observation metadata. It does not claim that one run proves an artifact benign and does not issue a promotion credential.
AID-I-001.003: AID-I-001.005 owns artifact detonation and raw observation completeness; AID-I-001.003 owns single-use sandbox creation, teardown, lease revocation, and residue checks. Detonation must consume the authenticated destruction and no-residue receipt before closing a case, but it adds a separate analysis population and attested observation result.
AID-H-031.003: AID-I-001.005 emits attested raw dynamic-analysis observations; AID-H-031.003 combines dynamic, static, and provenance evidence to decide artifact promotion. A detonation finding is evidence for the promotion gate, not the release decision itself.
Implementation guidance
- AID-I-001.005-G001: Orchestrate an automated analysis workflow using microVMs for strong isolation.
- AID-I-001.005-G002: Define and enforce a strict behavioral security policy within the sandbox.
- AID-I-001.005-G003: Generate a signed behavioral-analysis report whose payload and referenced evidence can be replayed against the pinned verifier.
- AID-I-001.005-G004: Monitor for anti-analysis and sandbox evasion techniques.
AID-I-001.005-G001
Sandbox analysis boundary
Use this method for scripts, binaries, containers, plugins, or model-loader candidates whose behavior must be observed before a downstream trust or release decision. The analysis controller accepts only an immutable artifact reference plus digest and a signature-verified profile. It delegates one-shot runtime creation and teardown to AID-I-001.003, but independently proves that the exact artifact bytes were analyzed under the exact profile and that only a verified report can leave the analysis boundary. A static-only artifact class is NOT_APPLICABLE when the signed policy records that classification.
Verified analysis orchestrator
# File: analysis/verified_orchestrator.py
from __future__ import annotations
import re
from dataclasses import dataclass
from typing import Callable
SHA256 = re.compile(r"^[0-9a-f]{64}$")
IDENTIFIER = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{7,255}$")
@dataclass(frozen=True)
class VerifiedAnalysisPolicy:
policy_sha256: str
profile_id: str
analyzer_image_digest: str
runtime_profile_ref: str
egress_policy_ref: str
report_schema: str
@dataclass(frozen=True)
class ArtifactSubject:
artifact_ref: str
artifact_sha256: str
media_type: str
tenant_id: str
release_id: str
@dataclass(frozen=True)
class ArtifactReader:
"""Required authenticated runtime adapter callables; no fallback implementation."""
rehash: Callable[[ArtifactSubject], str]
@dataclass(frozen=True)
class SandboxBroker:
"""Required authenticated runtime adapter callables; no fallback implementation."""
analyze_once: Callable[[ArtifactSubject, VerifiedAnalysisPolicy], dict[str, object]]
verify_absence: Callable[[dict[str, object]], dict[str, object]]
@dataclass(frozen=True)
class ReportVerifier:
"""Required authenticated runtime adapter callables; no fallback implementation."""
verify: Callable[[str, ArtifactSubject, VerifiedAnalysisPolicy], dict[str, object]]
@dataclass(frozen=True)
class EvidenceWriter:
"""Required authenticated runtime adapter callables; no fallback implementation."""
append_and_verify: Callable[[dict[str, object]], dict[str, str]]
def run_attested_analysis(
*,
subject: ArtifactSubject,
policy: VerifiedAnalysisPolicy,
artifacts: ArtifactReader,
sandboxes: SandboxBroker,
reports: ReportVerifier,
evidence: EvidenceWriter,
) -> dict[str, object]:
if not SHA256.fullmatch(subject.artifact_sha256):
raise ValueError("invalid artifact digest")
if not SHA256.fullmatch(policy.policy_sha256):
raise ValueError("invalid policy digest")
if "@sha256:" not in policy.analyzer_image_digest:
raise ValueError("analyzer image must be immutable")
if not IDENTIFIER.fullmatch(policy.profile_id):
raise ValueError("invalid profile ID")
if artifacts.rehash(subject) != subject.artifact_sha256:
raise PermissionError("artifact bytes do not match the analysis subject")
execution = sandboxes.analyze_once(subject=subject, policy=policy)
required_execution = {
"receipt_sha256", "artifact_sha256", "policy_sha256", "profile_id",
"analyzer_image_digest", "runtime_profile_ref", "egress_policy_ref",
"sandbox_id", "generation_id", "report_ref", "terminal_state",
}
if set(execution) != required_execution:
raise PermissionError("analysis execution receipt has an invalid schema")
expected = {
"artifact_sha256": subject.artifact_sha256,
"policy_sha256": policy.policy_sha256,
"profile_id": policy.profile_id,
"analyzer_image_digest": policy.analyzer_image_digest,
"runtime_profile_ref": policy.runtime_profile_ref,
"egress_policy_ref": policy.egress_policy_ref,
}
for key, value in expected.items():
if execution.get(key) != value:
raise PermissionError("analysis execution binding mismatch: " + key)
if execution["terminal_state"] != "SUCCEEDED":
raise PermissionError("analysis did not complete")
report = reports.verify(
str(execution["report_ref"]), subject=subject, policy=policy
)
if report.get("finding_state") not in {"NO_FINDING", "FINDING", "INCONCLUSIVE", "ERROR"}:
raise PermissionError("verified report has no closed finding state")
absence = sandboxes.verify_absence(execution)
if absence.get("outcome") != "PASS":
raise PermissionError("analysis runtime residue remains")
outcome = {
"NO_FINDING": "PASS",
"FINDING": "FAIL",
"INCONCLUSIVE": "INSUFFICIENT_DATA",
"ERROR": "ERROR",
}[str(report["finding_state"])]
final = evidence.append_and_verify({
"schema_version": "aidefend.behavioral-analysis-evidence.v1",
"control": "AID-I-001.005",
"tenant_id": subject.tenant_id,
"release_id": subject.release_id,
**expected,
"execution_receipt_sha256": execution["receipt_sha256"],
"analysis_report_sha256": report["report_sha256"],
"absence_receipt_sha256": absence["receipt_sha256"],
"finding_state": report["finding_state"],
"outcome": outcome,
})
return {"outcome": outcome, "evidence": final}
Runtime profile and verification
The digest-pinned analyzer fetches the immutable object through a read-only artifact service, rehashes it inside the sandbox, executes the complete signed case population with no secrets and only profile-authorized egress, stores raw observations outside the sandbox, and emits a signed observation report reference with a closed finding state, never a deployment authorization. For model-loader analysis, mount model bytes read-only, disable network, set local-only loader flags, and execute the exact deserializer/runtime combination named by policy. Resource and time bounds come from policy. The controller destroys the sandbox on success, denial, timeout, cancellation, report failure, and evidence failure.
AID-I-001.005-G002
Concept:
The effectiveness of the sandbox depends on the rules used to judge behavior. A strict, default-deny policy should be created that defines what the generated code is allowed to do. Any action outside this narrow scope is recorded as a policy-violation finding; the downstream release gate decides the bounded response. All network egress should be forced through a monitored proxy. For the model-loader-analysis profile used by H-003.002 and H-003.006, the policy should be even narrower: no outbound network, no secret mounts, read-only model bytes, no writes outside scratch space, no shell-outs, and bounded first-load execution.
Implement a Falco Rule for a Code Interpreter
Falco is a runtime security tool that can monitor kernel syscalls. This Falco rule defines the expected behavior for a sandboxed Python script. It allows file operations within `/tmp` but blocks network connections and file access elsewhere.
# File: sandbox_policies/falco_code_interpreter.yaml
- macro: aidefend_ai_sandbox_outbound
condition: >
evt.type = connect and
(fd.typechar = 4 or fd.typechar = 6) and
fd.ip != "0.0.0.0" and fd.net != "127.0.0.0/8" and
(evt.rawres >= 0 or evt.res = EINPROGRESS)
- rule: Disallowed Egress from AI-Sandbox
desc: Detects any outbound network connection from the sandboxed Python interpreter.
condition: >
aidefend_ai_sandbox_outbound and proc.name = python3 and not proc.aname contains "analysis_proxy"
output: "Disallowed network egress by AI-generated code (proc=%proc.name command=%proc.cmdline connection=%fd.name)"
priority: CRITICAL
tags: [network, ai_sandbox]
- rule: Disallowed File Write from AI-Sandbox
desc: Detects file writes outside of the /tmp directory by a sandboxed python process.
condition: >
(evt.type in (open,openat,openat2) and evt.is_open_write=true and fd.typechar='f' and fd.num>=0)
and proc.name = python3 and not fd.name startswith /tmp/
output: "Disallowed file write by AI-generated code (proc=%proc.name file=%fd.name)"
priority: CRITICAL
tags: [filesystem, ai_sandbox]
Action: Define a strict behavioral policy for your pre-execution sandbox using a tool like Falco or Tetragon. The microVM/container profile must enforce network and filesystem denial with network policy plus seccomp/AppArmor or equivalent controls. Falco observes violations and feeds the signed analysis finding state; it is not itself the blocking mechanism. A policy violation must produce FINDING with bound raw evidence for the downstream gate, and profile-specific constraints such as model-loader-analysis must be independently replayed.
AID-I-001.005-G003
Report subject and trust boundary
The report is analysis evidence for one immutable artifact and one completed analysis profile; it is not a release credential. It must bind the artifact bytes, release/tenant, policy and case-population digests, analyzer image and runtime identities, raw-evidence bundle, execution receipt, observation interval, closed finding state, issuer, key ID, and a unique report ID. The signer runs outside the analysis sandbox and signs only after validating the analyzer receipt and complete case population. An independent verifier rehashes the artifact and verifies the report locally; it never trusts a caller-supplied finding state.
Canonical signed report
# File: analysis/signed_report.py
from __future__ import annotations
import base64
import re
import time
from dataclasses import dataclass
from typing import Callable
import rfc8785
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
SHA256 = re.compile(r"^[0-9a-f]{64}$")
FINDING_STATES = {"NO_FINDING", "FINDING", "INCONCLUSIVE", "ERROR"}
REPORT_KEYS = {
"schema_version", "report_id", "issuer", "key_id", "tenant_id",
"release_id", "artifact_sha256", "media_type", "profile_id",
"policy_sha256", "case_population_sha256", "analyzer_image_digest",
"runtime_receipt_sha256", "execution_receipt_sha256",
"raw_evidence_sha256", "observed_from_epoch", "observed_to_epoch",
"issued_at_epoch", "expires_at_epoch", "finding_state",
}
@dataclass(frozen=True)
class VerifiedReportPolicy:
issuer: str
audience: str
policy_sha256: str
allowed_key_ids: frozenset[str]
max_report_age_seconds: int
@dataclass(frozen=True)
class DetachedSigner:
"""Required authenticated runtime adapter callables; no fallback implementation."""
key_id: Callable[[], str]
sign: Callable[[bytes], bytes]
def canonical(payload: dict[str, object]) -> bytes:
return rfc8785.dumps(payload)
def b64url(value: bytes) -> str:
return base64.urlsafe_b64encode(value).rstrip(b"=").decode("ascii")
def b64url_decode(value: str) -> bytes:
return base64.urlsafe_b64decode(value + "=" * (-len(value) % 4))
def issue_report(
*,
payload: dict[str, object],
signer: DetachedSigner,
) -> dict[str, object]:
if set(payload) != REPORT_KEYS:
raise ValueError("report payload has an unexpected schema")
if payload["key_id"] != signer.key_id():
raise ValueError("report key ID does not match signer")
if payload["finding_state"] not in FINDING_STATES:
raise ValueError("invalid report finding state")
for key in (
"artifact_sha256", "policy_sha256", "case_population_sha256",
"runtime_receipt_sha256", "execution_receipt_sha256",
"raw_evidence_sha256",
):
if not SHA256.fullmatch(str(payload[key])):
raise ValueError("invalid digest: " + key)
encoded = canonical(payload)
return {
"payload": payload,
"signature_b64url": b64url(signer.sign(encoded)),
}
def verify_analysis_report(
*,
envelope: dict[str, object],
public_keys: dict[str, Ed25519PublicKey],
policy: VerifiedReportPolicy,
expected_artifact_sha256: str,
expected_release_id: str,
now_epoch: int | None = None,
) -> dict[str, object]:
if set(envelope) != {"payload", "signature_b64url"}:
raise PermissionError("invalid report envelope")
payload = envelope["payload"]
if not isinstance(payload, dict) or set(payload) != REPORT_KEYS:
raise PermissionError("invalid report schema")
key_id = str(payload["key_id"])
if key_id not in policy.allowed_key_ids or key_id not in public_keys:
raise PermissionError("untrusted report key")
try:
public_keys[key_id].verify(
b64url_decode(str(envelope["signature_b64url"])),
canonical(payload),
)
except (InvalidSignature, ValueError) as exc:
raise PermissionError("invalid analysis report signature") from exc
now = int(time.time()) if now_epoch is None else now_epoch
if payload["issuer"] != policy.issuer:
raise PermissionError("wrong report issuer")
if payload["policy_sha256"] != policy.policy_sha256:
raise PermissionError("wrong report policy")
if payload["artifact_sha256"] != expected_artifact_sha256:
raise PermissionError("artifact substitution")
if payload["release_id"] != expected_release_id:
raise PermissionError("release substitution")
issued = int(payload["issued_at_epoch"])
expires = int(payload["expires_at_epoch"])
observed_from = int(payload["observed_from_epoch"])
observed_to = int(payload["observed_to_epoch"])
if not (observed_from <= observed_to <= issued <= now < expires):
raise PermissionError("invalid or stale report timeline")
if now - issued > policy.max_report_age_seconds:
raise PermissionError("report exceeds signed freshness policy")
if payload["finding_state"] not in FINDING_STATES:
raise PermissionError("invalid verified finding state")
return payload
Independently verify the report
The verifier reads the candidate artifact from immutable storage, recomputes its SHA-256, verifies the signed report with a pinned issuer/key registry and rollback-protected policy, checks freshness and release binding, and verifies the referenced execution/runtime receipts and raw-evidence bundle. It rejects unknown or extra fields, duplicate report IDs, stale or revoked keys, omitted cases, missing raw evidence, an invalid finding state, and any digest mismatch. Persist report-ID and policy-version high-water state to prevent replay and rollback. Pass the verified report to the downstream gate as evidence; do not translate it into a release decision inside this method.
AID-I-001.005-G004
Concept:
Advanced malicious code will actively try to detect if it's running in an analysis environment. The sandbox must be instrumented to detect these evasion attempts, such as unusually long sleep calls, VM-specific hardware probes, debugger checks, or CPU-feature checks.
Implement and validate an Anti-Evasion Detection Policy
Falco syscall rules must use supported event fields. For long sleeps, match the supported sleep event types and use evt.arg.interval, which Falco exposes as the requested interval in nanoseconds.
# File: sandbox_policies/falco_anti_evasion.yaml
- rule: Suspicious Long Sleep in AI Sandbox
desc: A sandboxed Python process requested a long sleep interval, possibly to evade automated analysis.
condition: >
evt.type in (nanosleep, clock_nanosleep) and
proc.name = python3 and evt.arg.interval > 60000000000
output: >
Suspicious long sleep detected from AI-generated code
(proc=%proc.name cmd=%proc.cmdline interval_ns=%evt.arg.interval)
priority: WARNING
tags: [anti-analysis, ai_sandbox]
CI validation
falco --validate sandbox_policies/falco_anti_evasion.yaml
Action: Enhance the sandbox behavioral policy with validated rules for common anti-analysis techniques. Treat rule validation failure as a deployment blocker, and flag artifacts that perform environment checks or delayed execution as suspicious.
Open-source tools
- Firecracker
- Kata Containers
- gVisor
- QEMU
- Falco
- Cilium Tetragon
- strace
- sysdig
- Wazuh
- CAPE Sandbox (CAPEv2) (detonation and behavioral observations; attestation and evidence binding remain integration-owned)
Commercial / hosted tools
- Joe Sandbox
- ANY.RUN
- VMRay Platform (detonation and behavioral observations; attestation and evidence binding remain integration-owned)
- CrowdStrike Falcon Sandbox
- Palo Alto Networks Advanced WildFire
Threat mappings
MITRE ATLAS
- AML.T0011 User Execution
- AML.T0110 AI Agent Tool Poisoning
- AML.T0115 Publish Poisoned AI Artifacts
- AML.T0115.002 Publish Poisoned AI Artifacts: AI Agent Tools
- AML.T0110.001 AI Agent Tool Poisoning: Implementation
- AML.T0011.002 User Execution: Poisoned AI Agent Tool
- AML.T0011.000 User Execution: Unsafe AI Artifacts
- AML.T0050 Command and Scripting Interpreter
- AML.T0072 Cyber Communication Channel (detonation exposes only instrumented egress and records attempted callback channels)
- AML.T0025 Exfiltration via Cyber Means
- AML.T0097 Virtualization/Sandbox Evasion (pre-execution analysis detects sandbox evasion techniques)
- AML.T0119 Exploit Automated Artifact Processing Pipeline (policy-designated artifacts are processed only inside a credential-free, deny-by-default detonation boundary)
MAESTRO
- Agent Tool Misuse (L7)
- Lateral Movement (Cross-Layer)
- Resource Hijacking (L4)
OWASP LLM Top 10 2026
- LLM04:2026 Supply Chain (detonation exposes malicious behavior in executable dependencies before promotion)
OWASP ML Top 10 2023
- N/A
OWASP Top 10 for Agentic Applications 2026
- ASI05:2026 Unexpected Code Execution (RCE)
NIST Adversarial Machine Learning 2025
- N/A
Cisco Integrated AI Security and Safety Framework
- AISubtech-12.1.3 Unsafe System / Browser / File Execution (artifact detonation reports observed code, filesystem and network violations)
- AISubtech-12.2.1 Code Detection / Malicious Code Output (generated-code detonation finds prohibited behavior before downstream approval)
- AISubtech-9.1.1 Code Execution (artifact detonation reports observed code, filesystem and network violations)
- AISubtech-9.1.2 Unauthorized or Unsolicited System Access (artifact detonation reports observed code, filesystem and network violations)
- AISubtech-9.1.3 Unauthorized or Unsolicited Network Access (artifact detonation reports observed code, filesystem and network violations)
- AISubtech-9.3.1 Malicious Package / Tool Injection (dynamic analysis finds executable dependency and model-loader violations)
- AITech-12.1 Tool Exploitation (artifact detonation reports observed code, filesystem and network violations)
- AITech-12.2 Insecure Output Handling (generated-code detonation finds prohibited behavior before downstream approval)
- AITech-9.1 Model or Agentic System Manipulation (artifact detonation reports observed code, filesystem and network violations)
- AITech-9.2 Detection Evasion (long-sleep rules flag a narrow dynamic-analysis evasion signal)
- AITech-9.3 Dependency / Plugin Compromise (dynamic analysis finds executable dependency and model-loader violations)
Google Secure AI Framework 2.0 - Risks
- N/A
Databricks AI Security Framework 3.0
- Algorithms 5.4: Malicious libraries (behavioral analysis detects malicious library behavior)
- Agents - Core 13.11: Unexpected RCE and Code Attacks