Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions examples/.claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/Users/riyandhiman/Library/Python/3.9/bin/agsec check --format=claude-code --policy-dir /Users/riyandhiman/project/agsec/examples/policies",
"timeout": 30
}
]
}
]
}
}
108 changes: 108 additions & 0 deletions examples/anthropic_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
"""
Real Anthropic example with agsec protection.

Run: pip install agsec[anthropic] && export ANTHROPIC_API_KEY=sk-ant-...
python examples/anthropic_example.py
"""

import json

from anthropic import Anthropic

from agsec.integrations.anthropic import protect, allow, deny, review, param

# Protect the client — one line
client = protect(
Anthropic(),
allow("get_weather", "search"),
deny("delete_user"),
deny("run_sql").when(param("query").contains("DROP")),
review("send_email"),
)

# Define tools
tools = [
{
"name": "get_weather",
"description": "Get weather for a city",
"input_schema": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
{
"name": "delete_user",
"description": "Delete a user account",
"input_schema": {
"type": "object",
"properties": {"user_id": {"type": "string"}},
"required": ["user_id"],
},
},
{
"name": "run_sql",
"description": "Run a SQL query",
"input_schema": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
},
]

print("=== Test 1: Safe request (weather) ===")
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "What's the weather in Paris?"}],
tools=tools,
)

for block in response.content:
if block.type == "tool_use":
print(f" ALLOWED: {block.name}({json.dumps(block.input)})")
elif block.type == "text":
print(f" Text: {block.text}")

if hasattr(response, "_agsec_blocked") and response._agsec_blocked:
for b in response._agsec_blocked:
print(f" BLOCKED: {b['name']} — {b['reason']}")


print("\n=== Test 2: Dangerous request (delete user) ===")
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Delete user xyz789 from the system"}],
tools=tools,
)

for block in response.content:
if block.type == "tool_use":
print(f" ALLOWED: {block.name}({json.dumps(block.input)})")
elif block.type == "text":
print(f" Text: {block.text}")

if hasattr(response, "_agsec_blocked") and response._agsec_blocked:
for b in response._agsec_blocked:
print(f" BLOCKED: {b['name']} — {b['reason']}")


print("\n=== Test 3: Conditional block (SQL injection) ===")
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
messages=[{"role": "user", "content": "Run this query: DROP TABLE users"}],
tools=tools,
)

for block in response.content:
if block.type == "tool_use":
print(f" ALLOWED: {block.name}({json.dumps(block.input)})")
elif block.type == "text":
print(f" Text: {block.text}")

if hasattr(response, "_agsec_blocked") and response._agsec_blocked:
for b in response._agsec_blocked:
print(f" BLOCKED: {b['name']} — {b['reason']}")
84 changes: 50 additions & 34 deletions examples/claude_code_setup.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,58 @@
"""
agsec + Claude Code — setup firewall in 30 seconds.
Claude Code + agsec setup — run this script to set everything up.

Run this script or use the CLI commands below.
Run: pip install agsec
python examples/claude_code_setup.py
"""

import os
import subprocess
import sys

print("""
=== agsec Claude Code Setup ===

Three commands to protect your agent:

1. pip install agsec
2. agsec init
3. agsec install claude-code

That's it. The firewall is active.

--- What gets blocked by default ---

rm -rf / BLOCKED (file deletion)
cat .env BLOCKED (secret access)
git push --force BLOCKED (force push)
git push origin main BLOCKED (protected branch)
curl --data secrets.json BLOCKED (data exfiltration)

--- What gets allowed ---

ls, grep, find ALLOWED (read ops)
python -m pytest ALLOWED (safe bash)
git push origin feature/x ALLOWED (feature branch)

--- Manage policies ---

agsec policy list # see all rules
agsec policy add # add a rule (interactive)
agsec policy remove <sid> # remove a rule
agsec validate # check for errors
agsec audit --stats # view activity
""")
def main():
print("=== agsec + Claude Code Setup ===\n")

# Step 1: Check if policies exist
has_policies = os.path.isdir("policies") or os.path.isdir(".agsec/policies")

if not has_policies:
print("1. Creating policies...")
result = subprocess.run(
[sys.executable, "-m", "agsec", "init"],
capture_output=True, text=True,
)
print(f" {result.stdout.strip().split(chr(10))[0]}")
else:
print("1. Policies already exist.")

# Step 2: Install hook
print("\n2. Installing Claude Code hook...")
result = subprocess.run(
[sys.executable, "-m", "agsec", "install", "claude-code"],
capture_output=True, text=True,
)
print(f" {result.stdout.strip().split(chr(10))[0]}")

# Step 3: Show current policies
print("\n3. Active policies:")
result = subprocess.run(
[sys.executable, "-m", "agsec", "policy", "list"],
capture_output=True, text=True,
)
for line in result.stdout.strip().split("\n"):
print(f" {line}")

# Step 4: Validate
print("\n4. Validating...")
result = subprocess.run(
[sys.executable, "-m", "agsec", "validate"],
capture_output=True, text=True,
)
print(f" {result.stdout.strip()}")

print("\n=== Done. Restart Claude Code to activate the firewall. ===")


if __name__ == "__main__":
main()
Loading
Loading