Agents and Agentic governance
The SDK exposes two agent-related layers:
| Surface | Purpose | Gateway route |
|---|---|---|
shield.agent | Explicit input/output/action/MCP guardrail checks | /api/guardrails/evaluate |
shield.agentic | Identity-aware policy decisions, Agentic Registry discovery, blueprint attestation, approvals, obligations, and automatic tool enforcement | /api/agentic-new/* with older-gateway compatibility where implemented |
Use shield.agent when content/tool classification is enough. Use
shield.agentic when execution depends on the registered agent, acting user,
resource permission, delegation, tool/action, approval, or workload identity.
Explicit agent guardrails
Section titled “Explicit agent guardrails”shield.agent.check_input("user message")shield.agent.evaluate_tool( name="ledger_read", args={"account": "A-7"}, action_class="read",)shield.agent.check_output("assistant response")See Chat and guardrails for result and exception semantics.
Automatic Agentic enforcement
Section titled “Automatic Agentic enforcement”Constructing a live DeepintShield client installs idempotent guards for
supported framework modules already imported and watches supported late
imports. Current integrations cover LangGraph, LangChain, CrewAI, LlamaIndex,
AutoGen/AG2, PydanticAI, OpenAI Agents SDK, LiteLLM, AWS Strands, Google ADK,
Temporal, and the Hermes tool dispatcher.
from deepintshield import DeepintShieldfrom langgraph.graph import StateGraph
shield = DeepintShield.from_env()
builder = StateGraph(State)# Add your ordinary nodes and tools.app = builder.compile()app.invoke(initial_state)The framework remains a third-party object. At its supported build/run/tool boundary, the SDK reports bounded topology/source evidence, obtains the authoritative decision, applies supported obligations, and stops execution on deny or approval-required outcomes.
Registration lifecycle
Section titled “Registration lifecycle”A new or changed agent blueprint is not automatically trusted. On first execution, the SDK captures bounded, credential-redacted implementation evidence. Common outcomes are:
agent_registration_pending: review and activate the captured agent.agent_not_registered: capture did not persist; verify gateway connectivity and rerun discovery.blueprint_coverage_incomplete: executable source coverage was missing, partial, truncated, or omitted.blueprint_scan_unavailable: the required scan/registration acknowledgement could not be obtained.
Review registrations and blueprint findings in Agentic before retrying. An unchanged approved blueprint avoids repeated scan work, but each governed tool still requires authorization (or a valid decision-cache hit) and therefore has workload-dependent request-path latency.
Direct decision probe
Section titled “Direct decision probe”decide() returns a Decision; it does not raise merely because the verdict is
DENY:
decision = shield.agentic.decide( tool="ledger.post", args={"amount": 12}, action="create_entry", action_class="write", prompt="Post the approved journal entry.",)
if not decision.proceed: print(decision.verdict, decision.decision_id)prompt is supplied for scanning at the PDP boundary. The SDK contract treats
it as scan-only, but applications should still avoid sending secrets that are
not necessary for the decision.
For full control, construct DelegationContext and ContextBag. Optional
application-observed signals include memory integrity, hallucination risk, goal
drift, inter-agent communication integrity, output manipulation, recovery cost,
and RAG provenance. These values influence policy only when your workspace
policy evaluates them; the SDK does not calculate their truth for you.
Govern one function
Section titled “Govern one function”@shield.agentic.tool( "ledger.post", action="create_entry", action_class="write", recovery_cost="high",)def post_entry(row: dict) -> dict: return ledger.insert(row)The decorator supports synchronous functions, coroutines, generators, and
async generators. It performs blueprint preflight and authorization before the
function body or iteration begins. shield_tool(tool=..., client=...) is the
standalone equivalent.
When exactly one live client exists, a bare decorator can resolve it. With
multiple clients, pass client= or bind a request-local run scope; ambiguity
fails closed.
Acting user and run scope
Section titled “Acting user and run scope”with shield.agentic.run( email="alice@example.com", session_id="checkout-req-018",) as run_id: app.invoke(initial_state)run() uses request/task-local context, restores nested state, and carries the
acting principal plus session grouping into governed calls. as_user() binds a
principal until changed; start_run()/end_run() manage a run override
manually. Prefer run() for shared clients and concurrent request handlers.
Identity resolution is designed to be fail-soft for directory creation: if the gateway cannot be reached, it returns a deterministic local subject. Tool authorization itself is fail-closed.
Explicit integration factories
Section titled “Explicit integration factories”Automatic boundaries are preferred for supported versions. Compatibility and plugin APIs remain available:
| Method | Result |
|---|---|
guard() / callback() | LangChain callback handler |
govern(target) | Describe, report, and instrument a supported target |
langgraph(graph) | In-place LangGraph adapter |
crewai(tools) | CrewAI tool adapter |
openai_agents(target) | OpenAI Agents adapter |
llamaindex(tools) | LlamaIndex tool adapter |
autogen(target) | AutoGen tool adapter |
pydanticai(agent) | PydanticAI adapter |
temporal() | Temporal interceptor |
strands() | AWS Strands hook provider |
google_adk() | Google ADK plugin |
hermes(ctx) | Install hooks on a Hermes plugin context |
openclaw_config(...) | OpenClaw provider configuration; tool governance still requires its TypeScript plugin |
Error boundary
Section titled “Error boundary”Application-facing Agentic boundaries translate internal errors to marked standard exceptions:
PermissionErrorfor denials.ConnectionErrorfor gateway/unusable-response failures.RuntimeErrorfor approval, configuration, dependency, registration, and blueprint lifecycle failures.
Read the stable marker through the public error helper rather than coupling to private attribute names:
from deepintshield import get_error_definition, get_exception_error_code
try: post_entry({"amount": 12})except (PermissionError, ConnectionError, RuntimeError) as exc: code = get_exception_error_code(exc) definition = get_error_definition(code) if definition is None: raise log.error("Agentic operation stopped", extra={"code": code})See Error codes for trusted descriptions, retryability, operator actions, and stability guidance, and Agentic control-plane setup for registration and policy workflows.