Apohara · governance

COMPLIANCE

Audit what your agent did — not just what your repo contains.

A deterministic Rust scanner that maps an AI coding agent's observed actions — or a repository — to compliance and agentic-security framework controls, surfacing candidate risks with citations for a human to confirm.

Candidates for human review — guidance/mapping only, never an assertion of compliance. v1.1.0 tagged · v2.x on main, not yet tagged (Pablo-gated).
$cargo install apohara-compliance
View source →

The candidate-findings report

Candidates with citations, never verdicts — what the scanner actually emits.

$apohara-compliance-scanner scan-session session.jsonl --format md
compliance scanner matches five observed signals (rm -rf, sudo, curl http, SELECT star FROM, act as) into five candidate findings, then prints the candidate-findings markdown with suggested controls and NIST citations under a guidance-only, candidates-not-assertions disclaimer

Candidates with citations, never verdicts — each maps a triggering signal to controls a human confirms. SARIF 2.1.0 + Markdown output, CI-ready. v2.2 carries the bound triple on real AgentDyn successes (169/236 last-gen open-ended) with the honest co-headline (28.7 % FP on resisted, ~20 % precision-on-success).

Framework coverage

One signal resolves across a ten-framework crosswalk — each carried control traces to a cited source.

OWASP Agentic
Top 10 for Agentic Applications · 2026 · ASI01–ASI10 · AGT-MEM-001 (ASI06) · AGT-TRJ-001/002/003
OWASP Agentic Skills
Skills Top 10 · 2026 · AST01–AST10 · draft
OWASP LLM
Top 10 for LLM Applications · 2025 · LLM-layer cross-refs
MITRE ATLAS
5.6.0 · adversarial ML techniques
ISO 42001
2023 · AI management system
EU AI Act
Reg. (EU) 2024/1689 · high-risk obligations
NIST AI RMF
1.0 · Govern / Map / Measure / Manage
NIST SP 800-53
Rev 5 · security & privacy controls
SOC 2
AICPA TSC 2017 · trust services criteria
ISO 27001
2022 · information security

What it does

Three scan surfaces · five additive passes (v1.0 → v2.2) · one deterministic crosswalk · CI-ingestible output.

Observed-action scan

scan-session session.jsonl

Reads an agent's session transcript and maps what it actually did — every tool call — to framework controls. Action-level coverage, not just files at rest.

Repository scan

scan-repo .

Walks a repository (respecting .gitignore) and maps its contents to the same frameworks. A gitignore-aware static surface alongside the action-level one.

OTLP telemetry scan

scan-otlp ./otel-export.json

Reads OTLP-exported logs/traces an OpenTelemetry exporter wrote to disk (offline, file-only — no socket). Post-hoc and exporter-bounded.

Multi-action sequence

AGT-MEM-001 · v1.1 · ASI06

Opt-in additive pass correlates an ordered pair — untrusted content followed by a write to a memory/RAG sink — to surface OWASP ASI06 (Memory & Context Poisoning) candidates. Candidate-only, never a runtime guarantee.

Trajectory taint + repr-aware

AGT-TRJ-001/002/003 · v2.0 / v2.1

Additive v2.0 pass correlates injection markers in tool-result: data the agent READ with later sensitive sinks (exfil / destructive / financial). v2.1 closes the representation gap with a reserved sink: channel + const SINK_GRAMMAR role tokens. Post-hoc; recognisable-in-log ≠ would-have-prevented.

Real-trajectory efficacy

ADR-6 · v2.2 · bound triple + ceiling

Same frozen rules run over real successful indirect-injection trajectories (AgentDyn): 169 / 236 (71.6 %) post-hoc recognition on last-gen open-ended, with the honest co-headline — 28.7 % FP on resisted, ~20 % precision-on-success. A correlation surfacer, NOT a success / causation discriminator.

CI-ready output

--format sarif | md | json

SARIF 2.1.0 + Markdown, ingestible by code scanning. Deterministic — no LLM, same input ⇒ same bytes. Suppressions supported via project config.

Gap analysis + baseline diff

gap · --baseline <prior.json> --only-new

Gap lists carried controls with no candidate evidence — "no signal observed for X", never "you fail X". Baseline diff emits only new findings via SARIF baselineState.

Structural shell tokenizer

AGT-MIS-004 · v2.1

A shlex-backed pass catches flag-reordered destructive commands a substring scan cannot (rm -r -f / rm -fr / quoted-arg variants), folded into AGT-MIS-004. sink: channel excluded from the single-action loop by a one-line guard.

Honest by design

The product's core integrity claim — what it gives you, and what it is not.

What it gives you

  • Deterministic mapping of triggering signals → controls, each carrying a citation (ID, name, version, source). 49 carried controls across the 10-framework crosswalk.
  • Observed-action coverage — what the agent did, not just static repo contents, plus OTLP-exported telemetry from disk (offline, file-only).
  • SARIF 2.1.0 for CI — findings land as note/warning, ingestible by code scanning. Gap analysis lists carried controls with no observed signal; baseline diff emits only new findings.
  • Reproducible, no LLM in the path — same input produces the same bytes out. Lineage: v1.0 / v1.1 / v1.4 / v2.0 / v2.1 / v2.2 on main; v1.1.0 is the latest crates.io / GitHub Release tag.

What it is NOT

  • Not a certification, attestation, or audit conclusion — running it does not make a project "compliant".
  • Findings are CANDIDATES a qualified human must confirm — a please-confirm, never a verdict.
  • Mapping / guidance only — it does not assert legal or regulatory compliance, and is no substitute for counsel.

Quick start

Install, scan, then confirm or suppress each candidate.

Install the scanner — builds from source, the lowest-trust path.
$ cargo install apohara-compliance
Scan an agent session transcript — Markdown for humans, or --format sarif for CI.
$ apohara-compliance-scanner scan-session session.jsonl --format md
Scan OTLP-exported telemetry (logs/traces) the OTel exporter wrote to disk — offline, file-only.
$ apohara-compliance-scanner scan-otlp ./otel-export.json --format sarif
Diff against a prior run — emit only NEW findings via SARIF baselineState.
$ apohara-compliance-scanner scan-repo . --baseline baseline.json --only-new --format sarif
v1.1.0 tagged v2.x on main (Pablo-gated) Dual MIT / Apache-2.0 Rust 1.74+ SARIF 2.1.0 49 carried controls 10-framework crosswalk OpenSSF Scorecard Candidates, not verdicts Offline & deterministic