Python SDK for Aegis LLM Inference Firewall
Project description
aegis-firewall
Python SDK for Aegis LLM Inference Firewall.
Installation
pip install aegis-firewall
Quick Start
Synchronous Client
from aegis import AegisClient, AegisFirewall
# Create client
client = AegisClient(
base_url="http://localhost:8080",
api_key="your-api-key",
)
# Create firewall wrapper
firewall = AegisFirewall(client)
# Add user message
user_span = firewall.add_user_message("Send email to john@example.com")
# Execute tool call with taint tracking
result = firewall.safe_execute_tool_call(
"tool.send_email",
{"to": "john@example.com", "subject": "Hello"},
[user_span.id]
)
if result["success"]:
print("Tool call executed successfully")
else:
print(f"Tool call failed: {result['error']}")
Asynchronous Client
import asyncio
from aegis import AegisAsyncClient, AegisAsyncFirewall
async def main():
async with AegisAsyncClient(
base_url="http://localhost:8080",
api_key="your-api-key",
) as client:
firewall = AegisAsyncFirewall(client)
# Add user message
user_span = await firewall.add_user_message("Send email")
# Execute tool call
result = await firewall.safe_execute_tool_call(
"tool.send_email",
{"to": "john@example.com"},
[user_span.id]
)
print(f"Success: {result['success']}")
asyncio.run(main())
Features
- ✅ Type-safe API - Full type hints with Pydantic
- ✅ Async support - Both sync and async clients
- ✅ Taint tracking - Automatic span management
- ✅ Policy builder - Programmatic policy creation
- ✅ Approval workflows - Human-in-the-loop support
- ✅ Error handling - Rich error types
API Reference
AegisClient
client = AegisClient(
base_url="http://localhost:8080",
api_key="optional-api-key",
timeout=30.0,
retries=3,
)
Methods
validate_tool_call(tool_call)- Validate tool callcreate_span(span_data)- Create new spanget_span(span_id)- Get span by IDlist_decisions(session_id=None)- List decisionsget_approval(approval_id)- Get approvallist_approvals()- List pending approvalsapprove(approval_id)- Approve requestdeny(approval_id, reason)- Deny requestget_trace(session_id)- Get traceverify_trace(bundle_data)- Verify tracehealth()- Health check
AegisFirewall
firewall = AegisFirewall(client)
Methods
add_user_message(content)- Add user messageadd_document(content, sensitivity=...)- Add RAG documentadd_system_prompt(content)- Add system promptexecute_tool_call(capability, args, source_span_ids)- Execute tool callsafe_execute_tool_call(...)- Safe execution with error handlingget_session_spans()- Get all spansclear_session()- Clear session
PolicyBuilder
from aegis import PolicyBuilder, TrustLevel
policy = (
PolicyBuilder()
.allow("tool.read_calendar", TrustLevel.UNTRUSTED_USER)
.allow("tool.send_email", TrustLevel.UNTRUSTED_USER, requires_approval=True)
.deny("payments.*", TrustLevel.UNTRUSTED_DOCUMENT)
.block_untrusted_documents()
.block_secret_data()
.require_approval_for_high_risk()
.auto_deny_after(30)
.build()
)
# Export as .aegis format
aegis_format = PolicyBuilder().allow("tool.send_email").to_aegis_format()
Examples
RAG with Document Isolation
from aegis import AegisClient, AegisFirewall, SensitivityLevel
client = AegisClient(base_url="http://localhost:8080")
firewall = AegisFirewall(client)
# Add user query
user_span = firewall.add_user_message("What is our pricing?")
# Add retrieved documents (automatically marked as untrusted)
doc = firewall.add_document("Pricing: $99/month", SensitivityLevel.PUBLIC)
# Tool call sourced only from documents will be BLOCKED
result = firewall.safe_execute_tool_call(
"tool.send_email",
{"to": "attacker@evil.com"},
[doc.id] # Only document source - blocked by taint tracking!
)
assert not result["success"], "Should be blocked"
Approval Workflow
def handle_approval(approval_id: str):
print(f"Waiting for approval: {approval_id}")
# Notify admin, poll for status, etc.
result = firewall.safe_execute_tool_call(
"tool.execute_code",
{"code": "print('hello')"},
[user_span.id],
on_approval_required=handle_approval
)
Async Example
import asyncio
from aegis import AegisAsyncClient, AegisAsyncFirewall
async def main():
async with AegisAsyncClient("http://localhost:8080") as client:
firewall = AegisAsyncFirewall(client)
user_span = await firewall.add_user_message("Hello")
result = await firewall.execute_tool_call(
"tool.search_web",
{"query": "weather"},
[user_span.id]
)
print(f"Allowed: {result.allowed}")
asyncio.run(main())
Error Handling
from aegis import (
CapabilityBlockedError,
ApprovalRequiredError,
NetworkError,
)
try:
result = client.validate_tool_call(tool_call)
except CapabilityBlockedError as e:
print(f"Blocked: {e.capability} - {e.reason}")
except ApprovalRequiredError as e:
print(f"Approval needed: {e.approval_id}")
await handle_approval(e.approval_id)
except NetworkError as e:
print(f"Network error: {e.status_code}")
Development
# Install dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
black aegis/
# Type check
mypy aegis/
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
aegis_firewall-2.0.0.tar.gz
(14.8 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aegis_firewall-2.0.0.tar.gz.
File metadata
- Download URL: aegis_firewall-2.0.0.tar.gz
- Upload date:
- Size: 14.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85548b43f017e068b5fc424c1b54c9d4a7096fa63d1235b4ca61318eb48f40fd
|
|
| MD5 |
ba0f73a874283375f28a463bc5d2ee84
|
|
| BLAKE2b-256 |
2740aa0fa572b393564ff7421bb46a70d8f4a785de3cd5ba9cd2688c5dfb659f
|
File details
Details for the file aegis_firewall-2.0.0-py3-none-any.whl.
File metadata
- Download URL: aegis_firewall-2.0.0-py3-none-any.whl
- Upload date:
- Size: 15.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
59b90bed942240ac3ad6cb34d0425fffac33e057a55cf574aa0954accfa99769
|
|
| MD5 |
7095ac04090b097ebdc6d32c5da1dedc
|
|
| BLAKE2b-256 |
592a5b3d79971925eb94d7fa54de9dfa3f0bdde2543bf80e17abd78827e74416
|