Skip to content

Anthropic Integration

The Glacis Anthropic integration wraps the official Anthropic client to automatically create attestations for every API call.

Installation

Terminal window
pip install glacis[anthropic]

Quick Start

from glacis.integrations.anthropic import attested_anthropic, get_last_receipt
client = attested_anthropic(
glacis_api_key="glsk_live_...",
anthropic_api_key="sk-ant-..."
)
# Make a normal Anthropic call - attestation happens automatically
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude!"}]
)
print(response.content[0].text)
# Get the attestation receipt
receipt = get_last_receipt()
print(f"Attested: {receipt.badge_url}")

What Gets Attested

For each message, Glacis captures:

FieldAttestedDetails
Request messagesHash onlySHA-256, never sent
Response contentHash onlySHA-256, never sent
ModelMetadataSent as-is
Max tokensMetadataSent as-is
System promptHash onlySHA-256, never sent
TimestampMetadataISO 8601

Environment Variables

Terminal window
export GLACIS_API_KEY=glsk_live_...
export ANTHROPIC_API_KEY=sk-ant-...
from glacis.integrations.anthropic import attested_anthropic
# Keys read from environment automatically
client = attested_anthropic()

Streaming Support

Streaming messages are automatically attested when the stream completes:

with client.messages.stream(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=[{"role": "user", "content": "Tell me a story"}]
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
# Receipt available after stream completes
receipt = get_last_receipt()
print(f"\n\nAttested: {receipt.badge_url}")

System Prompts

System prompts are hashed but never transmitted:

response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
system="You are a helpful AI assistant specialized in compliance.",
messages=[{"role": "user", "content": "What is GDPR?"}]
)
# System prompt is included in the attestation hash
receipt = get_last_receipt()

Multi-Turn Conversations

Each API call creates a separate attestation:

messages = []
# First turn
messages.append({"role": "user", "content": "Hello!"})
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=messages
)
receipt1 = get_last_receipt()
messages.append({"role": "assistant", "content": response.content[0].text})
# Second turn
messages.append({"role": "user", "content": "How are you?"})
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=messages
)
receipt2 = get_last_receipt()
# Each turn has its own attestation
print(f"Turn 1: {receipt1.attestation_id}")
print(f"Turn 2: {receipt2.attestation_id}")

Offline Mode

For development without an API key:

from glacis.integrations.anthropic import attested_anthropic
client = attested_anthropic(
glacis_mode="offline",
anthropic_api_key="sk-ant-..."
)
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello!"}]
)
receipt = get_last_receipt()
print(f"Status: {receipt.witness_status}") # "UNVERIFIED"

Full Example

#!/usr/bin/env python3
"""
Complete example: Anthropic Claude with attestation
"""
import os
from glacis.integrations.anthropic import attested_anthropic, get_last_receipt
def main():
client = attested_anthropic(
glacis_api_key=os.environ.get("GLACIS_API_KEY"),
anthropic_api_key=os.environ.get("ANTHROPIC_API_KEY"),
)
response = client.messages.create(
model="claude-3-opus-20240229",
max_tokens=1024,
system="You are a compliance expert.",
messages=[
{"role": "user", "content": "What is ISO 42001?"}
]
)
print("Response:", response.content[0].text)
print()
receipt = get_last_receipt()
print("Attestation Details:")
print(f" Receipt ID: {receipt.attestation_id}")
print(f" Timestamp: {receipt.timestamp}")
print(f" Badge URL: {receipt.badge_url}")
if __name__ == "__main__":
main()