Server and Python SDK 3.2.2
DeepIntShield Server 3.2.2 and Python SDK 3.2.2 - 23 October 2026.
This is a correction release on 3.2.1. It carries the corrections made on 22 and 23 October after a review of every error the internal QA testers had recorded against the deployed 3.2.1 and a measured run of the QA catalogue against it, and aligns the SDK, gateway and documentation reference at 3.2.2; every 3.2.1 client keeps working unchanged. Check the version and enabled capabilities of your own gateway: a documentation release does not establish what is deployed.
Decision targets are validated before authorization
Section titled “Decision targets are validated before authorization”POST /api/agentic-new/decide now checks the shape of object and
permission before it asks OpenFGA anything. An object must be <type>:<id>,
where the type is one of the authorization model’s object types and the id
holds no :, #, * or whitespace; a permission must be a relation defined
on that type (can_view, can_edit, can_fulfill, …) or a custom
permission key containing : (invoice:approve), which is checked as a
permission holder. A malformed target answers 400 invalid_object or
400 invalid_permission with a message that names the offending value and the
accepted forms; error.param carries the field, the value and the accepted
types or relations.
Until now such a request reached OpenFGA, which rejected the tuple, and the
decision read authz_engine_error, which told nobody what was wrong. Decisions
recorded by the MCP, task and rehearsal paths carry the same two reasons with
the failed check target; a genuine authorization-engine failure still reads
authz_engine_error. The rules follow the workspace’s pinned model, so types
published through the authorization studio validate too. The Python SDK shows
the code as the exception prefix (invalid_object: ...) followed by the
gateway’s message.
An over-limit blueprint scan is incomplete coverage, not an outage
Section titled “An over-limit blueprint scan is incomplete coverage, not an outage”A complete code capture whose static analysis produced more findings than one
attestation holds could not be persisted: the discover call answered
503 blueprint_scan_unavailable and quarantined the reporter under that code,
as if the scanner were down. Discovery now refuses more than 192 static
findings as 400 blueprint_coverage_incomplete and quarantines the reporter
under that exact code; the caps (256 findings in total, 64 from the model
phase, 192 static) are shared by discovery, the scan store and the handler.
blueprint_scan_unavailable is left for genuine store failures, so an
operator who sees it knows the store failed, and one who sees
blueprint_coverage_incomplete knows the scan ran and the program’s code is
what needs attention.
Guardrail evaluation names the policies it evaluated
Section titled “Guardrail evaluation names the policies it evaluated”The responses of POST /api/guardrails/evaluate and the simulate route gain
an additive policies_evaluated list (id, version_id, name, scope,
enforcement_mode, enabled, matched), omitted when nothing was evaluated.
A caller can now tell that a policy was not part of the evaluation - a rule
left disabled, for example - instead of inferring it from an allow. The
decision fields are unchanged, and a client that ignores fields it does not
know is unaffected.
Multipart uploads and SDP offers reach their handlers
Section titled “Multipart uploads and SDP offers reach their handlers”The request prefilter’s fast JSON check applied to every /v1/* body, so
POST /v1/files (multipart form data) and raw application/sdp bodies on
/v1/realtime/calls were refused with 400 request body is not valid JSON.
The check now applies only to bodies declared, or defaulted, as JSON: file
uploads and realtime SDP offers go through to their handlers, and JSON bodies
are checked exactly as before.
A provider error during a streaming response keeps its status and message
Section titled “A provider error during a streaming response keeps its status and message”An upstream error that arrived once a stream had started was relayed with an
empty message in every protocol format: OpenAI clients saw “An error occurred
during streaming”, Anthropic clients an api_error with no text, Gemini
clients a blank 500. An error that was the stream’s first event went out
under 200 text/event-stream, so a caller whose account had no credits, no
permission or an invalid request learned none of it.
The gateway now reads the first chunk before committing the stream. An error
there answers the real status with the format’s JSON envelope: OpenAI
error.type/code/message, Anthropic
{"type":"error","error":{"type":"rate_limit_error",...}}, Gemini
{"error":{"code":429,"status":"RESOURCE_EXHAUSTED",...}}. A mid-stream error
is emitted as the format’s error event with the status, type and message,
after which the stream ends. The status is the provider’s where it gives one
and otherwise inferred from the error type (insufficient_quota and rate
limits 429, authentication 401, permission 403, not found 404, invalid request
400, overloaded 529, unavailable 503). Native OpenAI-format streams no longer
append [DONE] after an error event. A client that retries on status codes
now sees the status it retries on; a stream that completes is delivered
exactly as before.
Console corrections
Section titled “Console corrections”- Provider keys. A provider key created without an explicit enabled flag could not be disabled: the unchanged-content check skipped the write while the page reported success. The disabled state is now written.
- Guardrail policies. A policy saved without a name was silently stored as
“Untitled Policy”; the API answers
400 Policy name is requiredand the editor shows the message under the field. - Custom pattern cards. A card using JavaScript-only regex syntax (lookahead, lookbehind, backreferences, named groups) passed the browser check and failed at save with a generic prefix; the card editor names the RE2 incompatibility at Create card.
- Numeric limits. Limit fields accepted
100abcor negative values; they accept unsigned decimals only, and the semantic-cache TTL shows its validation message beside the field. - RAG sources. A source could be saved with an empty name; the API answers
400 RAG source name is required. - Field-level errors. A field-level API error (a missing provider name in AI Models, for example) reached the page as “An unexpected error occurred”; the form shows the missing field.
Python SDK 3.2.2
Section titled “Python SDK 3.2.2”- Aligned with Server 3.2.2; the inference, guardrail, RAG, MCP and Agentic APIs are unchanged from 3.2.1.
- A composite LangGraph node no longer quarantines the agent at its first
execution. 3.2.1 covered a LangGraph node built from Runnables - a
RunnableParallel, a chain such asitemgetter("messages") | model, aRunnableBranch, aToolNode, a compiled subgraph - in the discovery report by the composition it dispatches, but the execution gate still attested the node by the framework method it wraps (the bound runnable’sinvoke), which never matched the acknowledged artifact. The first run after approval therefore posted a second, “first-run” capture built from LangGraph’s own source, an incomplete artifact the gateway refuses asblueprint_coverage_incompleteand quarantines the reporting agent for. The gate now attests the node by the same composition text and digest the discovery report carried (the decision fingerprint too), so the approved blueprint is recognised and the run proceeds to the authorization decision. A composition that cannot be read still fails closed. With SDK 3.2.1,RunnableParalleland chain nodes quarantine the agent on their first executed run: upgrade before running such a program.
With AWS Strands Agents 1.62 installed, SDK 3.2.2 refuses to build a client
once strands is imported (governance_configuration_error): it does not
recognise the tool terminal Strands 1.62 introduced. The fix shipped as
Server and Python SDK 3.2.3; until you upgrade, pin
strands-agents<1.62.
QA portal and test catalogue
Section titled “QA portal and test catalogue”The internal test catalogue was corrected with this release. From the error
review: a case whose shared setting was never provided, whose source checkout
is not found, or whose request the workspace’s provider key or model policy
refuses records Blocked with the exact value or setting to change instead of
a traceback; packs print UTF-8 on Windows consoles; source-test cases find the
checkout from the working directory; the sign-in cases start with enabling MFA
on the tester’s own account; a console page that shows a plan upgrade message
is recorded as Blocked; and the console cases were reworded to what the
product offers (Viewer invitations for read-only checks, CSV-only registry
import, comma-separated roles, provider cards in the model catalog). From the
measured run: SDK source cases prescribe the [dev,all] extras (the Strands,
Google ADK and Temporal tests were skipping); the file round-trip cases compare
the stored metadata of a user_data file instead of a download OpenAI refuses
for that purpose; the agentic investigation cases send authorization targets
the gateway evaluates (resource: objects with model relations, custom
permission keys for the counter tools), with the QA provisioning writing the
matching grants, group ownership and delegations; and two runner tools execute
the guardrail-rule family with each rule switched on in turn and the whole
automated catalogue with per-cause classification.
Upgrade
Section titled “Upgrade”python -m pip install --upgrade "deepintshield==3.2.2"# with gateway runtime authentication and LangGraph:python -m pip install --upgrade "deepintshield[runtime,langgraph]==3.2.2"The console ships inside the server image, so Server 3.2.2 and its UI upgrade
together. No configuration change, no new variable and no migration are
required; the authorization model republishes at start, so the decision-target
rules follow each workspace’s pinned model without operator action. Streaming
clients receive the provider’s status for an error from the first chunk on,
and policies_evaluated is an additive field; nothing else changes for
existing clients. For the 3.2.1 changes (MCP tool schemas only for callers that
can use them, JSON 404s for unknown API paths, the cost-optimization cascade
and the model policy, Gemini forced function calls), see
Server and Python SDK 3.2.1.