Skip to main content

Python SDK client for the ComplianceGuard HTTP API

Project description

complianceguard

Python client for the ComplianceGuard HTTP API. Hashes-by-default; raw input/output/metadata bytes never leave the process unless the caller explicitly opts into the encrypted-payload envelope.

Install

pip install complianceguard

cryptography>=42.0 is the only runtime dependency (used for AES-256-GCM in the envelope path).

Ingest a decision event (hashes-only)

from complianceguard import ComplianceGuardClient
from uuid import uuid4

client = ComplianceGuardClient(
    base_url="https://api.example.com",
    api_key="<environment-api-key>",
)

result = client.ingest_event(
    event_id=str(uuid4()),                # any UUIDv7-compatible identifier
    system_id="<your-system-profile-id>",
    occurred_at_utc="2026-05-01T12:00:00Z",
    model_id="candidate-screening-v1",
    version="2026.05.01",
    decision_classification="automated_decision",
    input={"prompt": "..."},              # hashed locally; never sent
    output={"answer": "..."},             # hashed locally; never sent
    metadata={"trace": "..."},            # hashed locally; never sent
)

print(result.event_id, result.event_hash)

The SDK computes SHA-256 of the canonical JSON of each component and sends only the references. The platform never receives the raw bytes.

Encrypted-payload envelope (optional)

If you want to retain payload visibility for your own internal use without trusting the platform with the plaintext, pass an AES-256 key. The SDK encrypts the wrapping {input, output, metadata} plaintext under your key, binds the ciphertext to the event identity via AAD, and sends only the opaque envelope. The platform stores it as bytes and never decrypts.

import secrets
from complianceguard import ComplianceGuardClient

key = secrets.token_bytes(32)             # store securely; the platform never sees this

client = ComplianceGuardClient(
    base_url="https://api.example.com",
    api_key="<environment-api-key>",
)

result = client.ingest_event(
    event_id="<uuid7>",
    system_id="cv-screening-prod",
    occurred_at_utc="2026-05-01T12:00:00Z",
    model_id="candidate-screening-v1",
    version="2026.05.01",
    decision_classification="automated_decision",
    input={"prompt": "..."},
    output={"answer": "..."},
    metadata={"trace": "..."},
    payload_key=key,
    payload_key_id="kek-customer-2026-05-01",
)

Decrypt later

The same key, fetched on the auditor side from your own KMS, recovers the plaintext. The platform never participates in this step.

from complianceguard import decrypt_event

# `event` is a GET /v1/events/{id} response payload (camelCase).
plaintext = decrypt_event(event, key)
print(plaintext["input"], plaintext["output"], plaintext["metadata"])

decrypt_event verifies the AAD binding before AES-GCM decryption and refuses to return plaintext on tag mismatch or AAD-rebind attempts.

Algorithm

  • AES-256-GCM, 96-bit random nonce per event, 128-bit auth tag.
  • AAD = canonical JSON of {eventId, systemId, timestamp}.
  • AAD hash (SHA-256 hex) sent as aadHash so the platform can verify the binding metadata without the key.

Full spec at docs/encrypted-payload-envelope.md in the backend repo.

Human oversight (Article 14)

When a human reviewer overrides an AI decision, record the override directly:

client.log_override(
    event_id="<uuid7>",
    system_id="cv-screening-prod",
    occurred_at_utc="2026-05-02T14:30:00Z",
    model_id="candidate-screening-v1",
    version="2026.05.01",
    request_id="<correlation-id-of-original-decision>",
    user_id="<reviewer-id>",
    reason="Operator escalated for manual review.",
    original_output={"answer": "deny"},
    final_output={"answer": "approve"},
)

The convenience method:

  • Sets correlationId to request_id, linking the override back to the original decision.
  • Builds a properly-shaped human_oversight block with decision="override", reviewerType="human", reviewerId=user_id, interventionType="override", and notes=reason.
  • Hashes original_output into inputReference and final_output into outputReference — the same hashes-by-default rule as ingest_event.

