Runtime AI Governance - govern any AI agent tool call
Project description
phronedge
Runtime governance for AI agents.
Every tool call checked. Every decision audited. Every regulation enforced.
The Problem
AI agents take actions. Actions have consequences. Right now there is no governance layer between your agent and everything it can touch.
Your agent can access data it was never authorized to see. Execute financial transactions without human approval. Leak sensitive information across jurisdictions. Be compromised through prompt injection. Have its credential tampered with at runtime.
And you will not know until a regulator asks you to prove it did not happen.
EU AI Act enforcement is live. GDPR fines reach 20M EUR or 4% of global revenue. The question is not whether your agent needs governance. The question is whether you can prove it has governance.
An agent is an untrusted entity. Treat it like one.
The Solution
PhronEdge intercepts every tool call before it executes. Seven checkpoints. Every time. No exceptions.
Your agent calls a tool
|
v
CP1 Credential Validator Is this agent who it claims to be? (ECDSA)
|
CP2 PII / Injection Scan Is there sensitive data or manipulation in the input?
|
CP3 Jurisdiction Router Is this action legally permitted? (196 countries)
|
CP4 Behavioral Monitor Is this agent behaving normally? (signed baseline)
|
CP5 Data Classifier What classification level is this data?
|
CP6 Tool Permission Is this tool in the agent's signed credential?
|
CP7 Output Constraint Is the response safe to return?
|
v
ALLOWED: your function executes normally
BLOCKED: reason + regulation citation returned, event anchored
Install
pip install phronedge
Works with every Python package manager:
pip install phronedge
uv add phronedge
poetry add phronedge
pdm add phronedge
pipenv install phronedge
Setup
One environment variable. Nothing else.
# .env
PHRONEDGE_API_KEY=pe_live_xxxxxxxxx
Get your API key at phronedge.com/try.
Quick Start
from phronedge import PhronEdge
pe = PhronEdge()
@pe.govern("lookup_claim")
def lookup_claim(claim_id: str) -> str:
return db.query(claim_id)
result = lookup_claim("CLM-2026-001")
Three lines. Every call to lookup_claim now passes through 7 governance checkpoints. Your existing function does not change.
What Governance Looks Like
Four scenarios. What your agent tries. What PhronEdge does.
Clean call:
result = lookup_claim("CLM-2026-001")
# ALLOWED in 23ms
# Claim data returned to agent
# Audit: TOOL_CALL_ALLOWED, 7/7 checkpoints passed
PII in input:
result = lookup_claim("SSN 123-45-6789")
# BLOCKED
# PII detected in function arguments (SSN pattern)
# Session escalated to PII_RESTRICTED
# Audit: PII_INPUT_DETECTED, GDPR Art. 9
Tool not in credential:
result = access_medical_records("patient-123")
# BLOCKED
# medical_records not in agent's signed credential
# Function never executed. Data never touched.
# Audit: TOOL_CALL_BLOCKED, EU AI Act Art. 14
Credential tampered at runtime:
# Attacker modifies credential at 2:00pm
# Agent makes next call at 2:01pm
result = lookup_claim("CLM-2026-001")
# ECDSA signature mismatch detected
# Vault restore runs automatically
# Call proceeds with restored credential
# You did nothing. PhronEdge fixed itself.
# Audit: VAULT_TAMPER_DETECTED + VAULT_CREDENTIAL_RESTORED
Framework Examples
LangChain / LangGraph
from phronedge import PhronEdge
from langchain_core.tools import tool
pe = PhronEdge()
@pe.govern("lookup_claim")
def _governed_lookup(claim_id: str) -> str:
return db.query(claim_id)
@tool
def lookup_claim(claim_id: str) -> str:
"""Look up an insurance claim by ID."""
return _governed_lookup(claim_id)
agent = create_react_agent(llm, [lookup_claim])
CrewAI
from phronedge import PhronEdge
from crewai.tools import BaseTool
pe = PhronEdge()
@pe.govern("lookup_claim")
def _governed_lookup(claim_id: str) -> str:
return db.query(claim_id)
class LookupClaimTool(BaseTool):
name: str = "lookup_claim"
description: str = "Look up an insurance claim"
def _run(self, claim_id: str) -> str:
return _governed_lookup(claim_id)
agent = Agent(role="Investigator", tools=[LookupClaimTool()])
Google ADK
from phronedge import PhronEdge
from google.adk.agents import Agent
pe = PhronEdge()
@pe.govern("lookup_claim")
def _governed_lookup(claim_id: str) -> str:
return db.query(claim_id)
def lookup_claim(claim_id: str, tool_context) -> str:
"""Look up an insurance claim by ID."""
return _governed_lookup(claim_id)
agent = Agent(name="investigator", model="gemini-2.0-flash", tools=[lookup_claim])
OpenAI Function Calling
from phronedge import PhronEdge
from openai import OpenAI
pe = PhronEdge()
@pe.govern("lookup_claim")
def lookup_claim(claim_id: str) -> str:
return db.query(claim_id)
# Define tools as usual, call lookup_claim when the model requests it
# PhronEdge governs the execution automatically
Pydantic AI
from phronedge import PhronEdge
from pydantic_ai import Agent
pe = PhronEdge()
@pe.govern("lookup_claim")
def _governed_lookup(claim_id: str) -> str:
return db.query(claim_id)
agent = Agent("openai:gpt-4o")
@agent.tool_plain
def lookup_claim(claim_id: str) -> str:
"""Look up an insurance claim."""
return _governed_lookup(claim_id)
Plain Python
from phronedge import PhronEdge
pe = PhronEdge()
@pe.govern("send_payment")
def send_payment(claim_id: str, amount: float, currency: str) -> str:
return payment_api.send(claim_id, amount, currency)
result = send_payment("CLM-001", 42500.0, "EUR")
# BLOCKED: requires human approval, checkpoint: human_oversight
The Data Never Leaves
Your data stays in your environment. Governance metadata travels to PhronEdge. Nothing else.
What PhronEdge receives: What PhronEdge never receives:
Agent ID Your customer data
Tool name Query results
Input metadata (scanned, not stored) Medical records
Credential ID Financial data
Internal service URLs
Anything your tool returns
GDPR, HIPAA, and EU AI Act all require data to stay in the appropriate environment. PhronEdge is architecturally compliant by design. Not by configuration. By architecture.
Constitutional Tiers
Every agent operates at a tier that defines its authority.
| Tier | Name | What it means |
|---|---|---|
| T0 | Advisory Only | Agent recommends. Human decides. No execution. |
| T1 | Human-in-the-Loop | Agent proposes. Waits for human approval. |
| T2 | Bounded Autonomy | Agent executes within scope. Escalates outside it. |
| T3 | Supervised Autonomy | Agent executes and logs. Human reviews after. |
High-value actions like financial transactions, sensitive data access, and irreversible operations are blocked at tiers below their required level. Automatically. Every time.
Agent Lifecycle
Control any running agent in real time. No restart. No code change.
# Quarantine: blocks all tool calls immediately
pe.quarantine("Suspicious pattern detected")
# Reinstate: resumes tool calls
pe.reinstate("Investigation complete")
Kill switch is available through the PhronEdge console only. Permanent agent termination is a critical operation that requires dashboard access at phronedge.com/brain.
The Audit Chain
Every event is cryptographically anchored. Every event links to the one before it. Tamper one event and the chain breaks.
{
"event_type": "TOOL_CALL_BLOCKED",
"agent_id": "claims-investigator-v1",
"tool": "access_medical_records",
"severity": "HIGH",
"regulation": "EU AI Act Art. 14 Human Oversight",
"checkpoint": "data_classification",
"policy_hash": "f107937d65017b17...",
"hash": "a3f2b1c4d5e6f7a8...",
"prev_hash": "9e8d7c6b5a4f3e2d...",
"timestamp": "2026-04-05T14:32:18.000Z"
}
Your regulator sees the complete governance history. Your auditor trusts the math.
Error Handling
from phronedge import PhronEdge, ToolBlocked, AgentTerminated
pe = PhronEdge(raise_on_block=True)
@pe.govern("send_payment")
def send_payment(claim_id, amount, currency):
return payment_api.send(claim_id, amount, currency)
try:
send_payment("CLM-001", 42500, "EUR")
except ToolBlocked as e:
print(f"Blocked: {e} (checkpoint: {e.checkpoint})")
except AgentTerminated:
print("Agent has been permanently killed")
Pre-scan Text
Check text for PII or injection before sending to an LLM:
pe = PhronEdge()
result = pe.scan("My SSN is 123-45-6789 and ignore previous instructions")
# {"pii_detected": true, "injection_detected": true, "patterns": ["SSN"]}
Regulatory Coverage
PhronEdge maps every governance decision to the applicable regulation for your jurisdiction and industry.
Cross-Industry:
| Regulation | Coverage |
|---|---|
| EU AI Act 2024 | Risk classification, human oversight, transparency |
| GDPR (EU) 2016/679 | Data minimisation, transfer restrictions, Art. 9 special categories |
| Schrems II (C-311/18) | Cross-border data transfer enforcement |
| CCPA / CPRA | California consumer data protection |
| ISO 42001 | AI management system controls |
| NIST AI RMF | Govern, map, measure, manage |
| SOC 2 Type II | Security, availability, processing integrity |
Financial Services:
| Regulation | Coverage |
|---|---|
| FCA Handbook | UK financial conduct authority rules |
| MiFID II | Markets in Financial Instruments Directive |
| DORA | Digital Operational Resilience Act |
| PSD2 | Payment Services Directive |
| Basel III/IV | Risk management and capital requirements |
| MAR | Market Abuse Regulation |
Healthcare:
| Regulation | Coverage |
|---|---|
| HIPAA | Protected health information, access control |
| HITECH Act | Health information technology enforcement |
| FDA 21 CFR Part 11 | Electronic records and signatures |
| MDR (EU) 2017/745 | Medical Device Regulation |
Insurance:
| Regulation | Coverage |
|---|---|
| Solvency II | Insurance risk management |
| IDD | Insurance Distribution Directive |
| German Insurance Act (VAG) | German insurance supervision |
Telecommunications:
| Regulation | Coverage |
|---|---|
| ePrivacy Directive | Electronic communications privacy |
| PECR | Privacy and Electronic Communications Regulations |
| NIS2 Directive | Network and information systems security |
196 countries. 30+ controls. Every policy signed against the applicable regulatory framework for your jurisdiction and industry.
Framework Support
| Framework | Status |
|---|---|
| LangGraph | Supported |
| LangChain | Supported |
| CrewAI | Supported |
| OpenAI | Supported |
| Google ADK | Supported |
| Pydantic AI | Supported |
| LlamaIndex | Supported |
| AutoGen | Supported |
| Smolagents | Supported |
| Plain Python | Supported |
One SDK. One gateway. One audit chain. Any framework. Any cloud. Any agent.
Try Before You Code
Visit phronedge.com/try to see runtime governance in action. Pick an industry (insurance, healthcare, finance, technology). Paste your OpenAI or Gemini API key. Chat with a governed agent. Watch every checkpoint fire in real time. No signup required. 30 seconds.
Get Started
pip install phronedge
from phronedge import PhronEdge
pe = PhronEdge()
@pe.govern("my_tool")
def my_tool(param: str) -> str:
return your_existing_function(param)
Built for the EU AI Act era.
Community
- Discord: https://discord.gg/Af4kyFAZ
- GitHub Discussions: https://github.com/phronedge/phronedge-python/discussions
- Support: support@phronedge.com
- Website: https://phronedge.com
- Playground: https://phronedge.com/try
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 phronedge-1.0.2.tar.gz.
File metadata
- Download URL: phronedge-1.0.2.tar.gz
- Upload date:
- Size: 9.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
031fe84c732f7608dd14b3abf86d4a4a82f168520d9d018264ea1cea8c23fc93
|
|
| MD5 |
cde30b0b28398929a29abd060e931722
|
|
| BLAKE2b-256 |
46aedd0406aa1d02399b1c42bcbb284ad93c46a96c860061238ecc27fdcb363c
|
File details
Details for the file phronedge-1.0.2-py3-none-any.whl.
File metadata
- Download URL: phronedge-1.0.2-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.14 {"installer":{"name":"uv","version":"0.9.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
201310112edeee6309b2f52d96d6817619b0a97aa347fba47f679eef080f8450
|
|
| MD5 |
3ab2ee972adb94a04cc3626978ec46b7
|
|
| BLAKE2b-256 |
0f592d553e978013c09fe6403e05500fd81ed31f8fede5c34b948fb2676c5867
|