Open-source policy & approval runtime for AI agents acting on systems you don't own
Project description
Aegis
Governance layer for AI agents. Policy engine + approval gate + audit log.
Your AI agent can browse the web, call APIs, and modify SaaS data.
Aegis makes sure it asks permission first.
Quick Start • Documentation • Integrations • Contributing
English • 한국어
The Problem
AI agents are getting real-world access. Without governance, a hallucinating agent can:
- Bulk-delete your CRM contacts
- Submit wrong forms to government portals
- Trigger irreversible API calls at 3am
- Run up cloud bills with infinite loops
There's no sudo for AI agents. Until now.
The Solution
Action Policy Approval Execute Audit
| | | | |
read CRM --> auto (low) --> skip -------> run ------> logged
bulk edit --> approve (high) --> human y/n -> run ------> logged
delete * --> block (critical) ------------> X --------> logged
Aegis sits between your agent and the real world. 3 lines to add governance:
from aegis import Action, Policy, Runtime
runtime = Runtime(executor=your_executor, policy=Policy.from_yaml("policy.yaml"))
results = await runtime.run_one(Action("write", "salesforce", params={...}))
Quick Start
pip install agent-aegis
1. Generate a policy
aegis init # Creates policy.yaml with sensible defaults
# policy.yaml
version: "1"
defaults:
risk_level: medium
approval: approve
rules:
- name: read_safe
match: { type: "read*" }
risk_level: low
approval: auto
- name: bulk_ops_need_approval
match: { type: "bulk_*" }
conditions:
param_gt: { count: 100 } # Only when count > 100
risk_level: high
approval: approve
- name: no_deletes
match: { type: "delete*" }
risk_level: critical
approval: block
2. Add to your agent
import asyncio
from aegis import Action, Policy, Runtime
from aegis.adapters.base import BaseExecutor
from aegis.core.result import Result, ResultStatus
class MyExecutor(BaseExecutor):
async def execute(self, action):
print(f" Executing: {action.type} -> {action.target}")
return Result(action=action, status=ResultStatus.SUCCESS)
async def main():
async with Runtime(
executor=MyExecutor(),
policy=Policy.from_yaml("policy.yaml"),
) as runtime:
plan = runtime.plan([
Action("read", "crm", description="Fetch contacts"),
Action("bulk_update", "crm", params={"count": 150}),
Action("delete", "crm", description="Drop table"),
])
print(plan.summary())
results = await runtime.execute(plan)
asyncio.run(main())
3. See what happened
aegis audit
ID Session Action Target Risk Decision Result
1 a1b2c3d4... read crm LOW auto success
2 a1b2c3d4... bulk_update crm HIGH approved success
3 a1b2c3d4... delete crm CRITICAL block blocked
Features
| Feature | Description |
|---|---|
| YAML policies | Glob matching, first-match-wins, JSON Schema for validation |
| Smart conditions | time_after, time_before, weekdays, param_gt/lt/eq/contains/matches |
| 4-tier risk model | low / medium / high / critical with per-rule overrides |
| Approval gates | CLI prompt, callback functions, or build your own (Slack, Discord, etc.) |
| Audit trail | SQLite (default), JSONL export, or Python logging backend |
| Context manager | async with Runtime(...) as rt: — auto setup/teardown |
| Single-action mode | await runtime.run_one(action) for simple cases |
| JSON Schema | aegis schema — auto-complete in VS Code / JetBrains |
| Policy generator | aegis init — starter policy in seconds |
| Type-safe | Full mypy --strict compliance, py.typed marker |
Integrations
Works with the agent frameworks you already use:
pip install 'agent-aegis[langchain]' # LangChain
pip install 'agent-aegis[crewai]' # CrewAI
pip install 'agent-aegis[openai-agents]' # OpenAI Agents SDK
pip install 'agent-aegis[httpx]' # REST APIs
pip install 'agent-aegis[playwright]' # Browser automation
pip install 'agent-aegis[all]' # Everything
LangChain — wrap tools or expose governed actions
from aegis.adapters.langchain import LangChainExecutor, AegisTool
# Wrap existing LangChain tools with governance
executor = LangChainExecutor(tools=[DuckDuckGoSearchRun()])
runtime = Runtime(executor=executor, policy=Policy.from_yaml("policy.yaml"))
# Or expose governed actions AS LangChain tools
tool = AegisTool.from_runtime(runtime, name="governed_search",
description="Policy-governed search", action_type="search", action_target="web")
OpenAI Agents SDK — decorator-based governance
from aegis.adapters.openai_agents import governed_tool
@governed_tool(runtime=runtime, action_type="write", action_target="crm")
async def update_contact(name: str, email: str) -> str:
"""Update a CRM contact — governed by Aegis policy."""
return await crm.update(name=name, email=email)
CrewAI — governed tools for crews
from aegis.adapters.crewai import AegisCrewAITool
tool = AegisCrewAITool(runtime=runtime, name="governed_search",
description="Search with governance", action_type="search",
action_target="web", fn=lambda query: do_search(query))
Anthropic Claude — govern tool_use calls
from aegis.adapters.anthropic import govern_tool_call
for block in response.content:
if block.type == "tool_use":
result = await govern_tool_call(
runtime=runtime, tool_name=block.name,
tool_input=block.input, target="my_system")
httpx — governed REST API calls
from aegis.adapters.httpx_adapter import HttpxExecutor
executor = HttpxExecutor(base_url="https://api.example.com",
default_headers={"Authorization": "Bearer ..."})
runtime = Runtime(executor=executor, policy=Policy.from_yaml("policy.yaml"))
# Action types map to HTTP methods: get, post, put, patch, delete
plan = runtime.plan([Action("get", "/users"), Action("delete", "/users/1")])
Custom adapters — 10 lines to integrate anything
from aegis.adapters.base import BaseExecutor
from aegis.core.action import Action
from aegis.core.result import Result, ResultStatus
class MyAPIExecutor(BaseExecutor):
async def execute(self, action: Action) -> Result:
response = await my_api.call(action.type, action.target, **action.params)
return Result(action=action, status=ResultStatus.SUCCESS, data=response)
async def verify(self, action: Action, result: Result) -> bool:
return result.data.get("status") == "ok"
Policy Conditions
Go beyond glob matching with smart conditions:
rules:
# Block writes after business hours
- name: after_hours_block
match: { type: "write*" }
conditions:
time_after: "18:00"
risk_level: critical
approval: block
# Escalate bulk operations over threshold
- name: large_bulk_ops
match: { type: "update*" }
conditions:
param_gt: { count: 100 }
risk_level: high
approval: approve
# Only allow deploys on weekdays
- name: weekday_deploys
match: { type: "deploy*" }
conditions:
weekdays: [1, 2, 3, 4, 5]
risk_level: medium
approval: approve
Available: time_after, time_before, weekdays, param_eq, param_gt, param_lt, param_gte, param_lte, param_contains, param_matches (regex).
Architecture
aegis/
core/ Action, Policy engine, Conditions, Risk levels, JSON Schema
adapters/ BaseExecutor, Playwright, httpx, LangChain, CrewAI, OpenAI, Anthropic
runtime/ Runtime engine, ApprovalHandler, AuditLogger (SQLite/JSONL/logging)
cli/ aegis validate | audit | schema | init
+----------------+
| Your Agent |
+-------+--------+
|
Action(type, target, params)
|
+-------v--------+
| Policy Engine | <-- policy.yaml (YAML rules + conditions)
+-------+--------+
|
PolicyDecision(risk, approval, rule)
|
+-------------+-------------+
| | |
auto: LOW approve: HIGH block: CRITICAL
| | |
v +------v------+ v
execute | Approval | blocked
| | Handler | |
| +------+------+ |
| | |
v v |
+---------+ +---------+ |
| Adapter | | Adapter | |
+---------+ +---------+ |
| | |
v v v
+------------------------------------+
| Audit Logger |
| (SQLite / JSONL / logging) |
+------------------------------------+
Why Not Build Your Own?
| DIY | Aegis | |
|---|---|---|
| Policy engine | Custom if/else per action | YAML rules + glob + conditions |
| Risk model | Hardcoded | 4-tier with per-rule overrides |
| Human approval | Build your own | Pluggable (CLI, Slack, custom) |
| Audit trail | printf debugging | SQLite + JSONL + session tracking |
| Framework support | Rewrite per framework | 6 adapters out of the box |
| Verification | Hope it worked | Post-execution verification hooks |
| Type safety | Maybe | mypy strict, py.typed |
| Time to integrate | Days | Minutes |
CLI
aegis init # Generate starter policy
aegis validate policy.yaml # Validate policy syntax
aegis schema # Print JSON Schema (for editor autocomplete)
aegis audit # View audit log
aegis audit --session abc --format json # Filter + format
aegis audit --format jsonl -o export.jsonl # Export
Roadmap
| Version | Status | Features |
|---|---|---|
| 0.1 | Released | Policy engine, 6 adapters, CLI, audit (SQLite + JSONL), conditions, JSON Schema |
| 0.2 | Planned | Dashboard UI, Slack/Discord approval, policy inheritance, hot-reload |
| 0.3 | Planned | MCP server adapter, rollback support, webhook notifications |
| 0.4 | Planned | Multi-tenant policies, team approvals, cloud audit storage |
Contributing
We welcome contributions! Check out:
- Good First Issues — great starting points
- Contributing Guide — setup, code style, PR process
- Architecture — how the codebase is structured
git clone https://github.com/Acacian/aegis.git && cd aegis
make dev # Install deps + hooks
make test # Run tests
make lint # Lint + format check
make coverage # Coverage report
Or jump straight into a cloud environment:
License
MIT -- see LICENSE for details.
Built for the era of autonomous AI agents.
If Aegis helps you, consider giving it a star -- it helps others find it too.
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
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 agent_aegis-0.1.3.tar.gz.
File metadata
- Download URL: agent_aegis-0.1.3.tar.gz
- Upload date:
- Size: 92.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
488a9775cd0c5d573b797e48a074a197f1fc6175e71610b1f37c64a367656132
|
|
| MD5 |
8c7a3f47c8c862eda626fe93cb2284f0
|
|
| BLAKE2b-256 |
d47abfd8a209c7ca7648f2cd4ab07146e958be83b817290a8bd25c873b8a0ecb
|
Provenance
The following attestation bundles were made for agent_aegis-0.1.3.tar.gz:
Publisher:
publish.yml on Acacian/aegis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_aegis-0.1.3.tar.gz -
Subject digest:
488a9775cd0c5d573b797e48a074a197f1fc6175e71610b1f37c64a367656132 - Sigstore transparency entry: 1152787600
- Sigstore integration time:
-
Permalink:
Acacian/aegis@0a5b666d45f1324747a99c84d99ea8e68bd18a30 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/Acacian
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0a5b666d45f1324747a99c84d99ea8e68bd18a30 -
Trigger Event:
release
-
Statement type:
File details
Details for the file agent_aegis-0.1.3-py3-none-any.whl.
File metadata
- Download URL: agent_aegis-0.1.3-py3-none-any.whl
- Upload date:
- Size: 38.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b78fbbe81fd15a9c3a5369b68cdd89b7912ac0628f4aefeec81c756462b913a
|
|
| MD5 |
3211ec93981eda187e3df21df0cd968b
|
|
| BLAKE2b-256 |
3e9db8011b05f13e68598d48a548bc90c5dc14ddc513f54195df39eadb8a584f
|
Provenance
The following attestation bundles were made for agent_aegis-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on Acacian/aegis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agent_aegis-0.1.3-py3-none-any.whl -
Subject digest:
1b78fbbe81fd15a9c3a5369b68cdd89b7912ac0628f4aefeec81c756462b913a - Sigstore transparency entry: 1152787878
- Sigstore integration time:
-
Permalink:
Acacian/aegis@0a5b666d45f1324747a99c84d99ea8e68bd18a30 -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/Acacian
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@0a5b666d45f1324747a99c84d99ea8e68bd18a30 -
Trigger Event:
release
-
Statement type: