glacis 0.1.3__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,275 @@
1
+ Metadata-Version: 2.4
2
+ Name: glacis
3
+ Version: 0.2.0
4
+ Summary: GLACIS SDK for Python - AI Compliance Attestation
5
+ Project-URL: Homepage, https://glacis.io
6
+ Project-URL: Documentation, https://docs.glacis.io/sdk/python
7
+ Project-URL: Repository, https://github.com/Glacis-io/glacis-python
8
+ Project-URL: Issues, https://github.com/Glacis-io/glacis-python/issues
9
+ Author-email: GLACIS <sdk@glacis.io>
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ Keywords: ai,attestation,compliance,logging,transparency
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: Apache Software License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Security :: Cryptography
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: httpx>=0.25.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Requires-Dist: pynacl>=1.5.0
27
+ Provides-Extra: all
28
+ Requires-Dist: anthropic>=0.18.0; extra == 'all'
29
+ Requires-Dist: mypy>=1.0.0; extra == 'all'
30
+ Requires-Dist: openai>=1.0.0; extra == 'all'
31
+ Requires-Dist: presidio-analyzer>=2.2.0; extra == 'all'
32
+ Requires-Dist: presidio-anonymizer>=2.2.0; extra == 'all'
33
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'all'
34
+ Requires-Dist: pytest-httpx>=0.22.0; extra == 'all'
35
+ Requires-Dist: pytest>=7.0.0; extra == 'all'
36
+ Requires-Dist: pyyaml>=6.0.0; extra == 'all'
37
+ Requires-Dist: ruff>=0.1.0; extra == 'all'
38
+ Requires-Dist: spacy>=3.5.0; extra == 'all'
39
+ Requires-Dist: torch>=2.0.0; extra == 'all'
40
+ Requires-Dist: transformers>=4.35.0; extra == 'all'
41
+ Provides-Extra: anthropic
42
+ Requires-Dist: anthropic>=0.18.0; extra == 'anthropic'
43
+ Provides-Extra: controls
44
+ Requires-Dist: presidio-analyzer>=2.2.0; extra == 'controls'
45
+ Requires-Dist: presidio-anonymizer>=2.2.0; extra == 'controls'
46
+ Requires-Dist: pyyaml>=6.0.0; extra == 'controls'
47
+ Requires-Dist: spacy>=3.5.0; extra == 'controls'
48
+ Requires-Dist: torch>=2.0.0; extra == 'controls'
49
+ Requires-Dist: transformers>=4.35.0; extra == 'controls'
50
+ Provides-Extra: dev
51
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
52
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
53
+ Requires-Dist: pytest-httpx>=0.22.0; extra == 'dev'
54
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
55
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
56
+ Provides-Extra: jailbreak
57
+ Requires-Dist: pyyaml>=6.0.0; extra == 'jailbreak'
58
+ Requires-Dist: torch>=2.0.0; extra == 'jailbreak'
59
+ Requires-Dist: transformers>=4.35.0; extra == 'jailbreak'
60
+ Provides-Extra: openai
61
+ Requires-Dist: openai>=1.0.0; extra == 'openai'
62
+ Provides-Extra: redaction
63
+ Requires-Dist: presidio-analyzer>=2.2.0; extra == 'redaction'
64
+ Requires-Dist: presidio-anonymizer>=2.2.0; extra == 'redaction'
65
+ Requires-Dist: pyyaml>=6.0.0; extra == 'redaction'
66
+ Requires-Dist: spacy>=3.5.0; extra == 'redaction'
67
+ Description-Content-Type: text/markdown
68
+
69
+ <p align="center">
70
+ <img src="assets/glacis-logo.png" alt="Glacis" width="200">
71
+ </p>
72
+
73
+ # Glacis Python SDK
74
+
75
+ **Tamper-proof audit logs for AI systems - without exposing sensitive data.**
76
+
77
+ ## The Problem
78
+
79
+ 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).
80
+
81
+ ## The Solution
82
+
83
+ Glacis creates cryptographic proofs of AI operations. Your data stays local - only a SHA-256 hash is sent for witnessing.
84
+
85
+ ```
86
+ Your Infrastructure Glacis Log
87
+ ┌─────────────────────┐ ┌─────────────────────┐
88
+ │ "Pt. Frodo Baggins │ │ 7a3f8b2c... │
89
+ │ has diabetes" │ ──→ │ (64-char hash) │
90
+ │ │ │ + timestamp │
91
+ │ (data stays here) │ │ + Merkle proof │
92
+ └─────────────────────┘ └─────────────────────┘
93
+ ```
94
+
95
+ Later, you can prove the hash matches your local records without revealing the data itself.
96
+
97
+ ## Installation
98
+
99
+ ```bash
100
+ pip install glacis[openai] # For OpenAI
101
+ pip install glacis[anthropic] # For Anthropic
102
+ pip install glacis[controls] # Add PII redaction + jailbreak detection
103
+ pip install glacis[all] # Everything
104
+ ```
105
+
106
+ ## Quick Start
107
+
108
+ ### Option 1: Drop-in Wrapper (Recommended)
109
+
110
+ Replace your OpenAI/Anthropic client with a wrapped version. Every API call is automatically attested.
111
+
112
+ ```python
113
+ import os
114
+ from glacis.integrations.openai import attested_openai, get_last_receipt
115
+
116
+ # Create wrapped client (offline mode - no Glacis account needed)
117
+ client = attested_openai(
118
+ openai_api_key="sk-...",
119
+ offline=True,
120
+ signing_seed=os.urandom(32),
121
+ )
122
+
123
+ # Use exactly like the normal OpenAI client
124
+ response = client.chat.completions.create(
125
+ model="gpt-4",
126
+ messages=[{"role": "user", "content": "Hello!"}]
127
+ )
128
+
129
+ # Get the attestation receipt
130
+ receipt = get_last_receipt()
131
+ print(f"Attestation ID: {receipt.attestation_id}")
132
+ ```
133
+
134
+ Works the same for Anthropic:
135
+
136
+ ```python
137
+ from glacis.integrations.anthropic import attested_anthropic, get_last_receipt
138
+
139
+ client = attested_anthropic(
140
+ anthropic_api_key="sk-ant-...",
141
+ offline=True,
142
+ signing_seed=os.urandom(32),
143
+ )
144
+ ```
145
+
146
+ ### Option 2: Direct API
147
+
148
+ For custom attestations (non-OpenAI/Anthropic, or manual control):
149
+
150
+ ```python
151
+ import os
152
+ from glacis import Glacis
153
+
154
+ glacis = Glacis(mode="offline", signing_seed=os.urandom(32))
155
+
156
+ receipt = glacis.attest(
157
+ service_id="my-ai-app",
158
+ operation_type="inference",
159
+ input={"prompt": "Summarize this..."},
160
+ output={"response": "The document..."},
161
+ )
162
+ ```
163
+
164
+ ## Adding PII Redaction
165
+
166
+ Automatically detect and redact sensitive data before it's hashed:
167
+
168
+ ```python
169
+ client = attested_openai(
170
+ openai_api_key="sk-...",
171
+ offline=True,
172
+ signing_seed=os.urandom(32),
173
+ redaction="fast", # Regex-based, or "full" for ML models
174
+ )
175
+
176
+ response = client.chat.completions.create(
177
+ model="gpt-4",
178
+ messages=[{"role": "user", "content": "My SSN is 123-45-6789"}]
179
+ )
180
+
181
+ # The attestation hash is computed on: "My SSN is [US_SSN]"
182
+ # Original text still sent to OpenAI, but redacted version is attested
183
+ ```
184
+
185
+ ## Configuration File
186
+
187
+ For persistent settings, create `glacis.yaml`:
188
+
189
+ ```yaml
190
+ attestation:
191
+ offline: true
192
+ service_id: my-ai-service
193
+
194
+ controls:
195
+ pii_phi:
196
+ enabled: true
197
+ mode: fast # "fast" (regex) or "full" (Presidio NER)
198
+
199
+ jailbreak:
200
+ enabled: true
201
+ threshold: 0.5 # Block prompt injection attempts
202
+ action: block # "warn" or "block"
203
+ ```
204
+
205
+ Then:
206
+
207
+ ```python
208
+ client = attested_openai(
209
+ openai_api_key="sk-...",
210
+ config_path="glacis.yaml",
211
+ )
212
+ ```
213
+
214
+ ## Retrieving Evidence
215
+
216
+ Full payloads are stored locally for audits:
217
+
218
+ ```python
219
+ from glacis.integrations.openai import get_last_receipt, get_evidence
220
+
221
+ receipt = get_last_receipt()
222
+ evidence = get_evidence(receipt.attestation_id)
223
+
224
+ print(evidence["input"]) # Original input
225
+ print(evidence["output"]) # Original output
226
+ print(evidence["control_plane_results"]) # PII/jailbreak results
227
+ ```
228
+
229
+ Evidence is stored in `~/.glacis/receipts.db` (SQLite).
230
+
231
+ ## Online vs Offline Mode
232
+
233
+ | Feature | Offline | Online |
234
+ |---------|---------|--------|
235
+ | Requires Glacis account | No | Yes |
236
+ | Signing | Local Ed25519 | Glacis witness |
237
+ | Third-party verifiable | No | Yes (Merkle proofs) |
238
+ | Use case | Development, air-gapped | Production, audits |
239
+
240
+ To use online mode:
241
+
242
+ ```python
243
+ client = attested_openai(
244
+ openai_api_key="sk-...",
245
+ glacis_api_key="glsk_live_...", # Get at glacis.io
246
+ )
247
+ ```
248
+
249
+ ## What Gets Sent to Glacis?
250
+
251
+ | Data | Sent? |
252
+ |------|-------|
253
+ | Your prompts | No (hash only) |
254
+ | Model responses | No (hash only) |
255
+ | API keys | No |
256
+ | service_id, operation_type | Yes |
257
+ | Timestamps | Yes |
258
+
259
+ ## CLI
260
+
261
+ Verify a receipt:
262
+
263
+ ```bash
264
+ python -m glacis verify receipt.json
265
+ ```
266
+
267
+ ## Security
268
+
269
+ - **Hashing**: SHA-256 with RFC 8785 canonical JSON (cross-runtime compatible)
270
+ - **Signing**: Ed25519 via PyNaCl (libsodium)
271
+ - **Online mode**: Merkle tree inclusion proofs (RFC 6962)
272
+
273
+ ## License
274
+
275
+ Apache 2.0
@@ -0,0 +1,21 @@
1
+ glacis/__init__.py,sha256=c56NUPfPCDk2kh9wuSiQvREvnJ3lZGk889zOUNIZt4c,3925
2
+ glacis/__main__.py,sha256=jnL1RezHA3aCK9Vx3JziwEZF5Wxl34fyoGmB9i4_gVs,141
3
+ glacis/client.py,sha256=dpMmaQCQ8u6QYCwY_dEyM69AI1j7xpwS6ljq4xDTOVM,29075
4
+ glacis/config.py,sha256=tjaPgXpIkoURkVPEsRb7ELjrZf53b5IXaqho57bXo_o,4034
5
+ glacis/crypto.py,sha256=Pq6b99DvWGtqaC-rpoDgRAZz87ygZ0lJqKDU9n-sBZg,5924
6
+ glacis/models.py,sha256=jb-vU2r90zxEnMzmN_BgJdnN6kd3cMgbAMOPANUo79I,17265
7
+ glacis/storage.py,sha256=2wPa4zX9ef_yoKRY_qyQm6Fj4lgkIJ4kzbK5ZZQbSNk,21428
8
+ glacis/streaming.py,sha256=hAmR4XHQixLia6awnFfCaA9hZOtCq2b-pOzgaMd3YzQ,11260
9
+ glacis/verify.py,sha256=e2Hr9cYrqt3gdsY7Qx69wYjAL_eoXaxZHJDuft7lNMA,4886
10
+ glacis/controls/__init__.py,sha256=gs4avL8EAKgKwr2ocPzIl2TfEr1PeUpHi44GaCwQtWk,7737
11
+ glacis/controls/base.py,sha256=AiLZQcH5KkXk1yQPOPB-hd0-Q8NCqX0rVoZSdq_NBOo,3321
12
+ glacis/controls/jailbreak.py,sha256=hXPAYcN2-qnmQMZBs5QOtk7IhErNp2oKbDoU361IOss,7740
13
+ glacis/controls/pii.py,sha256=K9_ZY4UMUiN6WTac-BvTaCyO3MhOc1oH9k5BGmq_Vrw,27833
14
+ glacis/integrations/__init__.py,sha256=reRDe-JaxHP3TrskPjdS5mxr1uCcVSKj-Vb5-ussl8o,1965
15
+ glacis/integrations/anthropic.py,sha256=rFf7cQuXq3Bs5ZkaPZcZltjd5EjGVCx2EeKmy287Jsg,10568
16
+ glacis/integrations/base.py,sha256=SAB_cIK_D8hEyClOx53Qe9p0Um0KtP9Ua4gZ23FBD-o,14784
17
+ glacis/integrations/openai.py,sha256=jtfo0RlVbEhDZfsSiGliJLcgFL2hziS2n8JukT-a4e0,8441
18
+ glacis-0.2.0.dist-info/METADATA,sha256=UiHN1EXWrzgUxriHL9U5F7A6XmlUbMq_6u8dQuSQ5KU,8290
19
+ glacis-0.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
20
+ glacis-0.2.0.dist-info/licenses/LICENSE,sha256=B7g2sM9vz4NF1poTFNMil2cnkwMFel1qUnimyvYW1sw,10766
21
+ glacis-0.2.0.dist-info/RECORD,,
Binary file