Skip to content

Architecture

English | 한국어

Responsibility Boundary

Spring AI Privacy Guardrails tokenizes PII detected by analyzers before sending data to a model, replacing it with request-scoped opaque tokens. These replacement strings do not directly reveal the original values. Immediately before tool execution, it restores only the original values allowed by policy and re-protects the results afterward. When output protection is enabled, it also applies the configured policy to the final response.

flowchart TD
    A["Input · Memory · RAG"] --> B["Detect PII<br/>then tokenize it"]
    B --> C["Model"]
    C -. "Tool call" .-> D["Tool<br/>(originals only for permitted types)"]
    D -. "Tokenize PII<br/>in the result" .-> C
    C --> E["Inspect final response<br/>(when output protection is enabled)"]
    E --> F["Application"]

Detection offsets always refer to the caller-supplied input text. Analyzers return ranges, entity types, scores, and other evidence; core validates, canonicalizes, and resolves that evidence according to application policy. Mappings between opaque tokens and original values are managed per request through PrivacySession.

The library protects data that crosses supported model, tool, and output boundaries. The optional Spring Security integration can also authorize tool discovery and execution.

Module Structure

This project is a Gradle multi-module library that separates core privacy policy, Spring AI integration, and analyzer integrations.

The diagram shows the main dependencies between this library's modules. Arrows point to the required module. Privacy protection and tool authorization can be used independently or applied together to the same ChatClient.

%%{init: {"flowchart": {"curve": "linear"}}}%%
flowchart LR
    CORE["core"]

    PRES["Presidio integration"] --> CORE
    SAI["Spring AI integration"] --> CORE
    OPEN["OpenNLP integration"] --> CORE
    SEC["Spring Security integration"]

    PRESBOOT["Presidio<br/>Spring Boot Starter"] --> PRES
    BASE["Base<br/>Spring Boot Starter"] --> SAI
    OPENBOOT["OpenNLP<br/>Spring Boot Starter"] --> OPEN
    SECBOOT["Spring Security<br/>Spring Boot Starter"] --> SEC

    PRESBOOT --> BASE
    OPENBOOT --> BASE

The core module has no Spring dependency and provides detection resolution, PII tokenization, session management, and the built-in Regex analyzer. The Presidio and OpenNLP integration modules add the corresponding analyzer integrations on top of these shared capabilities.

The Spring AI integration module connects core to ChatClient, model calls, and tool execution boundaries. The base Spring Boot starter assembles core with the Spring AI integration, while analyzer-specific Spring Boot starters add the corresponding analyzer integration.

The optional Spring Security integration uses Spring AI's tool-calling APIs and Spring Security Core. Its Spring Boot starter can be used independently of the base starter.

Both integration modules depend on spring-ai-privacy-guardrails-spring-ai-boundary. This shared module runs model-request stages in privacy, authorization, then inspection order, skipping unconfigured stages.

To use privacy protection and tool authorization together, add a privacy starter alongside the Spring Security starter and apply both capabilities to the same ChatClient. No Spring Security dependency is added to core or any existing privacy module.

The test-support module provides test-only APIs for verifying privacy behavior. Benchmarks and samples are repository-internal modules for performance measurement and runnable examples and are not published artifacts.

Library APIs and Extension Points

The library provides APIs used directly by applications and extension points for custom implementations. Internal implementation types are not public API and are not part of the compatibility contract.

Role Representative public APIs
Application API PrivacyService, PrivacySession
Analyzer extension PiiAnalyzer, RegexPiiMatchValidator
Tool policy ToolDisclosurePolicy, PrivacyToolCallbackFactory
Spring AI integration PrivacyChatClientConfigurer
Model-request composition ModelRequestBoundaryConfigurer
Spring Security integration ToolAuthorizationContext, SpringSecurityToolBoundary, ToolAuthorizationChatClientFactory, PrivacySecurityChatClientFactory
Test support PrivacyTestProbe, PrivacyTestAssertions, PrivacyTestProbeAssert

This table shows representative APIs only. See the Javadoc for the complete public API.

Detection and Resolution

Each PiiAnalyzer has a unique provider ID and returns detected source ranges as PiiSpan values. The core module applies entity aliases, score thresholds, the detection allowlist, and overlap-resolution rules before deciding which ranges to protect.