decision_classification defaults to "automated_decision". Pass any other keyword that ingest_event accepts (including payload_key for the encrypted-payload envelope, or a custom human_oversight to override one of the auto-populated fields) and it forwards through unchanged.

Performance and error capture (Article 15)

Wrap an AI provider call in a trace_call context manager. The trace captures wall-clock latency, the provider's HTTP status (or the exception type when no status is available), and the error message — truncated to 500 characters and SHA-256 hashed by default — and exposes them as a system_state.performance block ready to attach to the event:

from complianceguard import ComplianceGuardClient, trace_call

client = ComplianceGuardClient(base_url="...", api_key="...")

with trace_call() as trace:
    response = openai_client.chat.completions.create(...)

client.ingest_event(
    event_id="<uuid7>",
    system_id="cv-screening-prod",
    occurred_at_utc="2026-05-02T14:30:00Z",
    model_id="candidate-screening-v1",
    version="2026.05.01",
    decision_classification="automated_decision",
    input={"prompt": "..."},
    output={"answer": "..."},
    metadata={"trace": "..."},
    system_state=trace.system_state(),
)

system_state.performance contains:

  • latency_ms — milliseconds from __enter__ to __exit__.
  • provider_status — the provider's HTTP status as a string, or error:<ExceptionTypeName> if the call raised without a status. On success, the value is "success".
  • provider_error_message — only populated on failure. Truncated to 500 characters, then SHA-256 hashed by default. Pass trace_call(hash_error_messages=False) if the customer has confirmed the provider's error text contains no PII and they want the raw string.

The trace re-raises any provider exception so existing try/except logic keeps working. To merge extra structured fields, pass them as trace.system_state(extra={"metrics": {...}}).

Metric and human-intervention reporting

Metrics, drift signals, and human-intervention records are SDK-side concerns. The platform does not extract metrics from raw payloads — the previous payload-based extractor was deleted in B11. Metrics arrive only when the caller explicitly emits them as structured Article 12 fields on the event:

result = client.ingest_event(
    # ...standard event fields...
    decision_classification="automated_decision",
    system_state={
        "metrics": {
            "drift_score": 0.18,
            "error_rate": 0.07,
        },
    },
    # human_oversight is a separate first-class field on the event;
    # use it to record intervention type, reviewer, and notes:
    human_oversight={
        "reviewer_type": "human",
        "intervention_type": "override",
        "notes": "Operator overrode the default decision.",
    },
)

The platform reads system_state.metrics directly from the structured field for alert evaluation. There is no payload-decoding step on the server, no metric inference from output, and no fallback that parses raw bytes — the SDK is the only metric source.

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

complianceguard-0.1.2.tar.gz (14.9 kB view details)

Uploaded Source

Built Distribution

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

complianceguard-0.1.2-py3-none-any.whl (10.5 kB view details)

Uploaded Python 3

File details

Details for the file complianceguard-0.1.2.tar.gz.

File metadata

  • Download URL: complianceguard-0.1.2.tar.gz
  • Upload date:
  • Size: 14.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.2

File hashes

Hashes for complianceguard-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d6ef0e8a762e2a8fae37b6ffdf4da5593186497d621021454facbf6e50234b9f
MD5 0cb230b69da949f66f6f9a03c63b0a0c
BLAKE2b-256 449605097078f32c003df4b74a921aebda72eebdba552b0a7ca63994c696abdd

See more details on using hashes here.

File details

Details for the file complianceguard-0.1.2-py3-none-any.whl.

File metadata

File hashes

Hashes for complianceguard-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d56d60bbb0ee0bae0b4037f580e13fe506249660a9b60d7a8fbaa7cbc7c6f5fa
MD5 59237c895a300ef12cd4da387fee1976
BLAKE2b-256 d3b9cbbe3b84c8f9924a4beced5cb1494c5bc4baf43e82f64a0a7d94d6cfcf40

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