Skip to main content

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:

  1. Imports the real library in the background.
  2. Creates a fake module that mimics the real structure.
  3. Injects a SafeProxy class that intercepts all attribute access.
  4. Replaces the real library in sys.modules with the Safe Proxy.

Validation: setup rejects malformed configs (missing target_class/policies, non-list rules, non-string rule names/keys).

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gondolin-0.1.1.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gondolin-0.1.1-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

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

Hashes for gondolin-0.1.1.tar.gz
Algorithm Hash digest
SHA256 cebc28e123daac50f3b8c81e7551cd107f87233545f6c7614b82d403fdbbae2a
MD5 eac55a58134c3c4617107aaa7a94c23b
BLAKE2b-256 89a6561d0ced3fda547cec675dbcd038d016de94938c1d8803b290f048e7e220

See more details on using hashes here.

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

Hashes for gondolin-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6cfd79923076ceb01970826541b9281d9f346ccc2059b224d7b5c68e82192249
MD5 244a72240425978cb0ec29f0ea682815
BLAKE2b-256 e9f59e0e679d2e3f47140d6df33e7fe9ceb6a21027f6f95c922b0a8020d62194

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page