EVE Core/ Docs/ Python SDK

API & integration

EVE CoreGuard Python SDK

The eve-coreguard Python SDK provides a typed, ergonomic interface to the EVE CoreGuard governance decision engine. Install it from PyPI, configure your API key, and your first governance-enforced evaluation is running in under five minutes.

Installation

The SDK requires Python 3.9 or later. It has zero required dependencies — it uses only the Python standard library (urllib) for HTTP transport. Install from PyPI:

$pip install eve-coreguard

The package is published on PyPI: pypi.org/project/eve-coreguard.

To pin to a specific version (recommended for production):

$pip install "eve-coreguard==0.2.10"

For projects using pyproject.toml:

[project]
dependencies = [
    "eve-coreguard>=0.1.0,<1.0.0",
]

Verify the installation:

$python -c "import eve_coreguard; print(eve_coreguard.__version__)" 0.2.10

Quick Start — 5 Lines

The following example evaluates a loan approval against the lending_v1 policy pack and prints the disposition. evaluate() takes keyword arguments directly — there is no request object to construct:

from eve_coreguard import CoreGuardClient

client = CoreGuardClient(api_key="eve_sk_...")
result = client.evaluate(
    tenant_id="bank_001",
    proposed_action={"type": "loan_approval", "amount": 250000},
    model_output={"decision": "approve", "confidence": 0.91},
    context={"credit_score": 580, "debt_to_income": 0.52},
    policy_set="lending_v1",
)
print(result.verdict)  # ALLOWED | BLOCKED | MODIFIED

API key security: Never hardcode your API key in source code. Load it from an environment variable: api_key=os.environ["COREGUARD_API_KEY"]. See Configuration for all available options.

Configuration

The CoreGuardClient accepts the following constructor parameters:

ParameterTypeDefaultDescription
api_keystrrequiredYour EVE CoreGuard API key. Recommended to load from environment variable COREGUARD_API_KEY.
base_urlstrhttps://api.evecore.comBase URL for the EVE CoreGuard API (https://api.eveaicore.com reaches the same platform). Override for on-premises or private cloud deployments.
timeoutfloat30.0Request timeout in seconds.
max_retriesint3Maximum number of retries on transient 5xx errors. Uses exponential backoff.
raise_on_vetoboolFalseIf True, verify() raises VetoError on a hard-veto or charter violation instead of returning a result.

Load the API key from the environment rather than hardcoding it:

import os
from eve_coreguard import CoreGuardClient

client = CoreGuardClient(api_key=os.environ["COREGUARD_API_KEY"])

evaluate() Parameters

Call client.evaluate() with keyword arguments. They map directly to the POST /v1/decisions/evaluate request body.

ParameterTypeDescription
tenant_idstrrequiredOrganization/tenant identifier. Recorded on the decision certificate.
proposed_actiondictrequiredThe action being evaluated. Include type plus pack-specific fields (e.g. amount).
model_outputdictrecommendedThe AI model's recommendation, e.g. {"decision": "approve", "confidence": 0.91}.
contextdictoptionalDomain-specific signals the policy evaluates (e.g. credit_score, debt_to_income). Defaults to empty dict.
policy_setstroptionalOptional assertion; omitted from the request unless set (0.2.11+; 0.2.10 and earlier always sent "lending_v1"). The server binds the pack from proposed_action["type"]; a mismatch is a signed BLOCK (COREGUARD.POLICY_BINDING_MISMATCH). See PolicyInfo.bound_action_types from list_policies(). On 0.2.10, pass the bound pack’s policy_id explicitly for any non-lending or custom-bound action type.
include_evidencebooloptionalDefault False. When True, the server attaches the signed governance evidence record; it is exposed as result.signed_governance, the input to verify_evidence_offline().
userdictoptionalActor context, e.g. {"id": "u_001", "role": "loan_officer"}. Defaults to an SDK client identity.
request_idstr or NoneoptionalIdempotency key. Auto-generated (UUID4) when omitted.
timestampstr or NoneoptionalISO 8601 timestamp. Defaults to the current UTC time.

Full example

result = client.evaluate(
    tenant_id="bank_001",
    user={"id": "u_892", "role": "loan_officer"},
    proposed_action={
        "type": "loan_approval",
        "applicant_id": "app_7823",
        "amount": 85000,
    },
    model_output={"decision": "approve", "confidence": 0.88},
    context={"credit_score": 712, "debt_to_income": 0.31, "employment_verified": True},
    policy_set="lending_v1",
    request_id="req_unique_0001",  # idempotency key (optional)
)

