Skip to main content

Glacis

Glacis Python SDK

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.

The Problem

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).

The Solution

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.

Installation

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]         # Everything

Quick Start

Option 1: Drop-in Wrapper (Recommended)

Replace 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()

Option 2: Direct API

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..."},
)

Adding Controls

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.

Configuration File

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",
)

Retrieving Evidence

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 results

Evidence is stored locally using SQLite (default) or JSONL backends.

Online vs Offline Mode

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

What Gets Sent to Glacis?

Data Sent?
Your prompts No (hash only)
Model responses No (hash only)
API keys No
service_id, operation_type Yes
Timestamps Yes

CLI

Verify a receipt:

python -m glacis verify receipt.json

Security

  • Hashing: SHA-256 with RFC 8785 canonical JSON (cross-runtime compatible)
  • Signing: Ed25519 via PyNaCl (libsodium)
  • Online mode: Merkle tree inclusion proofs (RFC 6962)

License

Apache 2.0

Metadata

Release files for glacis 0.8.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for glacis 0.8.1
File Size Uploaded
glacis-0.8.1.tar.gz 77.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for glacis 0.8.1
File Interpreter ABI Platform
glacis-0.8.1-py3-none-any.whl Python 3 none any Details

Total release size: 172.9 kB

Release files / glacis-0.8.1.tar.gz

Download URL glacis-0.8.1.tar.gz
Size 77.4 kB
Tags Source
SHA-256 checksum
How to use checksums
ae3a17877200f04b255680be8c050d1b125853eed5876a2718f9886e8db9415f
BLAKE2b-256 checksum
How to use checksums
636eb202743fd57e1c19eee3918a5c4f5536f95d74f98f70a49e4837df272f63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.6

Release files / glacis-0.8.1-py3-none-any.whl

Download URL glacis-0.8.1-py3-none-any.whl
Size 95.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
20c0644e279c07c00174373e77fbfef1ef188d8a00fc81486fe5d01a1661a1d9
BLAKE2b-256 checksum
How to use checksums
ceaa11353e0420c39ce29e2dc727fa4d1b0bd809da280e3c4af8f0381878f582
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.6

Release history Release notifications | RSS feed

This release

0.8.1 This release

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page