Policy-as-Code for AI Agents. Secure your LLM's access to tools with decorators and safe proxies.
Project description
Gondolin
Gondolin is a security framework for AI Agents. It acts as a "Safe Proxy" layer between your LLM and sensitive Python libraries (like Jira, Stripe, AWS, or internal tools).
Named after the legendary Hidden City protected by seven gates, Gondolin enforces Policy-as-Code to ensure your Agent never executes dangerous actions, even if it tries.
Features
- Zero Boilerplate: No need to write wrapper scripts for every API call.
- Policy-as-Code: Define allowed methods and security rules in a simple YAML file.
- Decorator-Based Logic: Use standard Python decorators to enforce limits (e.g.,
max_amount=500), logging, or authorization. - Recursive Proxies: Automatically protects nested objects (e.g.,
client.users.delete). - Import Interception: Prevents the Agent from importing the "real" dangerous library.
Installation
pip install gondolin
Quick Start
1. Define your Policies (policy_config.yaml)
Define method allowlist and map to a list of policy decorators. Each lib entry must include target_class (the class that will be proxied).
libs:
jira:
target_class: "JIRA"
policies:
# Simple Allow
search_issues:
- audit_log
# Parametrized Logic
assign_issue:
- audit_log
- require_reason
# Dangerous Action (Not listed = Blocked by default)
# delete_issue: []
# Nested paths are supported (e.g., "sub.deep_action").
2. Define your Decorators (policy_decorators.py)
Write standard Python decorators to implement your business logic.
from gondolin import Registry
import logging
decorator_registry = Registry()
logger = logging.getLogger("Audit")
@decorator_registry.register("audit_log")
def audit_log(func):
def wrapper(*args, **kwargs):
logger.info(f"Agent calling {func.__name__} with {args} {kwargs}")
return func(*args, **kwargs)
return wrapper
@decorator_registry.register("require_reason")
def require_reason(func):
def wrapper(*args, **kwargs):
if "reason" not in kwargs:
raise PermissionError(f"SOP Violation: You must provide a 'reason' argument to call {func.__name__}")
return func(*args, **kwargs)
return wrapper
# Decorator args: {"limit": 5} passes 5 positionally; {"limit": {"max": 5}} passes kwargs.
3. Initialize Gondolin (main.py)
Run the setup before your Agent starts.
from gondolin import setup
from policy_decorators import decorator_registry
# 1. Bootstrap the environment
# This reads the YAML and monkey-patches sys.modules
setup("policy_config.yaml", decorator_registry)
# 2. Agent Execution
# When the Agent runs this, it gets the Safe Proxy, not the raw lib.
import jira
client = jira.JIRA(server="https://jira.example.com")
# ✅ Allowed (Logged)
client.search_issues("project = PROJ")
# ❌ Blocked (Raises PermissionError)
client.delete_issue("PROJ-1")
Architecture
Gondolin works by dynamically creating a Module Facade. When setup() is called, it:
- Imports the real library in the background.
- Creates a fake module that mimics the real structure.
- Injects a SafeProxy class that intercepts all attribute access.
- Replaces the real library in
sys.moduleswith the Safe Proxy.
Validation: setup rejects malformed configs (missing target_class/policies, non-list rules, non-string rule names/keys).
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
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 gondolin-0.1.1.tar.gz.
File metadata
- Download URL: gondolin-0.1.1.tar.gz
- Upload date:
- Size: 8.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cebc28e123daac50f3b8c81e7551cd107f87233545f6c7614b82d403fdbbae2a
|
|
| MD5 |
eac55a58134c3c4617107aaa7a94c23b
|
|
| BLAKE2b-256 |
89a6561d0ced3fda547cec675dbcd038d016de94938c1d8803b290f048e7e220
|
File details
Details for the file gondolin-0.1.1-py3-none-any.whl.
File metadata
- Download URL: gondolin-0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cfd79923076ceb01970826541b9281d9f346ccc2059b224d7b5c68e82192249
|
|
| MD5 |
244a72240425978cb0ec29f0ea682815
|
|
| BLAKE2b-256 |
e9f59e0e679d2e3f47140d6df33e7fe9ceb6a21027f6f95c922b0a8020d62194
|