EvaluationResult Fields

The evaluate() method returns a frozen EvaluationResult dataclass with the following structure (plus convenience properties .verdict, .allowed, .blocked, .decision_id, .signature, .audit_hash):

FieldTypeDescription
decision.statusstrFinal disposition: "ALLOWED", "BLOCKED", or "MODIFIED". Also exposed as result.verdict.
decision.actionstrResolved action, e.g. "deny_loan_approval".
risk.scorefloatRisk score, 0.0–1.0.
risk.levelstr"LOW", "MEDIUM", or "HIGH".
risk.factorslist[str]Human-readable risk factors that fired.
policy_violationslist[PolicyViolation]Violations that fired. Each has .policy_id and .description. Empty for ALLOWED.
regulatory_impactlist[RegulatoryImpact]Each maps a violation to a regulation: .regulation (e.g. ECOA), .risk, .severity.
counterfactualCounterfactual or NoneThresholds that would have produced ALLOWED (.credit_score_required, .max_dti_allowed, .employment_required).
liability_preventedLiabilityEstimate or NoneEstimated exposure prevented (.estimated_exposure, .reason).
modificationslist[Modification] or NoneField edits applied for MODIFIED decisions (.field_name, .original_value, .modified_value, .reason).
auditAuditRecordThe signed Decision Certificate. See Decision Certificates for the full schema.
audit.audit_idstrUnique certificate identifier. Also exposed as result.decision_id.
audit.signaturestrTagged signature over the canonical audit record, with the algorithm carried in the prefix: kms-ecdsa-p384-<hex> on the hosted service, hmac-<hex> for legacy and self-hosted symmetric records, also ed25519- and ecdsa-p256-. A verifier must dispatch on the prefix rather than assume one algorithm. Also result.signature.

Error Handling

The SDK uses a structured exception hierarchy. All exceptions inherit from CoreGuardError:

from eve_coreguard import (
    CoreGuardClient,
    CoreGuardError,
    AuthError,                # 401 — invalid or expired API key
    PaymentRequiredError,     # 402 — subscription past due / restricted
    RateLimitError,           # 429 — rate limit exceeded (has .retry_after)
    PolicySetNotFoundError,   # 404 — policy_set does not exist
    VetoError,                # raised by verify() when raise_on_veto=True
)

client = CoreGuardClient(api_key=os.environ["COREGUARD_API_KEY"])

try:
    result = client.evaluate(tenant_id="bank_001", proposed_action=action)
except AuthError:
    # Rotate API key; alert on-call
    raise
except RateLimitError as e:
    # Back off for e.retry_after seconds
    time.sleep(e.retry_after)
except PolicySetNotFoundError:
    # Unknown policy_set — check list_policies()
    raise
except PaymentRequiredError:
    # Subscription past due — inspect client.subscription_state
    raise
except CoreGuardError as e:
    logger.error(f"CoreGuard evaluation failed: {e} (status {e.status_code})")
    raise

Output Verification & Policy Discovery

Beyond decision enforcement, the same client verifies AI-generated text through the 43-stage governance pipeline, and discovers the policy packs available to your tenant.

Verify AI output

vr = client.verify(
    ai_output="The current prime rate is 8.5%.",
    confidence=0.9,
    domain="financial",  # factual | financial | legal | medical | safety | creative | general
)
print(vr.passed, vr.blocked, vr.crd)  # bool, bool, CRD score
if vr.blocked:
    print(vr.veto.type, vr.veto.reason)

Discover policy packs

# List the catalog (optionally filter by regulatory domain)
for p in client.list_policies(domain="fair_lending"):
    print(p.policy_id, p.version, p.rule_count)

# Fetch metadata for one pack
pack = client.get_policy("lending_v1")
print(pack.jurisdiction, pack.notes)

Advanced Usage

Batch Evaluation

The decision API evaluates one action per call. For high-throughput scenarios, evaluate concurrently with a thread pool — each call is an independent, idempotent HTTP request:

from concurrent.futures import ThreadPoolExecutor
from eve_coreguard import CoreGuardClient

client = CoreGuardClient(api_key=os.environ["COREGUARD_API_KEY"])

def check(app):
    return client.evaluate(
        tenant_id="bank_001",
        proposed_action=app["action"],
        context=app["context"],
        policy_set="lending_v1",
    )

