Repository navigation
examples: add ACS + Agent Threat Rules (ATR) annotator (#3018) - #3025
Imran Siddique (imran-siddique) merged 1 commit into
Conversation
Adds examples/acs-atr-annotator/: a custom ACS policy backed by a host annotator dispatcher that runs the open-source Agent Threat Rules engine (pyatr) over the policy target and denies on a match. - ATRAnnotator.dispatch runs ATR and returns a free-form annotation; the thin ATRPolicy.evaluate translates it into an ACS verdict (deny on match, else allow). Verdicts use only decision/reason/evidence -- no effects[] (AGT D1). Evidence carries rule IDs + verification links. - pyatr is an optional, pre-1.0 dependency: lazy import with a clear ImportError; tests use pytest.importorskip. - Validated against the ACS runtime: demo.py and test_atr_annotator.py run through agent_control_specification (from PyPI) and assert deny on injection / allow on benign at both the input and pre_tool_call intervention points. Addresses microsoft#3018. Signed-off-by: Adam Lin <adam@agentthreatrule.org>
🤖 AI Agent: test-generator — `examples/acs-atr-annotator/atr_adapter.py`
|
🤖 AI Agent: docs-sync-checker — Docs Sync
Docs Sync
|
🤖 AI Agent: security-scanner — View details
No security issues found. |
🤖 AI Agent: code-reviewer — Action items:
TL;DR: 0 blockers, 2 warnings. The pull request introduces a new example for integrating the Agent Threat Rules (ATR) engine with the ACS runtime. The implementation appears sound, but there are minor areas for improvement.
Action items:
| Warnings: fine as follow-up PRs. | |
🤖 AI Agent: breaking-change-detector — API Compatibility
API Compatibility
|
PR Review Summary
Verdict: AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims. |
|
🔴 Contributor Check: HIGH
Automated check by AGT Contributor Check. |
Imran Siddique (imran-siddique)
left a comment
There was a problem hiding this comment.
Examples-only, clean design — annotator dispatches detection, policy translates verdict shape, no reimplementation of detection logic. Lazy import for the optional pyatr dep is correct. Fails closed on dispatcher exception. No effects[] post-D1. Smoke tests cover dispatcher logic with the real engine skipped when unavailable. Good work.
1e31dc8
into
microsoft:main
* fix(ci): add tzdata, pyatr, nono-py to dep-confusion allowlist All three are registered PyPI packages flagged after recent merges: - tzdata: IANA tz database (Windows tz support in agent-os) - pyatr: AGT audit trail record library (acs-atr-annotator example, PR #3025) - nono-py: OS-native sandbox bindings (agt-sandbox[nono], PR #3029) Signed-off-by: Imran Siddique <imran.siddique@opaque.co> * fix(ci): add tzdata and pyatr to cspell allowlist Signed-off-by: Imran Siddique <imran.siddique@opaque.co> --------- Signed-off-by: Imran Siddique <imran.siddique@opaque.co>
… (microsoft#3025) Adds examples/acs-atr-annotator/: a custom ACS policy backed by a host annotator dispatcher that runs the open-source Agent Threat Rules engine (pyatr) over the policy target and denies on a match. - ATRAnnotator.dispatch runs ATR and returns a free-form annotation; the thin ATRPolicy.evaluate translates it into an ACS verdict (deny on match, else allow). Verdicts use only decision/reason/evidence -- no effects[] (AGT D1). Evidence carries rule IDs + verification links. - pyatr is an optional, pre-1.0 dependency: lazy import with a clear ImportError; tests use pytest.importorskip. - Validated against the ACS runtime: demo.py and test_atr_annotator.py run through agent_control_specification (from PyPI) and assert deny on injection / allow on benign at both the input and pre_tool_call intervention points. Addresses microsoft#3018. Signed-off-by: Adam Lin <adam@agentthreatrule.org> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
…soft#3033) * fix(ci): add tzdata, pyatr, nono-py to dep-confusion allowlist All three are registered PyPI packages flagged after recent merges: - tzdata: IANA tz database (Windows tz support in agent-os) - pyatr: AGT audit trail record library (acs-atr-annotator example, PR microsoft#3025) - nono-py: OS-native sandbox bindings (agt-sandbox[nono], PR microsoft#3029) Signed-off-by: Imran Siddique <imran.siddique@opaque.co> * fix(ci): add tzdata and pyatr to cspell allowlist Signed-off-by: Imran Siddique <imran.siddique@opaque.co> --------- Signed-off-by: Imran Siddique <imran.siddique@opaque.co> Signed-off-by: jlaportebot <jlaportebot@gmail.com>
Closes #3018.
Adds
examples/acs-atr-annotator/— acustomACS policy backed by a host annotator dispatcher that runs the open-source Agent Threat Rules engine (pyatr) over the policy target and denies on a match. This is the runtime/behavioral enforcement counterpart to the static control mapping indocs/mappings/atr-agt-mapping.md; they sit at different levels and don't overlap.Following the guidance in #3018:
ATRAnnotator.dispatchruns ATR and returns a free-form annotation; the thinATRPolicy.evaluatetranslates it into an ACS verdict (denyon match, elseallow). The adapter only does shape translation — it does not re-implement detection.decision/reason/evidence; noeffects[](AGT D1). Theevidencepayload carries the matched rule IDs plus a verification pointer per rule.pyatris an optional, pre-1.0 dependency: imported lazily with a clearImportError; tests usepytest.importorskip. A dispatcher exception fails closed (runtime_error:annotation_failed).manifest.yamlusestype: customwith a configurablerules_dir/min_severityinadapter_config, wired at both theinputandpre_tool_callintervention points.Validated against the ACS runtime, not just unit-mocked.
demo.pyandtest_atr_annotator.pyload the manifest throughagent_control_specificationand assertdenyon injection /allowon benign at both intervention points:pytest test_atr_annotator.py→ 4 passed (dispatcher logic + ACS runtime e2e). License headers added perscripts/check_license_headers.py; commit is DCO-signed.Imran Siddique (@imran-siddique) — ready for review per your note on #3018. Happy to adjust naming, placement, or the annotator/policy split.