Skip to main content

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, timestamp
  • policy_id, verdict, rule_id, reason
  • prompt_hash, response_hash (SHA-256, privacy-preserving — no raw text stored)
  • model, provider
  • signature (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


Download files

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

Source Distribution

evecore-0.1.0.tar.gz (49.3 kB view details)

Uploaded Source

Built Distribution

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

evecore-0.1.0-py3-none-any.whl (41.6 kB view details)

Uploaded Python 3

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

Hashes for evecore-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b9196546a5cdfd5a15bb71257d37419de6283d31f5a57fc1ec632bb58597727a
MD5 735df053ebe9252f7f83723b6e7ae56f
BLAKE2b-256 f3e24519dbbb6d54bc711e924ffb49c7095ede5bb5dfc6adad70a959aeb09459

See more details on using hashes here.

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

Hashes for evecore-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f1d83ffaf1982a4bd21171385615efd7749079883a9ed61015fdcc27a8051d8e
MD5 b6a97b28f0aeee3ea23385a5d5278e1e
BLAKE2b-256 2c0bfddedd8880819604cff8219934ec0871fe766959ac3ebda3970b7ecda9c1

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