with ThreadPoolExecutor(max_workers=8) as pool:
    for app, res in zip(application_batch, pool.map(check, application_batch)):
        if res.blocked:
            handle_blocked(app, res)

Custom Policy Sets

Organizations on Enterprise plans may have custom policy packs deployed in their own namespace (org:<org_id>). A custom pack governs a decision once your org admin binds an action type to it; you then call evaluate() exactly as for a built-in pack, and the binding — not policy_set — selects it. (policy_set remains an optional assertion; a value that does not match the bound pack is a signed BLOCK.) With eve-coreguard 0.2.10 (the version currently on PyPI), evaluate() sends policy_set="lending_v1" whenever the argument is omitted, so a non-lending or custom-bound action type comes back as a signed BLOCK (COREGUARD.POLICY_BINDING_MISMATCH). On 0.2.10, pass the bound pack’s policy_id as policy_set explicitly; 0.2.11 omits it.

result = client.evaluate(
    tenant_id="regional_bank_07",
    # loan_approval is governed by the custom pack your org admin bound it to
    user={"id": "u_100", "role": "underwriter"},
    proposed_action={"type": "loan_approval", "amount": 420000},
    # required on 0.2.10 (it would otherwise send "lending_v1"): the custom pack's
    # policy_id, as listed by client.list_policies()
    policy_set=custom_policy_id,
)

Offline Proof Verification

Every decision can be verified locally, with no server call: the SDK recomputes the content hash and checks the signature. Which key you need depends on which artifact you hold — the two are not interchangeable.

For a hosted decision record, verification is asymmetric: it needs only EVE’s public key and no shared secret, so the party checking the record is not the party that produced it. This gives publicly verifiable evidence of record integrity and signing-key possession (not, by itself, legal non-repudiation):

# A governed decision, with the signed evidence plane included
decision = client.evaluate(request_id="req-001", tenant_id="org_abc", proposed_action={"type": "loan_approval", "amount": 50000}, policy_set="lending_v1", include_evidence=True)

# Hosted records: verify against the PUBLISHED PUBLIC KEY — no shared secret, no
# network. The key is auto-fetched from /.well-known/eve-pubkey if not supplied.
result = client.verify_evidence_offline(decision.signed_governance)
print(f"Valid: {result.valid} | algorithm: {result.algorithm} | independent: {result.independently_verifiable}")

# Legacy / self-hosted symmetric proof bundle — DEPRECATED, and NOT independent
# proof: it needs the server's shared signing key, so anyone able to verify can
# also forge. Kept only for pre-existing HMAC records.
proof = client.get_proof("proof_abc123")
is_valid = CoreGuardClient.verify_proof(proof.raw, signing_key=key_hex)
print(f"Proof valid: {is_valid}")

# Export a batch of records for compliance review
export = client.export_audit(action_type="loan_approval", limit=100)
print(export.count, "records")

To verify certificates, chains, and ITI snapshots without any EVE CoreGuard client (the auditor/regulator path), use the dedicated offline verifier: pip install eve-governance.

Changelog

v0.2.10
Released 2026-09-14

Current release. Patch: the institutional-mandate verification surface is now importable from the package root. No API, wire, verdict or verification behavior changed.

  • 0.2.9 shipped eve_coreguard/mandate.py with the full offline authority-verification surface but never exported it, so from eve_coreguard import verify_mandate_authority raised ImportError while only from eve_coreguard.mandate import … worked.
  • Added to the package root and __all__: verify_mandate_authority, mandate_claim, compute_mandate_state_digest, select_governing_generation, MandateGeneration, MandateVerification. The submodule import keeps working.
v0.2.9
Released 2026-08-23

Patch: __version__ now matches the packaged version. No API, wire, verdict or verification behavior changed.

  • Fixes 0.2.8 shipping with eve_coreguard.__version__ == "0.2.7" — the release bump touched pyproject.toml and left the module attribute behind, so an audit record naming the verifying tool would have reported the wrong version.
  • 0.2.8 is otherwise identical; upgrade only if you read __version__.
v0.2.8
Released 2026-08-23

Default API endpoint is now https://api.evecore.com. Backward compatible — no wire, verdict, or verification behavior changed.

  • The default base_url for CoreGuardClient and TrustClient is now https://api.evecore.com, the canonical EVE API hostname.
  • https://api.eveaicore.com reaches the same production platform — same service, same database, same signing key — and remains fully supported with no deprecation date.
  • Hostname is not an input to tenant resolution, policy evaluation, authority, certificates, idempotency or execution-token validity. Certificates issued before this release verify offline unchanged.