Entity labels returned by analyzers are not trusted as-is. Core validates entity-label syntax and reported span ranges, then applies aliases and trusted entity types. Labels that are neither built in nor explicitly trusted are handled as the generic PII entity type.

When an application supplies PiiSpan values directly without running an analyzer, the same core rules for range validation, entity normalization, and overlap resolution still apply. Detection results retain input-text offsets and provenance rather than copying PII substrings from the input text.

The provided Regex, Presidio, and OpenNLP analyzers are implemented for safe reuse across concurrent requests. Presidio request timeouts and retries are managed through library configuration.

A custom PiiAnalyzer or RegexPiiMatchValidator may be invoked concurrently by multiple requests and must therefore be thread-safe. If it adds blocking work such as an external service call, that work must also use an appropriate finite timeout.

Analyzer selection, failure policy, and score thresholds are configured under Detection and Resolution, which also documents overlap-resolution behavior.

Requests and Sessions

Mappings between opaque tokens and original values are managed per request through PrivacySession. Direct core usage and Spring AI integration use the same session model.

Each request receives a separate session, and opaque tokens created in that session are valid only within that request. The Spring AI execution context carries only a session handle. The actual mapping between opaque tokens and original values remains in library-managed internal state and is not included in model requests or tool inputs.

A session is not bound to a specific execution thread, so tool execution can continue on another thread while using the same request session. If the session is missing or already closed, privacy processing fails instead of continuing.

With Spring AI integration, the library automatically cleans up the session mapping when a request completes, fails, or its stream is cancelled. When using the core module's PrivacyService directly, the application manages the session lifecycle explicitly.

Spring AI Execution Flow

The Spring AI integration protects the supported model and tool flow within one request session. When this library's Spring Security integration is applied to the client, it also checks which tools can be shown to the model and whether the requested tools may execute.

sequenceDiagram
    participant A as Application
    participant P as Privacy Guardrails
    participant M as Model
    participant T as Tool

    A->>P: Input · Memory · RAG
    P->>P: Detect PII, then tokenize it

    P->>P: Keep only authorized tools<br/>(with tool authorization)

    P->>M: Protected model request

    opt Tool call
        M->>P: Tool call

        P->>P: Check tool execution permissions<br/>(with tool authorization)

        P->>P: Restore permitted originals
        P->>T: Execute tool
        T-->>P: Tool result
        P->>P: Tokenize PII in the tool result
        P-->>M: Protected tool result
    end

    M-->>P: Final response

    opt Output protection enabled
        P->>P: Inspect final response
    end

    P-->>A: Application output
    P->>P: Clean up session

Tool authorization uses the authentication of the user who started the request. The tool list is authorized before every model call. All requested tools are authorized before any of them execute, and each tool is checked again immediately before it runs. If execution authorization is denied for a tool, its original values are not restored and the tool is not executed. See Tool Authorization for authentication propagation and policy configuration.

PrivacyChatClientConfigurer applies the privacy configuration only to the ChatClient.Builder selected by the application and does not affect other ChatClient instances. A builder derived from an already protected client retains that privacy configuration and should not have PrivacyChatClientConfigurer applied again.

If a privacy boundary cannot resolve its required session, or if the privacy configuration is duplicated, execution fails closed rather than continuing with incomplete protection.

The privacy integration can be used with other Spring AI advisors. Changes to model input, tools, or responses made by an advisor outside the privacy boundary are outside the automatic protection scope. See Apply Privacy Protection to ChatClient for the supported composition rules.

Model and Output

Text in supported model-bound inputs is protected before the model provider is invoked. This includes the initial user input as well as supported message and tool-related text that is later sent to the model.

Supported Message implementations preserve the fields required by their contracts while applying privacy protection. Unsupported Message implementations fail rather than allowing unprotected data to reach the model.

When output protection is enabled, the configured policy is applied to each complete response before it is returned to the application. When a complete response must be inspected, streaming output is buffered until completion so sensitive values split across multiple stream chunks can be inspected as one response.

Apart from reasoning text explicitly supported by the library, response metadata and non-text content such as images and audio are not automatically protected.

Output policy and streaming behavior are documented under Output Policy and Streaming.

Tool Execution

PrivacyToolCallbackFactory is the public API for applying privacy protection to ToolCallback and ToolCallbackProvider instances. Protected tools use the current request session to restore only the original values they need and protect their results again after execution.

