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.3.tar.gz (51.5 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.3-py3-none-any.whl (45.6 kB view details)

Uploaded Python 3

File details

Details for the file evecore-0.1.3.tar.gz.

File metadata

  • Download URL: evecore-0.1.3.tar.gz
  • Upload date:
  • Size: 51.5 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.3.tar.gz
Algorithm Hash digest
SHA256 54b209696ca9f6012739102d224da9c4b88c8331083ae436cd010cc4fa83d2ca
MD5 b814f1bd34853c605360cdb4535528fc
BLAKE2b-256 033d69c8bf0c987de6394c318135ba2011552590756be42d9b6cdf4487d0e114

See more details on using hashes here.

File details

Details for the file evecore-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: evecore-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 45.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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 c9c9c38f172cca78cb0120ea180be8b66ff66190ff087b4e51f49e4fcd6603e9
MD5 2513a90f485b15dae6d7b2263a7b1c60
BLAKE2b-256 35819d1e1118ca31d76aa9aaba8913f589053deb11f789e5b01ae080f2c928ec

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