mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-08-03 01:10:18 +03:00
Add 55 new skills across 3 new domains + 6 undercovered areas (762 -> 817)
Demand-driven expansion targeting the fastest-growing 2025-2026 threat and
skills categories (ISC2/WEF/CrowdStrike/Mandiant signals):
- AI Security (NEW domain, 12 skills): LLM red-teaming with garak/PyRIT,
prompt injection (direct/indirect/RAG), MCP tool-poisoning, agentic tool
invocation, guardrails, model/data poisoning, system-prompt leakage,
embedding/vector weaknesses, model extraction, continuous red-teaming
- Supply Chain Security (NEW domain, 5 skills): SBOMs, dependency confusion,
malicious-npm triage, typosquatting, SLSA/Sigstore provenance
- Hardware & Firmware Security (NEW domain, 4 skills): CHIPSEC/UEFI audit,
Secure Boot bypass, TPM measured-boot attestation, ESP bootkit hunting
- Identity (10): Entra ID/ROADtools, GraphRunner, AADInternals, ADCS/Certipy,
shadow credentials, coercion, BloodHound CE, device-code phishing, SSO abuse
- Cloud-native (8): Stratus, Pacu, CloudFox, container escape, K8s RBAC,
Falco, Trivy, kube-bench
- Offensive C2 (6): Sliver, Havoc, NetExec, DPAPI, NTLM relay ESC8, redirectors
- DFIR (6): Hayabusa, Chainsaw, KAPE, Velociraptor, EZ Tools, Plaso
- Backfill (4): OpenCTI, MISP, honeytokens, post-quantum crypto migration
Each skill follows the repo taxonomy (SKILL.md + references/{standards,api-reference}.md
+ scripts/agent.py + LICENSE), with researched real tool commands (no placeholders),
complete frontmatter, and ATT&CK/ATLAS + NIST CSF mappings. Updates README domain
table, skill count, and index.json.
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python3
|
||||
# Defensive AI-security control. Deploy on agents you own/operate.
|
||||
"""Agentic AI tool-invocation policy gate.
|
||||
|
||||
Implements deny-by-default tool allowlisting, per-tool JSON-schema argument
|
||||
validation, an allow/require_approval/deny decision, an interactive human-in-the-loop
|
||||
approval gate for high-impact tools, and a structured audit log for SIEM ingestion.
|
||||
|
||||
Examples:
|
||||
python agent.py --tool search_docs --args '{"query":"vpn policy"}'
|
||||
python agent.py --tool send_email --args '{"to":"a@example.com","subject":"x","body":"y"}'
|
||||
python agent.py --tool transfer_funds --args '{"amount":50}' --auto-approve
|
||||
"""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
|
||||
try:
|
||||
from jsonschema import validate, ValidationError
|
||||
except ImportError:
|
||||
print("Install: pip install jsonschema", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
# Impact tiers and approval requirements (deny-by-default: unknown tools rejected).
|
||||
TOOL_POLICY = {
|
||||
"search_docs": {"impact": "read", "approval": False},
|
||||
"create_ticket": {"impact": "write", "approval": False},
|
||||
"send_email": {"impact": "high", "approval": True},
|
||||
"transfer_funds":{"impact": "high", "approval": True},
|
||||
"run_shell": {"impact": "high", "approval": True},
|
||||
}
|
||||
|
||||
# Per-tool argument allowlists.
|
||||
TOOL_SCHEMAS = {
|
||||
"search_docs": {
|
||||
"type": "object",
|
||||
"properties": {"query": {"type": "string", "maxLength": 500}},
|
||||
"required": ["query"], "additionalProperties": False,
|
||||
},
|
||||
"create_ticket": {
|
||||
"type": "object",
|
||||
"properties": {"title": {"type": "string", "maxLength": 200},
|
||||
"body": {"type": "string", "maxLength": 5000}},
|
||||
"required": ["title"], "additionalProperties": False,
|
||||
},
|
||||
"send_email": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"to": {"type": "string", "pattern": r"^[^@\s]+@example\.com$"},
|
||||
"subject": {"type": "string", "maxLength": 200},
|
||||
"body": {"type": "string", "maxLength": 5000},
|
||||
},
|
||||
"required": ["to", "subject", "body"], "additionalProperties": False,
|
||||
},
|
||||
"transfer_funds": {
|
||||
"type": "object",
|
||||
"properties": {"amount": {"type": "number", "minimum": 0, "maximum": 1000},
|
||||
"account": {"type": "string"}},
|
||||
"required": ["amount"], "additionalProperties": False,
|
||||
},
|
||||
"run_shell": {
|
||||
"type": "object",
|
||||
"properties": {"cmd": {"type": "string", "enum": ["ls", "whoami", "df -h"]}},
|
||||
"required": ["cmd"], "additionalProperties": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def validate_args(tool, args):
|
||||
schema = TOOL_SCHEMAS.get(tool)
|
||||
if schema is None:
|
||||
return False, "no schema (deny-by-default)"
|
||||
try:
|
||||
validate(instance=args, schema=schema)
|
||||
return True, "ok"
|
||||
except ValidationError as exc:
|
||||
return False, f"schema: {exc.message}"
|
||||
|
||||
|
||||
def authorize(tool, args, actor):
|
||||
policy = TOOL_POLICY.get(tool)
|
||||
if policy is None:
|
||||
return _event("deny", tool, args, actor, "tool not in allowlist")
|
||||
ok, why = validate_args(tool, args)
|
||||
if not ok:
|
||||
return _event("deny", tool, args, actor, why)
|
||||
if policy["approval"]:
|
||||
return _event("require_approval", tool, args, actor,
|
||||
f"high-impact ({policy['impact']})")
|
||||
return _event("allow", tool, args, actor, "allowlisted")
|
||||
|
||||
|
||||
def _event(decision, tool, args, actor, reason):
|
||||
return {
|
||||
"ts": datetime.now(timezone.utc).isoformat(), "actor": actor, "tool": tool,
|
||||
"args_sha256": hashlib.sha256(
|
||||
json.dumps(args, sort_keys=True).encode()).hexdigest(),
|
||||
"decision": decision, "reason": reason, "atlas": "AML.T0053",
|
||||
}
|
||||
|
||||
|
||||
def hitl_prompt(event, auto_approve):
|
||||
"""Fail-closed human-in-the-loop gate."""
|
||||
if auto_approve:
|
||||
return True
|
||||
if not sys.stdin.isatty():
|
||||
return False # no interactive approver -> deny
|
||||
ans = input(f"APPROVAL: call {event['tool']} "
|
||||
f"(args {event['args_sha256'][:12]})? [y/N] ").strip().lower()
|
||||
return ans == "y"
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser(description="Agentic AI tool-invocation policy gate")
|
||||
ap.add_argument("--tool", required=True, help="Tool the agent wants to call")
|
||||
ap.add_argument("--args", default="{}", help="JSON tool arguments")
|
||||
ap.add_argument("--actor", default="agent-session", help="Acting user/session id")
|
||||
ap.add_argument("--auto-approve", action="store_true",
|
||||
help="Auto-approve HITL (testing only)")
|
||||
ap.add_argument("--audit-log", help="Append audit events to this JSONL file")
|
||||
args = ap.parse_args()
|
||||
|
||||
try:
|
||||
tool_args = json.loads(args.args)
|
||||
if not isinstance(tool_args, dict):
|
||||
raise ValueError("args must be a JSON object")
|
||||
except (json.JSONDecodeError, ValueError) as exc:
|
||||
print(f"[!] Invalid --args: {exc}", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
event = authorize(args.tool, tool_args, args.actor)
|
||||
|
||||
if event["decision"] == "require_approval":
|
||||
approved = hitl_prompt(event, args.auto_approve)
|
||||
event["decision"] = "allow" if approved else "deny"
|
||||
event["reason"] += "; approved" if approved else "; not approved (fail-closed)"
|
||||
|
||||
print(json.dumps(event, indent=2))
|
||||
if args.audit_log:
|
||||
with open(args.audit_log, "a", encoding="utf-8") as fh:
|
||||
fh.write(json.dumps(event) + "\n")
|
||||
|
||||
sys.exit(0 if event["decision"] == "allow" else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user