Original-value disclosure to tools is default-deny. Tool registration and permission to receive original values are separate concerns: only tools configured for specific entity types receive those originals immediately before execution.

Tool information sent to the model, including the tool name, description, and JSON schema, is also inspected for PII. Tool input is protected before execution, only the required values are selectively restored, and tool results are inspected and protected again before returning to the model or application.

On a protected ChatClient's standard tool path, callbacks that are not wrapped by PrivacyToolCallbackFactory are rejected. Separate execution paths that use a custom ToolCallingManager or ToolCallbackResolver are outside the automatic protection scope.

Logs written or exceptions raised inside a tool after original values have been disclosed are not re-protected and may contain those values.

Detailed disclosure rules and the returnDirect flow are documented under Per-Tool Original Disclosure.

Optional Tool Authorization Boundary

The Spring Security integration shows the model only tools the current user is allowed to use, then checks permission again immediately before each tool runs. Authorization checks use the user's Authentication obtained at the start of the request. Tool authorization can be used on its own or with privacy protection.

flowchart TD
    A["Request user's authentication"] --> D["Tool permission checks"]
    B["Application authorization policy"] --> D
    D --> E["Before each model call:<br/>show only authorized tools"]
    D --> F["Immediately before execution:<br/>recheck permission"]
    F --> G["Execute authorized tool"]

When tool authorization and privacy protection are used together, tool permission is checked before restoring the original PII values allowed for that tool.

The Spring Boot starter provides factories for creating clients with tool authorization. A factory applies authorization to the ChatClient it creates. The configuration of other clients, including those using the same model, is unaffected.

See Spring Security Tool Authorization for authorization policies, custom tool execution, and authentication in asynchronous calls.

Errors and Diagnostics

Library-owned privacy failures use PrivacyGuardrailException and PrivacyFailureCode. These failures do not include original PII or analyzer response bodies; they expose only limited diagnostic information such as the failure category and processing phase.

PiiAnalyzerFailureObserver receives the same sanitized failure information. It cannot change the analysis result, and the information can be used for operational diagnostics such as metrics, tracing, and logs.

The optional PrivacyEnforcementObserver reports PROTECTED, DISCLOSED, and BLOCKED outcomes at the model, tool-input, tool-result, and application-output boundaries. Events contain only boundary and outcome; observer failures cannot affect privacy enforcement.

Exceptions raised by model providers, application tools, and external libraries may propagate using their original exception types. Exceptions and logs created outside the library are outside this sanitization boundary, and whether they record sensitive values depends on the logging configuration of the component that produced them.

Error codes and processing phases are documented under Privacy Error Handling.

Resource Limits and Request Cleanup

Privacy operations performed directly by the library, such as text transformation, structured-value traversal, analyzer-result retention, and response inspection, use processing bounds to keep memory use predictable. See Configuration for the main limits and related settings.

When a Spring AI streaming request is cancelled or fails, the library cleans up the request session and the privacy mappings it manages.

Request cancellation cleans up the session but cannot forcibly stop synchronous analyzer or tool code that is already running. Such implementations need their own timeouts and cancellation handling.

These resource limits apply to privacy inspection and transformation. Execution policies such as model and tool call counts, cost, and concurrency continue to follow the application's or orchestration framework's existing settings.

Test Support

The spring-ai-privacy-guardrails-test module provides test utilities that can record requests sent to the model and inputs passed to tool execution. With a local ChatModel test double, they can verify without calling a remote model that PII did not reach the model, only required original values were disclosed to a tool, and the request session was cleaned up correctly.

PrivacyTestProbe is a test-only API for verifying privacy-boundary behavior. See Test Support for usage.

Analyzer Integration

Analyzer integration modules such as Presidio and OpenNLP translate analyzer detections into the common PiiAnalyzer contract. Regardless of which analyzer is used, downstream detection resolution and per-tool original disclosure continue to follow the shared core rules.

For a remote analyzer service such as Presidio, connection security, credentials, and deployment environment follow that service's configuration. When the application supplies a model, as with OpenNLP, the selected model can affect both detection coverage and quality.

Available analyzer configurations are documented under Starter Selection.

Stored Data

ChatMemory content and RAG results are protected when supported text from them is included in model or tool input. The library does not automatically rewrite data that is already stored.

See Stored Data and Diagnostics for the detailed scope.