Skip to main content

Add your description here

Project description

PyIntents

pyintents

Declarative capability-based access control for Python functions.

Explore the docs »

Getting Started · Basic Usage · Latest Documentation · License


GitHub License GitHub forks GitHub commits since latest release GitHub Release Date GitHub Actions Workflow Status GitHub Actions Workflow Status PyPI - Downloads PyPI - Version GitHub contributors


📖 Overview

PyIntents brings capability-based security to Python. Functions declare what they are allowed to do via @intent decorators, and the runtime enforces these permissions at call time. Define namespaces with allow and disallow rules, propagate restrictions recursively, or selectively exempt trusted functions with without. Permissions are dynamic and layered — grant or revoke access at runtime without touching the original code. Ideal for plugin sandboxes, AI agent tool control, environment-specific security policies, and testing. Trust explicitly, fail safely. No more functions that quietly do whatever they want.


🚀 Getting Started

Installation

pip install pyintents

Quick Example

from pyintents import IntentNamespace

# Create a namespace that allows only print()
namespace = IntentNamespace(uses=[print])

@namespace.intent()
def safe_function():
    print("This is allowed")  # ✅

@namespace.intent()
def unsafe_function():
    import os
    os.system("rm -rf /")  # ❌ Raises IntentViolationError

🛡️ Basic Usage

1. Allow Specific Functions

namespace = IntentNamespace(uses=[print, len])

@namespace.intent()
def my_func():
    print("Hello")   # Allowed
    return len([1])  # Allowed

2. Recursive Enforcement

namespace = IntentNamespace(uses=[print], recursive=True)

def helper():
    print("Inside helper")

@namespace.intent()
def main():
    helper()  # Recursively validated

3. Exempt Trusted Functions

namespace = IntentNamespace(
    uses=[print, helper],
    without=[helper]  # Exempt from checks
)

@namespace.intent()
def main():
    helper()  # Called without validation
    print("OK")

4. Runtime Layering

base = IntentNamespace(uses=[print])

@base.intent(uses=[len])  # Adds len to permissions
def layered_func():
    print("Hi")
    return len("world")

5. Explicit Denial

namespace = IntentNamespace(
    uses=[print],
    deny=[os.system]
)

@namespace.intent()
def restricted():
    print("OK")
    os.system("echo bad")  # ❌ Explicitly denied

6. Local Functions

namespace = IntentNamespace(uses=[print])

def local_helper():
    pass

@namespace.intent(uselocals=True)
def main():
    local_helper()  # Allowed (local scope)

📦 API Reference

IntentNamespace

Parameter Type Description
uses list[Callable] Allowed functions
recursive bool Enable recursive validation (default: False)
without list[Callable] Exempt functions from validation
uselocals bool Allow local functions (default: False)
deny list[Callable] Explicitly forbidden functions

@intent() Decorator

Overrides namespace settings per function:

@namespace.intent(
    uses=[print],           # Override allowed functions
    recursive=True,         # Override recursion
    without=[helper],       # Override exemptions
    uselocals=True,         # Override local scope
    deny=[os.system]        # Override denials
)
def custom_func():
    pass

⚠️ Exceptions

IntentViolationError

Raised when a function violates declared permissions:

from pyintents.exceptions import IntentViolationError

try:
    func()
except IntentViolationError as e:
    print(e)  # Function 'func' calls forbidden 'os.system'

🔧 How It Works

  1. AST Parsing — PyIntents parses the function's source code using Python's ast module
  2. Call Tree Construction — Builds a tree of all function calls up to the specified depth
  3. Permission Resolution — Resolves call names to actual function objects
  4. Rule Matching — Validates each call against:
    • uses — allowed functions
    • deny — explicitly forbidden functions
    • without — exempt functions
    • uselocals — local scope exceptions
  5. Runtime Enforcement — Validates at call time, raising IntentViolationError on violations

Limitations

  • Source Code Required — Functions must have source code available (not built-ins or C extensions)
  • Dynamic Calls — Calls via getattr() or eval() cannot be statically analyzed
  • Depth Limit — Recursion depth is capped to prevent infinite loops

🎯 Use Cases

Use Case Description
Plugin Sandboxes Restrict what third-party plugins can do
AI Agent Control Limit tool access for LLM agents
Environment Policies Enforce different rules per environment (dev/staging/prod)
Testing Isolate unit tests from external dependencies
Security Audits Document and enforce capability boundaries

📄 License

Licensed under the GNU General Public License v3.0.

See LICENSE for details.


🤝 Contributing

Contributions are welcome! Feel free to open issues, submit PRs, or suggest features.


📚 Documentation


🌟 Support

If you find PyIntents useful, consider:

  • ⭐ Starring the repository on GitHub
  • 🐛 Reporting issues
  • 💡 Suggesting features
  • 📖 Improving documentation

Trust explicitly. Fail safely.

↑ Back to top

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

pyintents-0.1.0.tar.gz (6.3 kB view details)

Uploaded Source

Built Distribution

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

pyintents-0.1.0-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file pyintents-0.1.0.tar.gz.

File metadata

  • Download URL: pyintents-0.1.0.tar.gz
  • Upload date:
  • Size: 6.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pyintents-0.1.0.tar.gz
Algorithm Hash digest
SHA256 30aa02f0a86f7a49b91e37e7c0e047f2c6a711420accc1b96da5acc92328339f
MD5 3ee60acf094dcf4c091cbe709e020110
BLAKE2b-256 671f3252abb655f4f848ff0081655cd6dd7b637033171e53970352a4664f49a5

See more details on using hashes here.

File details

Details for the file pyintents-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pyintents-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.29 {"installer":{"name":"uv","version":"0.11.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pyintents-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b6d7125f0dee76d8e53b136b7873870ed27f6e335998db2bd57f26c8ab42a7e0
MD5 f6696f74f1eaaf8c321d2cec30a7c55f
BLAKE2b-256 2463e54425dadbbc922e8609fd040a849776b26ced411e8056601f5145435370

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