Governed LLM client for regulated AI deployments — drop-in replacement for openai.OpenAI()
Project description
evecore — Governed LLM for Regulated AI
Drop-in replacement for openai.OpenAI() that enforces governance policy before and after every model call, writes a signed audit record, and raises GovernanceVetoError when a rule is violated.
Install
pip install evecore # core only (no provider deps)
pip install "evecore[openai]" # + OpenAI provider
pip install "evecore[anthropic]" # + Anthropic provider
pip install "evecore[proxy]" # + OpenAI-compatible proxy server
pip install "evecore[all]" # everything
Quickstart
from evecore import GovernedLLM
client = GovernedLLM(policy="financial-v1")
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "What is the current prime rate?"}]
)
print(response.choices[0].message.content)
print(response.governance.certificate_id) # audit trail reference
Or with the simple interface:
result = client.complete("What is the current prime rate?")
print(result)
Handling vetoes
from evecore import GovernedLLM
from evecore.exceptions import GovernanceVetoError
client = GovernedLLM(policy="financial-v1")
try:
response = client.complete("Approve loan for $500,000")
except GovernanceVetoError as e:
print(e.verdict) # REQUIRE_HUMAN_REVIEW
print(e.rule_id) # fin.high_value_approval
print(e.reason) # Amount meets or exceeds $250,000 threshold
print(e.certificate_id) # gov-a1b2c3d4e5f6... (audit trail reference)
OpenAI-compatible proxy
The proxy lets existing applications get governance with one line change:
# Start the proxy
python -m evecore.proxy --policy financial-v1 --port 4141
# Before
from openai import OpenAI
client = OpenAI(api_key="sk-...")
# After — one line changed, everything else stays identical
from openai import OpenAI
client = OpenAI(base_url="http://localhost:4141/v1", api_key="any")
The proxy intercepts every request, runs governance, and returns blocked responses in the same OpenAI format so your existing error handling still works.
Built-in policies
| Policy ID | Domain | Key rules |
|---|---|---|
financial-v1 |
Banking / lending / insurance | PII blocking, high-value approval gates, investment advice warnings, 7-year audit retention |
healthcare-v1 |
Healthcare / HIPAA | PHI blocking, no-diagnosis enforcement, emergency escalation |
general-v1 |
General purpose | Prompt injection blocking, PII leak warnings |
Custom policies
from evecore import GovernedLLM
from evecore._policy import register_policy
register_policy({
"id": "my-org-policy",
"name": "My Org Policy",
"version": "1.0.0",
"input_rules": [
{
"id": "org.block_competitor",
"action": "BLOCK",
"reason": "Competitor mention blocked",
"priority": 100,
"keywords": ["competitor_name"]
},
{
"id": "org.flag_large_deal",
"action": "REQUIRE_HUMAN_REVIEW",
"reason": "Deal value requires human approval",
"priority": 80,
"triggers": ["approve", "sign", "commit"],
"amount_threshold": 50000.0,
"amount_pattern": r"\$([0-9,]+(?:\.\d{2})?)"
}
],
"output_rules": [
{
"id": "org.no_guarantees",
"action": "WARN",
"reason": "Response contains guarantee language",
"priority": 60,
"patterns": [r"\b(guarantee|guaranteed|we promise)\b"]
}
]
})
client = GovernedLLM(policy="my-org-policy")
Or load from a JSON file:
client = GovernedLLM(policy="/path/to/my-policy.json")
Rule actions
| Action | Behavior |
|---|---|
BLOCK |
Raises GovernanceVetoError(verdict="BLOCKED") — request/response is stopped |
REQUIRE_HUMAN_REVIEW |
Raises GovernanceVetoError(verdict="REQUIRE_HUMAN_REVIEW") by default |
ESCALATE |
Raises GovernanceVetoError(verdict="ESCALATE") by default |
WARN |
Logs the warning; execution continues (unless raise_on_warn=True) |
ALLOW |
Rule did not trigger; no action taken |
Rule fields
{
"id": "rule.unique_id",
"action": "BLOCK | WARN | REQUIRE_HUMAN_REVIEW | ESCALATE",
"reason": "Human-readable explanation shown in GovernanceVetoError",
"priority": 100,
"patterns": ["regex1", "regex2"],
"keywords": ["keyword1", "keyword2"],
"triggers": ["trigger_word"],
"amount_threshold": 250000.0,
"amount_pattern": "\\$([0-9,]+(?:\\.\\d{2})?)"
}
Higher priority rules are evaluated first. When multiple rules trigger, the highest-priority action wins (BLOCK > ESCALATE > REQUIRE_HUMAN_REVIEW > WARN > ALLOW).
Audit log
Every request produces two signed audit records (input governance + output governance) written to a JSONL file:
data/audit/governed_llm_audit.jsonl (default location)
Records are HMAC-SHA256 signed and hash-chained — any tampering is detectable. Signing key sourced from EVE_AUDIT_KEY env var (or EVE_JWT_SECRET, or a dev fallback).
Each record includes:
event_id,certificate_id,timestamppolicy_id,verdict,rule_id,reasonprompt_hash,response_hash(SHA-256, privacy-preserving — no raw text stored)model,providersignature(HMAC-SHA256)record_hash,prev_hash(hash chain)
Providers
| Provider | provider= |
API key env var |
|---|---|---|
| OpenAI | "openai" |
OPENAI_API_KEY |
| Anthropic | "anthropic" |
ANTHROPIC_API_KEY |
| Local (Ollama, LM Studio) | "local" |
— |
| Auto-detect | "auto" (default) |
Checks env vars |
# Auto-detect from environment
client = GovernedLLM(policy="financial-v1")
# Explicit provider
client = GovernedLLM(policy="financial-v1", provider="anthropic")
# Azure OpenAI or other compatible endpoint
client = GovernedLLM(
policy="financial-v1",
provider="openai",
base_url="https://my-org.openai.azure.com/",
api_key="azure-key",
)
# Local Ollama
client = GovernedLLM(policy="general-v1", provider="local")
GovernedLLM parameters
| Parameter | Default | Description |
|---|---|---|
policy |
"general-v1" |
Policy ID or path to JSON file |
provider |
"auto" |
LLM provider |
api_key |
None |
Provider API key (falls back to env vars) |
base_url |
None |
Override provider base URL |
audit_log |
None |
Path to audit JSONL file |
raise_on_block |
True |
Raise GovernanceVetoError on BLOCK/ESCALATE/REQUIRE_HUMAN_REVIEW |
raise_on_warn |
False |
Raise GovernanceVetoError on WARN |
Proxy options
python -m evecore.proxy --help
--policy financial-v1, healthcare-v1, general-v1, or /path/to/policy.json
--port Port to listen on (default: 4141)
--host Host to bind (default: 127.0.0.1)
--upstream Upstream provider URL (default: https://api.openai.com)
--api-key Provider API key (falls back to OPENAI_API_KEY)
--audit-log Path to audit JSONL file
--log-level DEBUG | INFO | WARNING | ERROR
Running tests
cd sdks/evecore
pip install -e ".[dev]"
pytest tests/ -v
Tests are fully offline — all provider calls are mocked. No API keys required.
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 evecore-0.1.0.tar.gz.
File metadata
- Download URL: evecore-0.1.0.tar.gz
- Upload date:
- Size: 49.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b9196546a5cdfd5a15bb71257d37419de6283d31f5a57fc1ec632bb58597727a
|
|
| MD5 |
735df053ebe9252f7f83723b6e7ae56f
|
|
| BLAKE2b-256 |
f3e24519dbbb6d54bc711e924ffb49c7095ede5bb5dfc6adad70a959aeb09459
|
File details
Details for the file evecore-0.1.0-py3-none-any.whl.
File metadata
- Download URL: evecore-0.1.0-py3-none-any.whl
- Upload date:
- Size: 41.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1d83ffaf1982a4bd21171385615efd7749079883a9ed61015fdcc27a8051d8e
|
|
| MD5 |
b6a97b28f0aeee3ea23385a5d5278e1e
|
|
| BLAKE2b-256 |
2c0bfddedd8880819604cff8219934ec0871fe766959ac3ebda3970b7ecda9c1
|