Repository navigation
Expand file tree
/
Copy pathgallery.py
More file actions
91 lines (77 loc) · 2.42 KB
/
Copy pathgallery.py
File metadata and controls
91 lines (77 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"""
Recusal, gate scenario gallery (offline, no API key).
Robustness across the common autonomous-agent failure modes, mapped to the
OWASP Top 10 for Agentic Applications (2026). Each row is a proposed agent action,
the deterministic verdict, and what the gate does.
python examples/gallery.py
"""
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from scenarios import ( # noqa: E402
action_budget,
coverage_floor,
data_exfiltration,
destructive_path,
unscoped_sql,
wrong_subject,
)
from recusal import compute_verdict # noqa: E402
ACTIVE = "C1001"
# (label, OWASP category, proposed action, findings)
CASES = [
(
"wrong-subject write",
"ASI03 Identity Abuse",
"update_customer_record(C-9988)",
wrong_subject({"customer_id": "C-9988"}, ACTIVE),
),
(
"destructive file delete",
"ASI02 Tool Misuse",
"delete_file(/etc/passwd)",
destructive_path({"path": "/etc/passwd"}),
),
(
"unscoped SQL mutation",
"ASI05 Code Execution",
"run_sql(DELETE FROM orders)",
unscoped_sql({"sql": "DELETE FROM orders"}),
),
(
"data exfiltration",
"ASI01 Goal Hijack",
"send_email(attacker@evil.com)",
data_exfiltration({"to": "attacker@evil.com"}),
),
("coverage floor", "quality gate", "merge_pr(coverage=61%)", coverage_floor(61)),
("runaway action volume", "ASI08 Cascading", "150 tool calls this run", action_budget(150)),
(
"compliant write",
"-",
"update_customer_record(C1001)",
wrong_subject({"customer_id": "C1001"}, ACTIVE),
),
]
def _outcome(v):
if v.passed and v.warnings:
return "ALLOW (warned)"
if v.passed:
return "ALLOW"
if v.retryable:
return "BLOCK (retry)"
return "REFUSE"
def main():
print("RECUSAL - gate scenarios (offline)\n")
print(f" {'scenario':<24}{'OWASP':<22}{'verdict':<8}outcome")
print(" " + "-" * 70)
for label, owasp, _action, findings in CASES:
v = compute_verdict(findings)
print(f" {label:<24}{owasp:<22}{v.decision.value:<8}{_outcome(v)}")
print(
"\n CRITICAL -> REFUSE (terminal) | ERROR -> BLOCK (retry once) | "
"WARNING -> ALLOW + record | clean -> ALLOW"
)
if __name__ == "__main__":
main()