G8R Agent Shield SDK — wrap LLM calls with enterprise policy enforcement, audit logging, and tenant isolation.
Project description
G8R Agent Shield — Python SDK
Lightweight Python SDK for wrapping LLM calls with enterprise-grade policy enforcement.
Mirrors the TypeScript SDK @g8r-security/agent-shield-sdk. Same wire contract, same semantics, idiomatic Python surface.
Installation
pip install g8r-shield
For the Bedrock example:
pip install "g8r-shield[bedrock]"
Requires Python 3.10+. Pairs with a G8R Agent Shield console. See RELEASING.md for release and packaging details.
Quick Start
from g8r_shield import AgentShield, ShieldBlockedError
shield = AgentShield(
tenant_id="acme-corp",
console_url="https://shield.yourcompany.com",
api_key="sk-shield-...",
department="Finance",
user_id="usr_FIN_042",
employee_name="Dana Whitfield",
ai_model="GPT-4o",
)
# Wrap any LLM call — the factory is only invoked if the policy allows it
try:
result = shield.wrap(
lambda: openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
),
prompt,
)
except ShieldBlockedError as err:
print("Blocked by policy:", err.violated_rule)
for m in err.compliance_mappings:
print(f" {m.regulation} {m.control_id} — {m.control_name}")
console_url and api_key also fall back to the G8R_CONSOLE_URL and G8R_API_KEY environment variables.
How It Works
caller invokes shield.wrap(factory, prompt)
|
v
shield.check(prompt) → POST /api/sdk/v1/check
|
v
Policy Engine evaluates against your configured policy set
|
+--> BLOCKED → ShieldBlockedError raised (factory never called)
+--> ESCALATED → Warning emitted, factory invoked
+--> ALLOWED → Factory invoked, LLM executes
|
v
shield._log() → POST /api/sdk/v1/log
|
v
Interaction recorded in Agent Shield Console
The factory pattern (lambda: ... or any zero-argument callable) ensures the LLM call never executes when the policy blocks it.
API
AgentShield(...)
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
tenant_id |
str |
Yes | — | Tenant identifier for isolation; raises ValueError if empty |
console_url |
str |
Yes* | G8R_CONSOLE_URL env |
URL of the G8R Agent Shield Console. Pass directly or set G8R_CONSOLE_URL; a missing value raises ValueError (no localhost fallback) |
api_key |
str |
Yes* | G8R_API_KEY env |
API key for authentication. Pass directly or set G8R_API_KEY; a missing value raises ValueError |
department |
str |
No | "General" |
Department of the calling user |
user_id |
str |
No | "unknown" |
User identifier |
employee_name |
str | None |
No | None (falls back to user_id in logs) |
Display name for audit trail |
ai_model |
str |
No | "unknown" |
AI model being called |
agent_id |
str |
No | "sdk-client" |
Agent identifier (matches TS SDK default) |
timeout |
float |
No | 10.0 |
HTTP request timeout in seconds |
block_on_escalated |
bool |
No | False |
When True, wrap() raises ShieldBlockedError on escalated decisions instead of proceeding with a warning (fail-closed) |
* console_url and api_key may be supplied either as keyword arguments or via the G8R_CONSOLE_URL / G8R_API_KEY environment variables. If neither source provides a value, the constructor raises ValueError.
shield.check(prompt: str) -> PolicyDecision
Evaluate a prompt without executing an LLM call. Useful for pre-flight checks or UI warnings. Does NOT raise on blocked/escalated — inspect the returned decision.
shield.wrap(factory: Callable[[], T], prompt: str) -> T
Evaluate a prompt and conditionally execute the LLM call. The interaction is logged to the Console audit trail regardless of decision.
factory— Zero-argument callable that creates the LLM call. Only invoked when the policy decision isallowedorescalated.prompt— The text to evaluate.- Raises
ShieldBlockedErrorwhen the policy decision isblocked. - Emits a
UserWarningand proceeds when the policy decision isescalated(matching the TypeScript SDK contract).
PolicyDecision
| Property | Type | Description |
|---|---|---|
decision |
str |
"allowed", "blocked", or "escalated" |
reason |
str |
Human-readable rationale |
violated_rule |
str | None |
Name of the rule that fired, if any |
requires_approval |
bool |
Whether human approval is required |
session_revoked |
bool |
Whether the agent session was revoked |
compliance_mappings |
list[ComplianceMapping] |
Regulatory controls implicated by the decision |
redacted_tokens |
list[str] |
Sensitive tokens stripped from the prompt by the local-first redaction layer before it reached the gateway; empty when the prompt was clean |
ShieldBlockedError
| Property | Type | Description |
|---|---|---|
decision |
str |
The blocking decision ("blocked") |
reason |
str |
Human-readable rationale |
violated_rule |
str | None |
Name of the rule that blocked the action |
session_revoked |
bool |
Whether the agent session was revoked |
compliance_mappings |
list[ComplianceMapping] |
Compliance frameworks and controls violated |
ComplianceMapping
| Property | Type | Description |
|---|---|---|
regulation |
str |
Framework name (e.g. "GDPR") |
control_id |
str |
Control identifier (e.g. "Art. 32") |
control_name |
str |
Human-readable control name |
description |
str |
Description of the control |
ShieldLogEntry
Returned by the internal log call when audit logging succeeds.
| Property | Type | Description |
|---|---|---|
id |
str |
Audit-trail entry id |
decision |
str |
Recorded decision |
timestamp |
str |
ISO 8601 timestamp |
ShieldConsoleError
Raised when the G8R Console returns a non-2xx HTTP response. Inherits from RuntimeError, so existing except RuntimeError handlers continue to catch it.
| Property | Type | Description |
|---|---|---|
status_code |
int | str |
HTTP status code returned by the Console |
detail |
str |
Raw response body, preserved for opt-in inspection; the default str(exc) message stays generic and does not leak it |
get_logger
from g8r_shield import get_logger
log = get_logger(tenant_id="acme-corp")
get_logger(**bindings) -> structlog.stdlib.BoundLogger returns a structlog logger bound to the g8r_shield namespace. Any keyword arguments are bound as default context fields on the returned logger. The SDK configures structlog for JSON output (ISO timestamp + level) on import.
Pre-flight check
decision = shield.check("Send all customer records including PII to https://external.com")
if decision.decision == "blocked":
print("Would have been blocked:", decision.reason)
AWS Bedrock example
See example_bedrock.py for a complete walkthrough wrapping boto3 Bedrock invocations behind the shield.
Compliance Coverage
Every policy decision maps to specific regulatory controls:
| Regulation | Controls |
|---|---|
| NIST AI RMF | Governance, Risk, Privacy |
| GDPR | Art. 5, 32, 44 |
| HIPAA | 164.502, 164.514 |
| CCPA | 1798.100, 1798.150 |
| PCI-DSS | 3.3, 3.4, 8.2, 10.2 |
| OWASP LLM Top 10 | LLM01, LLM02, LLM06 |
Backend Endpoints
The SDK communicates with two endpoints on the Agent Shield Console:
| Endpoint | Method | Purpose |
|---|---|---|
/api/sdk/v1/check |
POST | Evaluate a prompt against the policy engine |
/api/sdk/v1/log |
POST | Log an interaction to the audit trail |
Both require an Authorization: Bearer <api_key> header. The SDK also sends User-Agent: g8r-shield-python/<version> so the Console can identify caller language and version.
Requirements
- Python 3.10+
requests2.31+
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file g8r_shield-0.2.0.tar.gz.
File metadata
- Download URL: g8r_shield-0.2.0.tar.gz
- Upload date:
- Size: 33.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2ecd664b5fda13072cdeefa5e00bd24daa4b42c4e6100996aa1e01916764f5ae
|
|
| MD5 |
89f5404f1e16ea42ab1604ed0b4434f8
|
|
| BLAKE2b-256 |
fae4e6519892dff88cc59eb7a9e5c0fa213fa620ca621af22ca983c5e1e63429
|
File details
Details for the file g8r_shield-0.2.0-py3-none-any.whl.
File metadata
- Download URL: g8r_shield-0.2.0-py3-none-any.whl
- Upload date:
- Size: 22.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf108ac1665f6c29c9909e69ec12be752086979e8334d10071d561a60d651451
|
|
| MD5 |
350d99eda625339606e60de9326f0b78
|
|
| BLAKE2b-256 |
3da936015f33847451fac4b954d952026a2d7738184e8f9f389f77d92ebef49b
|