Tamper-proof audit logs for AI systems - without exposing sensitive data.
Note: Online attestation (Merkle tree proofs via the Glacis API) is not yet available. The SDK currently supports offline mode with local Ed25519 signing. Online mode will be enabled in a future release.
You need to prove what your AI did for compliance, audits, or legal discovery. But sending prompts and responses to a logging service exposes sensitive data (PII, PHI, trade secrets).
Glacis creates cryptographic proofs of AI operations. Your data stays local - only a SHA-256 hash is sent for witnessing.
Your Infrastructure Glacis Log
┌─────────────────────┐ ┌─────────────────────┐
│ "Pt. Frodo Baggins │ │ 7a3f8b2c... │
│ has diabetes" │ ──→ │ (64-char hash) │
│ │ │ + timestamp │
│ (data stays here) │ │ + Merkle proof │
└─────────────────────┘ └─────────────────────┘
Later, you can prove the hash matches your local records without revealing the data itself.
pip install glacis[openai] # For OpenAI
pip install glacis[anthropic] # For Anthropic
pip install glacis[gemini] # For Google Gemini
pip install glacis[controls] # Add PII detection + jailbreak detection
pip install glacis[all] # EverythingReplace your OpenAI/Anthropic/Gemini client with a wrapped version. Every API call is automatically attested.
import os
from glacis.integrations.openai import attested_openai, get_last_receipt
# Create wrapped client (offline mode - no Glacis account needed)
client = attested_openai(
openai_api_key="sk-...",
offline=True,
signing_seed=os.urandom(32),
)
# Use exactly like the normal OpenAI client
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "Hello!"}]
)
# Get the attestation receipt
receipt = get_last_receipt()
print(f"Attestation ID: {receipt.id}")Works the same for Anthropic:
from glacis.integrations.anthropic import attested_anthropic, get_last_receipt
client = attested_anthropic(
anthropic_api_key="sk-ant-...",
offline=True,
signing_seed=os.urandom(32),
)And for Google Gemini:
from glacis.integrations.gemini import attested_gemini, get_last_receipt
client = attested_gemini(
gemini_api_key="...",
offline=True,
signing_seed=os.urandom(32),
)
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Hello!"
)
receipt = get_last_receipt()For custom attestations (non-OpenAI/Anthropic/Gemini, or manual control):
import os
from glacis import Glacis
glacis = Glacis(mode="offline", signing_seed=os.urandom(32))
receipt = glacis.attest(
service_id="my-ai-app",
operation_type="inference",
input={"prompt": "Summarize this..."},
output={"response": "The document..."},
)Detect PII/PHI and prompt injection attempts in your AI calls. Enable controls via a YAML config file:
client = attested_openai(
openai_api_key="sk-...",
offline=True,
signing_seed=os.urandom(32),
config_path="glacis.yaml", # Enable controls via config
)Control results (detections, scores, latencies) are included in the attestation record.
For persistent settings, create glacis.yaml:
version: "1.3"
attestation:
offline: true
service_id: my-ai-service
controls:
input:
pii_phi:
enabled: true
mode: fast # "fast" (regex) or "full" (Presidio NER)
if_detected: flag # "forward", "flag", or "block"
jailbreak:
enabled: true
threshold: 0.5
if_detected: block
sampling:
l1_rate: 1.0 # Evidence collection rate (0.0-1.0)
l2_rate: 0.0 # Deep inspection rate (must be <= l1_rate)Then:
client = attested_openai(
openai_api_key="sk-...",
config_path="glacis.yaml",
)Full payloads are stored locally for audits:
from glacis.integrations.openai import get_last_receipt, get_evidence
receipt = get_last_receipt()
evidence = get_evidence(receipt.id)
print(evidence["input"]) # Original input
print(evidence["output"]) # Original output
print(evidence["control_plane_results"]) # PII/jailbreak resultsEvidence is stored locally using SQLite (default) or JSONL backends.
Online mode is not yet available. Use offline mode for now.
| Feature | Offline | Online (coming soon) |
|---|---|---|
| Requires Glacis account | No | Yes |
| Signing | Local Ed25519 | Glacis witness |
| Third-party verifiable | No | Yes (Merkle proofs) |
| Use case | Development, production | Audits, regulatory |
| Data | Sent? |
|---|---|
| Your prompts | No (hash only) |
| Model responses | No (hash only) |
| API keys | No |
| service_id, operation_type | Yes |
| Timestamps | Yes |
Verify a receipt:
python -m glacis verify receipt.json- Hashing: SHA-256 with RFC 8785 canonical JSON (cross-runtime compatible)
- Signing: Ed25519 via PyNaCl (libsodium)
- Online mode: Merkle tree inclusion proofs (RFC 6962)
Apache 2.0