v0.2.7
Released 2026-08-02

Offline verification of AWS-KMS-signed decision records (ECDSA P-384) — additive; no verdict or wire behavior changed for existing records.

  • The offline verifier now recognizes the kms-ecdsa-p384-<hex> signature tag (AWS KMS ECC_NIST_P384/ECDSA_SHA_384, DER-encoded): it recomputes the SHA-384 digest of content_hash and checks the signature against the published public key — no KMS or AWS access required.
  • Adds test_kms_verify.py with a kms_vector.json test vector. Existing ecdsa-p384/ecdsa-p256/hmac verification is unchanged; a tampered record still fails.
v0.2.6
Released 2026-07-27

Offline verifier broadening for over-bound records. No verdict or wire behavior changed.

  • verify_decision_record falls back to a full-record content hash when the fixed eve.decision.v3/v4 signed-field reconstruction does not match, recognizing “over-bound” records whose signature legitimately covers more fields than the fixed set. A tampered record still fails both reconstructions, so verification is never weakened.
  • Published to PyPI and verified byte-reproducible from tag eve-coreguard-v0.2.6.
v0.2.5
Released 2026-07-22

License-metadata correction and canonical entry-point alignment. No verdict, verification, or wire behavior changed.

  • Restores the correct proprietary package metadata (the 0.2.4 build carried a stray MIT classifier that contradicted the LICENSE file). PyPI versions are immutable, so the correction shipped as a new version.
  • The public API is now CoreGuardClient only; the EVE facade is removed. Use from eve_coreguard import CoreGuardClient.
v0.2.4
Released 2026-07-21

Published to PyPI. Offline verification for the eve.decision.v3 decision-record schema.

  • Adds offline verification for the eve.decision.v3 schema: request, response, and rule-results digest checking plus public-key signature verification.
  • No breaking API changes from the 0.1.x line; the evaluate() keyword interface is unchanged.
v0.1.5
Released 2026-06-18

Offline-verification reliability fix.

  • Fixes a critical bug where fetch_public_key() failed because the base URL was never set, causing offline ECDSA P-384 verification to silently fail.
  • Adds test_evidence.py covering round-trip, tamper, fail-closed, and auto-fetch paths.
  • Removes the unused [async] install extra; honest verify_chain() docstring. (0.2.1 restored the [async] extra to match the published package metadata; it only installs aiohttp.)
v0.1.4
Released 2026-06-12

Independent offline decision-evidence verification.

  • New evidence.py: verify_decision_record(), fetch_public_key_pem(), recompute_content_hash() — recompute the SHA-256 content hash locally and check the ECDSA P-384 signature with no server call.
  • New verify install extra (pip install "eve-coreguard[verify]", pulls cryptography>=41).
  • LICENSE now included in the source distribution.
v0.1.3
Released 2026-06-04

Policy catalog discovery.

  • client.list_policies(domain=...) and client.get_policy(policy_id) for discovering available policy packs.
  • New typed PolicyInfo model (policy_id, version, domain, jurisdiction, rule_count).
  • SDK test suite grows to 33 tests.
v0.1.0
Released 2026-05-05

Initial public release.

  • Synchronous CoreGuardClient with evaluate() for decision enforcement.
  • verify() for running AI output through the 43-stage governance pipeline.
  • Audit & proof retrieval: get_proof(), get_recent_proofs(), export_audit(), and the static CoreGuardClient.verify_proof() for offline HMAC verification.
  • Typed, frozen result models: EvaluationResult, VerifyResult, ProofBundle.
  • Automatic retry with exponential backoff on 5xx errors.
  • Exception hierarchy: CoreGuardError, AuthError, PaymentRequiredError, RateLimitError, PolicySetNotFoundError, VetoError.
  • Zero required dependencies (stdlib urllib transport); 28 tests at launch.
  • Compatible with Python 3.9, 3.10, 3.11, 3.12, 3.13.

For upcoming releases and the full commit history, see the GitHub repository. Bug reports and feature requests are welcome via GitHub Issues or [email protected].

Part of the EVE AI Core control plane Deterministic AI Governance Control Plane → Policy decisions that return the same result for the same input every time, before execution.