shieldcortex 0.1.0__tar.gz → 0.2.0__tar.gz
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.
- shieldcortex-0.2.0/CHANGELOG.md +57 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/PKG-INFO +93 -31
- shieldcortex-0.2.0/README.md +214 -0
- shieldcortex-0.2.0/examples/audit_export.py +48 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/pyproject.toml +1 -1
- shieldcortex-0.2.0/src/shieldcortex/__init__.py +277 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/src/shieldcortex/_http.py +68 -8
- shieldcortex-0.2.0/src/shieldcortex/_payloads.py +341 -0
- shieldcortex-0.2.0/src/shieldcortex/_version.py +1 -0
- shieldcortex-0.2.0/src/shieldcortex/async_client.py +1116 -0
- shieldcortex-0.2.0/src/shieldcortex/client.py +1110 -0
- shieldcortex-0.2.0/src/shieldcortex/types.py +1256 -0
- shieldcortex-0.2.0/tests/conftest.py +23 -0
- shieldcortex-0.2.0/tests/endpoint_manifest.py +133 -0
- shieldcortex-0.2.0/tests/test_audit_exports.py +571 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/test_client.py +168 -2
- shieldcortex-0.2.0/tests/test_incidents_recall.py +257 -0
- shieldcortex-0.2.0/tests/test_license.py +146 -0
- shieldcortex-0.2.0/tests/test_parity.py +100 -0
- shieldcortex-0.2.0/tests/test_skills_threats.py +243 -0
- shieldcortex-0.2.0/tests/test_sync.py +551 -0
- shieldcortex-0.2.0/tests/test_verify.py +446 -0
- shieldcortex-0.1.0/README.md +0 -152
- shieldcortex-0.1.0/examples/audit_export.py +0 -29
- shieldcortex-0.1.0/src/shieldcortex/__init__.py +0 -140
- shieldcortex-0.1.0/src/shieldcortex/_version.py +0 -1
- shieldcortex-0.1.0/src/shieldcortex/async_client.py +0 -533
- shieldcortex-0.1.0/src/shieldcortex/client.py +0 -539
- shieldcortex-0.1.0/src/shieldcortex/types.py +0 -444
- shieldcortex-0.1.0/tests/conftest.py +0 -12
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/.github/workflows/publish.yml +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/.github/workflows/test.yml +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/.gitignore +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/LICENSE +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/examples/basic_scan.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/examples/batch_scanning.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/examples/crewai_memory.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/examples/langchain_callback.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/src/shieldcortex/errors.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/src/shieldcortex/integrations/__init__.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/src/shieldcortex/integrations/crewai.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/src/shieldcortex/integrations/langchain.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/src/shieldcortex/pagination.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/__init__.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/fixtures.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/integrations/__init__.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/integrations/test_crewai.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/test_errors.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/test_pagination.py +0 -0
- {shieldcortex-0.1.0 → shieldcortex-0.2.0}/tests/test_types.py +0 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 — 2026-08-11
|
|
4
|
+
|
|
5
|
+
SDK lockstep release: the Python SDK now covers the full customer surface
|
|
6
|
+
documented in the SDK lockstep contract, in lockstep with the TypeScript SDK.
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **Verification** — `submit_verification()`, `list_verifications()`,
|
|
11
|
+
`get_verification()`, `get_verification_stats()`, `delete_verification()`
|
|
12
|
+
- **Skills** — `ingest_skill_scans()`, `list_skill_scans()`
|
|
13
|
+
- **Threats** — `report_threat()` (OpenClaw realtime compat shim)
|
|
14
|
+
- **Incidents** — `replay_incidents()`
|
|
15
|
+
- **Recall** — `explain_recall()`
|
|
16
|
+
- **Sync** — `get_sync_health()`, `push_memories()`, `list_synced_memories()`,
|
|
17
|
+
`push_memory_graph()`. Note: `list_synced_memories()` omits the
|
|
18
|
+
`include_deleted` param unless truthy — the server Boolean-coerces any
|
|
19
|
+
present value (even `"false"`) as enabling it. Every other boolean query
|
|
20
|
+
param was audited for the same coercion trap; none affected.
|
|
21
|
+
- **Licence** — `get_license()`, `regenerate_license()`
|
|
22
|
+
- **Audit** — `ingest_audit_events()`, `get_iron_dome_stats()`,
|
|
23
|
+
`get_iron_dome_events()`, and the export-manifest surface
|
|
24
|
+
(`list_audit_exports()`, `get_audit_export_manifest()`,
|
|
25
|
+
`verify_audit_export()`, `list_audit_export_verifications()`)
|
|
26
|
+
- Cross-SDK endpoint parity manifest and drift guard
|
|
27
|
+
(`tests/endpoint_manifest.py`, kept in lockstep with the TS SDK's
|
|
28
|
+
`tests/endpoint-manifest.ts`), including a sync/async surface parity test
|
|
29
|
+
- Shared request builders (`_payloads.py`) so the sync and async clients
|
|
30
|
+
construct identical wire payloads and cannot drift
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- **BREAKING:** `export_audit_logs()` (both clients) now returns
|
|
35
|
+
`AuditExportResult` — the raw file body in `.content` plus the parsed
|
|
36
|
+
`X-ShieldCortex-Export-*` integrity headers in `.headers` — instead of a
|
|
37
|
+
bare `str`. Previously the integrity headers were discarded, so exports
|
|
38
|
+
structurally could not be verified. An absent `sha256`/`signature` header
|
|
39
|
+
is `None` (never `""`): the export is unverifiable. Migration:
|
|
40
|
+
`client.export_audit_logs(...)` → `client.export_audit_logs(...).content`.
|
|
41
|
+
|
|
42
|
+
### Deprecated
|
|
43
|
+
|
|
44
|
+
- `create_checkout_session()` / `create_portal_session()` now emit
|
|
45
|
+
`DeprecationWarning`: self-serve plans were retired 2026-07 (Free +
|
|
46
|
+
Enterprise model); the endpoints remain for grandfathered licence holders.
|
|
47
|
+
|
|
48
|
+
## 0.1.1 — 2026-03-12
|
|
49
|
+
|
|
50
|
+
- Added Iron Dome patterns/policies client support; fixed the default-policy
|
|
51
|
+
verb (PUT).
|
|
52
|
+
|
|
53
|
+
## 0.1.0 — 2026-02-15
|
|
54
|
+
|
|
55
|
+
- Initial release: scanning, audit, quarantine, keys, teams, invites,
|
|
56
|
+
billing, devices, alerts, webhooks, firewall rules; sync + async clients;
|
|
57
|
+
CrewAI and LangChain integrations; Python 3.9+ compatibility fixes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: shieldcortex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Official Python SDK for the ShieldCortex API — AI memory security scanning
|
|
5
5
|
Project-URL: Homepage, https://shieldcortex.ai
|
|
6
6
|
Project-URL: Documentation, https://shieldcortex.ai/docs
|
|
@@ -45,7 +45,25 @@ Description-Content-Type: text/markdown
|
|
|
45
45
|
|
|
46
46
|
Official Python SDK for the [ShieldCortex](https://shieldcortex.ai) API — AI memory security scanning.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
## How It Works
|
|
49
|
+
|
|
50
|
+
AI agents store memories (user inputs, tool outputs, conversation history) to improve over time. But those memories are an attack surface — prompt injection, credential leaks, and encoding attacks can all be smuggled into memory stores.
|
|
51
|
+
|
|
52
|
+
ShieldCortex scans content **before** it reaches your agent's memory through a 6-layer defence pipeline:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
Agent receives content
|
|
56
|
+
│
|
|
57
|
+
▼
|
|
58
|
+
ShieldCortex scan ──→ BLOCK → reject, log threat
|
|
59
|
+
│
|
|
60
|
+
▼
|
|
61
|
+
ALLOW ──→ safe to store in memory
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
The SDK sends content to the ShieldCortex cloud API and returns a verdict: **ALLOW**, **BLOCK**, or **QUARANTINE** — along with trust scores, threat indicators, and sensitivity classification.
|
|
65
|
+
|
|
66
|
+
**Get an API key** at [shieldcortex.ai](https://shieldcortex.ai) (free tier: 500 scans/month).
|
|
49
67
|
|
|
50
68
|
## Installation
|
|
51
69
|
|
|
@@ -67,14 +85,15 @@ from shieldcortex import ShieldCortex
|
|
|
67
85
|
|
|
68
86
|
client = ShieldCortex(api_key="sc_live_...")
|
|
69
87
|
|
|
70
|
-
# Scan
|
|
71
|
-
result = client.scan("user input
|
|
88
|
+
# Scan content before storing in your agent's memory
|
|
89
|
+
result = client.scan("user input to remember")
|
|
72
90
|
|
|
73
|
-
if
|
|
91
|
+
if result.allowed:
|
|
92
|
+
save_to_memory(result) # safe — store it
|
|
93
|
+
else:
|
|
74
94
|
print(f"Blocked: {result.firewall.reason}")
|
|
75
95
|
print(f"Threats: {result.firewall.threat_indicators}")
|
|
76
|
-
|
|
77
|
-
print(f"Safe (trust: {result.trust.score})")
|
|
96
|
+
# don't store — content failed security checks
|
|
78
97
|
```
|
|
79
98
|
|
|
80
99
|
## Async Support
|
|
@@ -88,6 +107,8 @@ async with AsyncShieldCortex(api_key="sc_live_...") as client:
|
|
|
88
107
|
|
|
89
108
|
## Batch Scanning
|
|
90
109
|
|
|
110
|
+
Scan up to 100 items in a single request — useful for bulk-importing memory entries:
|
|
111
|
+
|
|
91
112
|
```python
|
|
92
113
|
from shieldcortex import BatchItem
|
|
93
114
|
|
|
@@ -98,25 +119,9 @@ result = client.scan_batch([
|
|
|
98
119
|
print(f"Scanned: {result.total_scanned}, Threats: {result.threats}")
|
|
99
120
|
```
|
|
100
121
|
|
|
101
|
-
## Audit Logs
|
|
102
|
-
|
|
103
|
-
```python
|
|
104
|
-
from shieldcortex import AuditQuery
|
|
105
|
-
|
|
106
|
-
# Query with filters
|
|
107
|
-
logs = client.get_audit_logs(AuditQuery(level="BLOCK", limit=10))
|
|
108
|
-
|
|
109
|
-
# Auto-paginate through all entries
|
|
110
|
-
for entry in client.iter_audit_logs():
|
|
111
|
-
print(entry.id, entry.firewall_result)
|
|
112
|
-
|
|
113
|
-
# Export as CSV
|
|
114
|
-
csv = client.export_audit_logs(format="csv")
|
|
115
|
-
```
|
|
116
|
-
|
|
117
122
|
## CrewAI Integration
|
|
118
123
|
|
|
119
|
-
|
|
124
|
+
Add a security gate between your CrewAI agent and its memory store. The guard scans all content before it's saved — blocking prompt injection and credential leaks:
|
|
120
125
|
|
|
121
126
|
```python
|
|
122
127
|
from shieldcortex import ShieldCortex
|
|
@@ -134,7 +139,7 @@ except MemoryBlockedError as e:
|
|
|
134
139
|
|
|
135
140
|
## LangChain Integration
|
|
136
141
|
|
|
137
|
-
|
|
142
|
+
Automatically scan all LLM inputs and outputs as they flow through your chain — no changes to your existing code:
|
|
138
143
|
|
|
139
144
|
```python
|
|
140
145
|
from shieldcortex import AsyncShieldCortex
|
|
@@ -143,10 +148,30 @@ from shieldcortex.integrations.langchain import ShieldCortexCallbackHandler
|
|
|
143
148
|
client = AsyncShieldCortex(api_key="sc_live_...")
|
|
144
149
|
handler = ShieldCortexCallbackHandler(client, raise_on_block=True)
|
|
145
150
|
|
|
146
|
-
#
|
|
151
|
+
# Scans inputs on chain start, outputs on LLM end, and tool I/O
|
|
147
152
|
llm = ChatOpenAI(callbacks=[handler])
|
|
148
153
|
```
|
|
149
154
|
|
|
155
|
+
## Audit Logs
|
|
156
|
+
|
|
157
|
+
Every scan is logged. Query your history, export for compliance, or auto-paginate through all entries:
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from shieldcortex import AuditQuery
|
|
161
|
+
|
|
162
|
+
# Query with filters
|
|
163
|
+
logs = client.get_audit_logs(AuditQuery(level="BLOCK", limit=10))
|
|
164
|
+
|
|
165
|
+
# Auto-paginate through all entries
|
|
166
|
+
for entry in client.iter_audit_logs():
|
|
167
|
+
print(entry.id, entry.firewall_result)
|
|
168
|
+
|
|
169
|
+
# Export as CSV — returns the raw body plus integrity headers
|
|
170
|
+
export = client.export_audit_logs(format="csv")
|
|
171
|
+
print(export.content)
|
|
172
|
+
print(export.headers.sha256) # None ⇒ export unverifiable
|
|
173
|
+
```
|
|
174
|
+
|
|
150
175
|
## Error Handling
|
|
151
176
|
|
|
152
177
|
```python
|
|
@@ -162,23 +187,60 @@ except ValidationError:
|
|
|
162
187
|
print("Invalid request")
|
|
163
188
|
```
|
|
164
189
|
|
|
165
|
-
##
|
|
190
|
+
## API Coverage
|
|
166
191
|
|
|
167
|
-
The SDK covers
|
|
192
|
+
The SDK covers the full customer surface documented in the SDK lockstep contract:
|
|
168
193
|
|
|
169
194
|
| Category | Methods |
|
|
170
195
|
|----------|---------|
|
|
171
196
|
| **Scanning** | `scan()`, `scan_batch()`, `scan_skill()` |
|
|
172
|
-
| **Audit** | `get_audit_logs()`, `get_audit_entry()`, `get_audit_stats()`, `get_audit_trends()`, `export_audit_logs()`, `iter_audit_logs()` |
|
|
197
|
+
| **Audit** | `get_audit_logs()`, `get_audit_entry()`, `get_audit_stats()`, `get_audit_trends()`, `export_audit_logs()`, `iter_audit_logs()`, `ingest_audit_events()`, `get_iron_dome_stats()`, `get_iron_dome_events()` |
|
|
198
|
+
| **Audit Export Manifests** | `list_audit_exports()`, `get_audit_export_manifest()`, `verify_audit_export()`, `list_audit_export_verifications()` |
|
|
173
199
|
| **Quarantine** | `get_quarantine()`, `get_quarantine_item()`, `review_quarantine_item()` |
|
|
174
200
|
| **API Keys** | `create_api_key()`, `list_api_keys()`, `revoke_api_key()` |
|
|
175
201
|
| **Teams** | `get_team()`, `update_team()`, `get_team_members()`, `get_usage()` |
|
|
176
202
|
| **Invites** | `create_invite()`, `list_invites()`, `delete_invite()`, `resend_invite()` |
|
|
177
|
-
| **Billing** | `create_checkout_session()`, `create_portal_session()` |
|
|
203
|
+
| **Billing** (deprecated) | `create_checkout_session()`, `create_portal_session()` — self-serve plans retired 2026-07; retained for grandfathered licence holders |
|
|
178
204
|
| **Devices** | `get_devices()`, `register_device()`, `update_device()`, `device_heartbeat()` |
|
|
179
205
|
| **Alerts** | `get_alerts()`, `create_alert()`, `update_alert()`, `delete_alert()` |
|
|
180
206
|
| **Webhooks** | `get_webhooks()`, `create_webhook()`, `update_webhook()`, `delete_webhook()`, `test_webhook()`, `get_webhook_deliveries()` |
|
|
181
207
|
| **Firewall Rules** | `get_firewall_rules()`, `get_active_firewall_rules()`, `create_firewall_rule()`, `update_firewall_rule()`, `delete_firewall_rule()` |
|
|
208
|
+
| **Iron Dome** | `get_injection_patterns()`, `get_injection_patterns_sync()`, `create_injection_pattern()`, `update_injection_pattern()`, `test_injection_pattern()`, `delete_injection_pattern()`, `get_iron_dome_policies()`, `get_iron_dome_policy_sync()`, `create_iron_dome_policy()`, `update_iron_dome_policy()`, `set_default_iron_dome_policy()`, `delete_iron_dome_policy()` |
|
|
209
|
+
| **Verification** | `submit_verification()`, `list_verifications()`, `get_verification()`, `get_verification_stats()`, `delete_verification()` |
|
|
210
|
+
| **Skills** | `ingest_skill_scans()`, `list_skill_scans()` |
|
|
211
|
+
| **Threats** | `report_threat()` |
|
|
212
|
+
| **Incidents** | `replay_incidents()` |
|
|
213
|
+
| **Recall** | `explain_recall()` |
|
|
214
|
+
| **Sync** | `get_sync_health()`, `push_memories()`, `list_synced_memories()`, `push_memory_graph()` |
|
|
215
|
+
| **Licence** | `get_license()`, `regenerate_license()` |
|
|
216
|
+
|
|
217
|
+
### Deferred endpoints
|
|
218
|
+
|
|
219
|
+
The audit **verification-export download chain** (`GET .../verifications/export`,
|
|
220
|
+
`GET .../verification-exports`, `GET .../verification-exports/{id}` and its
|
|
221
|
+
`/download`) is deliberately deferred — it serves CLI tooling rather than SDK
|
|
222
|
+
consumers. See `tests/endpoint_manifest.py` for the canonical list.
|
|
223
|
+
|
|
224
|
+
### Out of scope
|
|
225
|
+
|
|
226
|
+
- `/v1/platform/*` — platform-owner operations
|
|
227
|
+
- `/v1/auth/*` — magic-link login flows (browser/dashboard, not API-key auth)
|
|
228
|
+
- `/v1/customizer/*` — retired 2026-07
|
|
229
|
+
|
|
230
|
+
Additional dashboard/session-scoped `/v1` routes exist server-side; they sit
|
|
231
|
+
outside the SDK's API-key surface.
|
|
232
|
+
|
|
233
|
+
### Cross-SDK policy notes
|
|
234
|
+
|
|
235
|
+
The Python and TypeScript SDKs cover the same endpoint manifest, with two
|
|
236
|
+
deliberate differences:
|
|
237
|
+
|
|
238
|
+
1. **Deletes** — the TypeScript SDK returns `void` from every delete method;
|
|
239
|
+
the Python SDK returns the typed response body where the server sends one
|
|
240
|
+
(per-language internal consistency).
|
|
241
|
+
2. **Audit export** — both SDKs return the raw file content together with the
|
|
242
|
+
parsed `X-ShieldCortex-Export-*` integrity headers. An absent `sha256` or
|
|
243
|
+
`signature` header means the export is unverifiable.
|
|
182
244
|
|
|
183
245
|
## Documentation
|
|
184
246
|
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# shieldcortex
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/shieldcortex/)
|
|
4
|
+
[](https://pypi.org/project/shieldcortex/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Official Python SDK for the [ShieldCortex](https://shieldcortex.ai) API — AI memory security scanning.
|
|
8
|
+
|
|
9
|
+
## How It Works
|
|
10
|
+
|
|
11
|
+
AI agents store memories (user inputs, tool outputs, conversation history) to improve over time. But those memories are an attack surface — prompt injection, credential leaks, and encoding attacks can all be smuggled into memory stores.
|
|
12
|
+
|
|
13
|
+
ShieldCortex scans content **before** it reaches your agent's memory through a 6-layer defence pipeline:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
Agent receives content
|
|
17
|
+
│
|
|
18
|
+
▼
|
|
19
|
+
ShieldCortex scan ──→ BLOCK → reject, log threat
|
|
20
|
+
│
|
|
21
|
+
▼
|
|
22
|
+
ALLOW ──→ safe to store in memory
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The SDK sends content to the ShieldCortex cloud API and returns a verdict: **ALLOW**, **BLOCK**, or **QUARANTINE** — along with trust scores, threat indicators, and sensitivity classification.
|
|
26
|
+
|
|
27
|
+
**Get an API key** at [shieldcortex.ai](https://shieldcortex.ai) (free tier: 500 scans/month).
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install shieldcortex
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
With framework integrations:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pip install shieldcortex[crewai] # CrewAI memory guard
|
|
39
|
+
pip install shieldcortex[langchain] # LangChain callback handler
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
from shieldcortex import ShieldCortex
|
|
46
|
+
|
|
47
|
+
client = ShieldCortex(api_key="sc_live_...")
|
|
48
|
+
|
|
49
|
+
# Scan content before storing in your agent's memory
|
|
50
|
+
result = client.scan("user input to remember")
|
|
51
|
+
|
|
52
|
+
if result.allowed:
|
|
53
|
+
save_to_memory(result) # safe — store it
|
|
54
|
+
else:
|
|
55
|
+
print(f"Blocked: {result.firewall.reason}")
|
|
56
|
+
print(f"Threats: {result.firewall.threat_indicators}")
|
|
57
|
+
# don't store — content failed security checks
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Async Support
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from shieldcortex import AsyncShieldCortex
|
|
64
|
+
|
|
65
|
+
async with AsyncShieldCortex(api_key="sc_live_...") as client:
|
|
66
|
+
result = await client.scan("user input here")
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Batch Scanning
|
|
70
|
+
|
|
71
|
+
Scan up to 100 items in a single request — useful for bulk-importing memory entries:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from shieldcortex import BatchItem
|
|
75
|
+
|
|
76
|
+
result = client.scan_batch([
|
|
77
|
+
BatchItem(content="memory entry 1"),
|
|
78
|
+
BatchItem(content="memory entry 2"),
|
|
79
|
+
])
|
|
80
|
+
print(f"Scanned: {result.total_scanned}, Threats: {result.threats}")
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CrewAI Integration
|
|
84
|
+
|
|
85
|
+
Add a security gate between your CrewAI agent and its memory store. The guard scans all content before it's saved — blocking prompt injection and credential leaks:
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from shieldcortex import ShieldCortex
|
|
89
|
+
from shieldcortex.integrations.crewai import ShieldCortexMemoryGuard, MemoryBlockedError
|
|
90
|
+
|
|
91
|
+
client = ShieldCortex(api_key="sc_live_...")
|
|
92
|
+
guard = ShieldCortexMemoryGuard(client, mode="strict")
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
guard.check("content to remember")
|
|
96
|
+
# Safe — save to memory store
|
|
97
|
+
except MemoryBlockedError as e:
|
|
98
|
+
print(f"Blocked: {e.result.firewall.reason}")
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## LangChain Integration
|
|
102
|
+
|
|
103
|
+
Automatically scan all LLM inputs and outputs as they flow through your chain — no changes to your existing code:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from shieldcortex import AsyncShieldCortex
|
|
107
|
+
from shieldcortex.integrations.langchain import ShieldCortexCallbackHandler
|
|
108
|
+
|
|
109
|
+
client = AsyncShieldCortex(api_key="sc_live_...")
|
|
110
|
+
handler = ShieldCortexCallbackHandler(client, raise_on_block=True)
|
|
111
|
+
|
|
112
|
+
# Scans inputs on chain start, outputs on LLM end, and tool I/O
|
|
113
|
+
llm = ChatOpenAI(callbacks=[handler])
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Audit Logs
|
|
117
|
+
|
|
118
|
+
Every scan is logged. Query your history, export for compliance, or auto-paginate through all entries:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from shieldcortex import AuditQuery
|
|
122
|
+
|
|
123
|
+
# Query with filters
|
|
124
|
+
logs = client.get_audit_logs(AuditQuery(level="BLOCK", limit=10))
|
|
125
|
+
|
|
126
|
+
# Auto-paginate through all entries
|
|
127
|
+
for entry in client.iter_audit_logs():
|
|
128
|
+
print(entry.id, entry.firewall_result)
|
|
129
|
+
|
|
130
|
+
# Export as CSV — returns the raw body plus integrity headers
|
|
131
|
+
export = client.export_audit_logs(format="csv")
|
|
132
|
+
print(export.content)
|
|
133
|
+
print(export.headers.sha256) # None ⇒ export unverifiable
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Error Handling
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from shieldcortex.errors import AuthError, RateLimitError, ValidationError
|
|
140
|
+
|
|
141
|
+
try:
|
|
142
|
+
result = client.scan("content")
|
|
143
|
+
except AuthError:
|
|
144
|
+
print("Invalid API key")
|
|
145
|
+
except RateLimitError as e:
|
|
146
|
+
print(f"Rate limited, retry after {e.retry_after}s")
|
|
147
|
+
except ValidationError:
|
|
148
|
+
print("Invalid request")
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## API Coverage
|
|
152
|
+
|
|
153
|
+
The SDK covers the full customer surface documented in the SDK lockstep contract:
|
|
154
|
+
|
|
155
|
+
| Category | Methods |
|
|
156
|
+
|----------|---------|
|
|
157
|
+
| **Scanning** | `scan()`, `scan_batch()`, `scan_skill()` |
|
|
158
|
+
| **Audit** | `get_audit_logs()`, `get_audit_entry()`, `get_audit_stats()`, `get_audit_trends()`, `export_audit_logs()`, `iter_audit_logs()`, `ingest_audit_events()`, `get_iron_dome_stats()`, `get_iron_dome_events()` |
|
|
159
|
+
| **Audit Export Manifests** | `list_audit_exports()`, `get_audit_export_manifest()`, `verify_audit_export()`, `list_audit_export_verifications()` |
|
|
160
|
+
| **Quarantine** | `get_quarantine()`, `get_quarantine_item()`, `review_quarantine_item()` |
|
|
161
|
+
| **API Keys** | `create_api_key()`, `list_api_keys()`, `revoke_api_key()` |
|
|
162
|
+
| **Teams** | `get_team()`, `update_team()`, `get_team_members()`, `get_usage()` |
|
|
163
|
+
| **Invites** | `create_invite()`, `list_invites()`, `delete_invite()`, `resend_invite()` |
|
|
164
|
+
| **Billing** (deprecated) | `create_checkout_session()`, `create_portal_session()` — self-serve plans retired 2026-07; retained for grandfathered licence holders |
|
|
165
|
+
| **Devices** | `get_devices()`, `register_device()`, `update_device()`, `device_heartbeat()` |
|
|
166
|
+
| **Alerts** | `get_alerts()`, `create_alert()`, `update_alert()`, `delete_alert()` |
|
|
167
|
+
| **Webhooks** | `get_webhooks()`, `create_webhook()`, `update_webhook()`, `delete_webhook()`, `test_webhook()`, `get_webhook_deliveries()` |
|
|
168
|
+
| **Firewall Rules** | `get_firewall_rules()`, `get_active_firewall_rules()`, `create_firewall_rule()`, `update_firewall_rule()`, `delete_firewall_rule()` |
|
|
169
|
+
| **Iron Dome** | `get_injection_patterns()`, `get_injection_patterns_sync()`, `create_injection_pattern()`, `update_injection_pattern()`, `test_injection_pattern()`, `delete_injection_pattern()`, `get_iron_dome_policies()`, `get_iron_dome_policy_sync()`, `create_iron_dome_policy()`, `update_iron_dome_policy()`, `set_default_iron_dome_policy()`, `delete_iron_dome_policy()` |
|
|
170
|
+
| **Verification** | `submit_verification()`, `list_verifications()`, `get_verification()`, `get_verification_stats()`, `delete_verification()` |
|
|
171
|
+
| **Skills** | `ingest_skill_scans()`, `list_skill_scans()` |
|
|
172
|
+
| **Threats** | `report_threat()` |
|
|
173
|
+
| **Incidents** | `replay_incidents()` |
|
|
174
|
+
| **Recall** | `explain_recall()` |
|
|
175
|
+
| **Sync** | `get_sync_health()`, `push_memories()`, `list_synced_memories()`, `push_memory_graph()` |
|
|
176
|
+
| **Licence** | `get_license()`, `regenerate_license()` |
|
|
177
|
+
|
|
178
|
+
### Deferred endpoints
|
|
179
|
+
|
|
180
|
+
The audit **verification-export download chain** (`GET .../verifications/export`,
|
|
181
|
+
`GET .../verification-exports`, `GET .../verification-exports/{id}` and its
|
|
182
|
+
`/download`) is deliberately deferred — it serves CLI tooling rather than SDK
|
|
183
|
+
consumers. See `tests/endpoint_manifest.py` for the canonical list.
|
|
184
|
+
|
|
185
|
+
### Out of scope
|
|
186
|
+
|
|
187
|
+
- `/v1/platform/*` — platform-owner operations
|
|
188
|
+
- `/v1/auth/*` — magic-link login flows (browser/dashboard, not API-key auth)
|
|
189
|
+
- `/v1/customizer/*` — retired 2026-07
|
|
190
|
+
|
|
191
|
+
Additional dashboard/session-scoped `/v1` routes exist server-side; they sit
|
|
192
|
+
outside the SDK's API-key surface.
|
|
193
|
+
|
|
194
|
+
### Cross-SDK policy notes
|
|
195
|
+
|
|
196
|
+
The Python and TypeScript SDKs cover the same endpoint manifest, with two
|
|
197
|
+
deliberate differences:
|
|
198
|
+
|
|
199
|
+
1. **Deletes** — the TypeScript SDK returns `void` from every delete method;
|
|
200
|
+
the Python SDK returns the typed response body where the server sends one
|
|
201
|
+
(per-language internal consistency).
|
|
202
|
+
2. **Audit export** — both SDKs return the raw file content together with the
|
|
203
|
+
parsed `X-ShieldCortex-Export-*` integrity headers. An absent `sha256` or
|
|
204
|
+
`signature` header means the export is unverifiable.
|
|
205
|
+
|
|
206
|
+
## Documentation
|
|
207
|
+
|
|
208
|
+
- [ShieldCortex Docs](https://shieldcortex.ai/docs)
|
|
209
|
+
- [API Reference](https://shieldcortex.ai/docs)
|
|
210
|
+
- [Examples](examples/)
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
MIT
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""Audit log querying and export example."""
|
|
2
|
+
|
|
3
|
+
from shieldcortex import ShieldCortex, AuditQuery
|
|
4
|
+
|
|
5
|
+
client = ShieldCortex(api_key="sc_live_YOUR_KEY_HERE")
|
|
6
|
+
|
|
7
|
+
# Get summary stats
|
|
8
|
+
stats = client.get_audit_stats(time_range="7d")
|
|
9
|
+
print(f"Total operations: {stats.total_operations}")
|
|
10
|
+
print(f"Allowed: {stats.allowed_count}")
|
|
11
|
+
print(f"Blocked: {stats.blocked_count}")
|
|
12
|
+
print(f"Quarantined: {stats.quarantined_count}")
|
|
13
|
+
|
|
14
|
+
# Query blocked entries
|
|
15
|
+
logs = client.get_audit_logs(AuditQuery(level="BLOCK", limit=5))
|
|
16
|
+
print(f"\nRecent blocks ({logs.total} total):")
|
|
17
|
+
for entry in logs.logs:
|
|
18
|
+
print(f" [{entry.timestamp}] {entry.reason} (trust: {entry.trust_score})")
|
|
19
|
+
|
|
20
|
+
# Auto-paginate through all entries
|
|
21
|
+
print("\nAll audit entries:")
|
|
22
|
+
for entry in client.iter_audit_logs(AuditQuery(level="BLOCK")):
|
|
23
|
+
print(f" #{entry.id}: {entry.firewall_result}")
|
|
24
|
+
|
|
25
|
+
# Export as CSV — returns the raw body plus X-ShieldCortex-Export-* integrity headers
|
|
26
|
+
export = client.export_audit_logs(format="csv")
|
|
27
|
+
with open("audit_export.csv", "w") as f:
|
|
28
|
+
f.write(export.content)
|
|
29
|
+
print("\nExported to audit_export.csv")
|
|
30
|
+
|
|
31
|
+
# Verify the export's integrity. sha256/signature/manifest_id are None when
|
|
32
|
+
# the server did not send them — the export is unverifiable, never "".
|
|
33
|
+
headers = export.headers
|
|
34
|
+
if headers.sha256 is None or headers.signature is None:
|
|
35
|
+
print("Export is UNVERIFIABLE — integrity headers absent")
|
|
36
|
+
else:
|
|
37
|
+
print(f"Entries: {headers.count}")
|
|
38
|
+
print(f"SHA-256: {headers.sha256}")
|
|
39
|
+
print(f"Signature ({headers.signature_algorithm}): {headers.signature}")
|
|
40
|
+
if headers.manifest_id is not None:
|
|
41
|
+
# Server-side check against the persisted, signed manifest
|
|
42
|
+
response = client.verify_audit_export(
|
|
43
|
+
headers.manifest_id, export_sha256=headers.sha256
|
|
44
|
+
)
|
|
45
|
+
result = response.verification
|
|
46
|
+
print(f"Manifest {headers.manifest_id}:")
|
|
47
|
+
print(f" signature valid: {result.signature_valid}")
|
|
48
|
+
print(f" sha256 matches: {result.sha256_matches}")
|