Getting Started¶
English | 한국어
This guide shows the basic path for adding Spring AI Privacy Guardrails to an existing Spring AI application and applying privacy protection across model, tool, MCP, and output boundaries.
Start with the built-in Regex analyzer for a setup that requires no external analyzer service. For PII detection beyond application-specific patterns, you can integrate Presidio, an open-source framework for PII detection and de-identification, as an external analyzer service.
Use OpenNLP when you want to run your own NER models inside the JVM, or a
custom PiiAnalyzer when you need detection tailored to your application.
The application is expected to already provide a ChatModel and
ChatClient.Builder.
To check protection with a local model and fixed examples, without an external model API key, see the Sample / Demo Guide.
Prerequisites¶
The current code is verified with:
- Java 17
- Spring AI 2.0.1
- Spring Boot 4.1.1
1. Choose a Privacy Starter¶
Choose the starter for the analyzer you want to use. Each linked section includes its Gradle and Maven dependencies.
| Starter | Use |
|---|---|
| Base | Application-defined Regex rules or custom analyzers |
| Presidio | Detect various types of PII through an external Presidio service. |
| OpenNLP | Detect PII inside the application using OpenNLP models you provide. No external analysis service is needed. |
The Presidio and OpenNLP starters already include the base starter. Use the same version for all Privacy Guardrails modules used together. Adding a starter does not enable privacy protection or an analyzer automatically.
Tool authorization uses a separate Spring Security starter. It can be used on its own or together with a privacy starter. See Spring Security Tool Authorization for its dependency and setup.
2. Quick Start with Regex¶
The built-in Regex analyzer is the easiest way to verify the privacy boundary without an external analyzer service.
Add the base starter.
Gradle¶
dependencies {
implementation "io.github.ultramancode:spring-ai-privacy-guardrails-spring-boot-starter:0.3.0"
}
Maven¶
<dependency>
<groupId>io.github.ultramancode</groupId>
<artifactId>spring-ai-privacy-guardrails-spring-boot-starter</artifactId>
<version>0.3.0</version>
</dependency>
Enable Regex and define application-specific identifiers:
spring:
ai:
privacy:
regex:
enabled: true
rules:
- entity-type: EMPLOYEE_ID
pattern: "(?<![A-Za-z0-9_])EMP-[0-9]{4}(?![A-Za-z0-9_])"
score: 0.90
- entity-type: CUSTOMER_ID
pattern: "(?<![A-Za-z0-9_])CUST-[0-9]{6}(?![A-Za-z0-9_])"
score: 0.90
These rules detect only the configured formats. Regex rules are useful for structured application identifiers; they are not intended to provide complete general-purpose PII detection.
Once a PiiAnalyzer bean is available, the starter provides PrivacyService
and PrivacyChatClientConfigurer.
If a format match also needs a checksum or business-rule check, add a custom Regex validator.
3. Protect a ChatClient¶
Configuring an analyzer does not automatically protect every
ChatClient.
Apply the starter-provided PrivacyChatClientConfigurer to each builder that
should be inside the privacy boundary:
@Bean
ChatClient privacyChatClient(
ChatClient.Builder builder,
PrivacyChatClientConfigurer privacyConfigurer
) {
return privacyConfigurer.configure(builder).build();
}
Use the configured client normally:
String response = privacyChatClient.prompt()
.user("Employee EMP-1234 requested customer CUST-123456.")
.call()
.content();
In this library, PII tokenization replaces detected PII with request-scoped opaque tokens before the model call. These replacement strings do not directly reveal the original values.
The example below shows what the model receives. The <opaque> part represents
a value generated for each request.
In this example, the detected employee and customer IDs are not sent to the model as original values. The library manages mappings between opaque tokens and original values for each request. Application logic must not parse opaque token internals or depend on a specific opaque token format.
Direct calls to a ChatModel are outside this automatic boundary.
To inspect the input sent to the model, run the fixed examples in the Privacy Boundary Inspector.
4. Protect Local and MCP Tools¶
Once privacy protection is applied to a tool, detected PII is passed as opaque tokens
by default. If a tool needs an original value, such as a customer ID for a
lookup, specify the tool name and permitted PII types in tools.disclosures.
For both local and MCP tools, the name configured in tools.disclosures is
case-sensitive and must exactly match the actual ToolDefinition.name(). With
this policy, customerLookup receives only customer IDs (CUSTOMER_ID) as
original values. Other detected PII is passed as opaque tokens.
Local ToolCallback¶
Wrap an existing Spring AI ToolCallback before registering it with a protected
ChatClient:
Here, customerLookupToolCallback is the application's existing Spring AI
ToolCallback.
Register the wrapped ToolCallback with the client's defaultTools(...):
ChatClient toolClient = privacyConfigurer.configure(
ChatClient.builder(chatModel)
.defaultTools(protectedCustomerLookup)
).build();
Detected values in tool results are protected again before being sent back to the model or returned directly to the application.
MCP and Dynamic ToolCallbackProvider¶
MCP tool lists can be registered through a ToolCallbackProvider. Wrap the
provider itself with wrapProvider(...) so protection also applies to tools it
supplies in later requests. In this example, mcpToolCallbackProvider is the
ToolCallbackProvider supplied by the application's MCP integration.
ToolCallbackProvider protectedMcpTools =
privacyToolCallbackFactory.wrapProvider(mcpToolCallbackProvider);
Register the wrapped ToolCallbackProvider with the client's defaultTools(...):
ChatClient mcpClient = privacyConfigurer.configure(builder)
.defaultTools(protectedMcpTools)
.build();
If an MCP provider adds a tool-name prefix, configure tools.disclosures with
the final prefixed tool name.
Privacy protection is not applied automatically to separate tool-calling paths
that directly configure ToolCallingManager or ToolCallbackResolver. If your
application uses these paths, integrate privacy protection with them separately.
For an actual local Streamable HTTP MCP round trip showing scoped disclosure and tool-result re-protection, see the Sample / Demo Guide.
Optional Spring Security Tool Authorization¶
To limit which tools the model can discover and execute based on the current
user's permissions, add the Spring Security starter and register a tool
authorization policy as an AuthorizationManager<ToolAuthorizationContext>
bean. Create the ChatClient with the factory bean for the features you need:
- Tool authorization alone: Use
ToolAuthorizationChatClientFactory. No privacy starter or analyzer is required. - Combined with privacy protection: Configure a privacy starter and an
analyzer, then use
PrivacySecurityChatClientFactory. If you configured privacy protection in the preceding steps, use this factory to create the client.
Both factories create clients with builder(chatModel).build(). When both
features are used, permission is checked again immediately before tool
execution, and only then are the original PII values allowed for that tool
restored.
See Spring Security Tool Authorization for starter dependencies, an authorization policy, and client configuration examples.
5. Use Presidio for PII Detection¶
Presidio is an open-source framework for PII detection and de-identification. Use the Presidio starter when you want to detect PII beyond application-specific patterns through an external Presidio Analyzer service.
The Presidio starter already includes the base Privacy Guardrails starter, so do not add the base starter separately when using Presidio. Add another analyzer starter only when that analyzer is also needed.
Gradle¶
dependencies {
implementation "io.github.ultramancode:spring-ai-privacy-guardrails-presidio-spring-boot-starter:0.3.0"
}
Maven¶
<dependency>
<groupId>io.github.ultramancode</groupId>
<artifactId>spring-ai-privacy-guardrails-presidio-spring-boot-starter</artifactId>
<version>0.3.0</version>
</dependency>
Enable Presidio and configure its Analyzer endpoint:
spring:
ai:
privacy:
analysis:
language: en
presidio:
enabled: true
analyzer-url: http://localhost:5002
If you cloned this repository, start its pinned local Presidio service with:
Presidio also requires the PrivacyChatClientConfigurer setup in
Protect a ChatClient. If you already applied it above,
you do not need to configure the client again.
Regex and Presidio may also be enabled together. In the default UNION mode,
all configured analyzers run and their detection findings are merged. The
default REQUIRE_ALL failure policy fails the request if any configured
analyzer fails. Review
Configuration before combining
analyzers in production.
6. Use OpenNLP for JVM-Local Detection¶
Use the OpenNLP starter when detection should run inside the application JVM with application-supplied compatible OpenNLP models.
Gradle¶
dependencies {
implementation "io.github.ultramancode:spring-ai-privacy-guardrails-opennlp-spring-boot-starter:0.3.0"
}
Maven¶
<dependency>
<groupId>io.github.ultramancode</groupId>
<artifactId>spring-ai-privacy-guardrails-opennlp-spring-boot-starter</artifactId>
<version>0.3.0</version>
</dependency>
A minimal PERSON configuration can look like:
spring:
ai:
privacy:
analysis:
language: en
opennlp:
enabled: true
tokenizer-model: classpath:/models/en-token.bin
entity-models:
PERSON: classpath:/models/en-ner-person.bin
OpenNLP model binaries are not bundled with this project. The application owns the model files and must validate model provenance, tokenizer compatibility, and detection quality for the target environment.
tokenizer-model is optional; when omitted, the integration uses OpenNLP's
SimpleTokenizer.
See the Full Sample Guide for the reproducible OpenNLP smoke-test setup.
7. Optional: Protect Final Responses¶
Input and tool boundaries do not automatically enable final-response inspection.
Enable output protection when application-facing responses also need a final privacy check:
Supported output actions are:
TOKENIZE: replace detected PII with request-scoped opaque tokens.REDACT: replace detected PII with typed markers that cannot be restored to the original values.BLOCK: stop response delivery when PII is detected and throwPrivacyOutputBlockedException.
The streaming API remains available when output protection is enabled, but response chunks are not released to the application as soon as they arrive. The library first buffers the complete response, inspects it, and then releases the protected result. This allows PII split across multiple chunks to be detected, but model output cannot be delivered in real time as it is generated.
See Output Policy and Streaming and Input and Response Limits for details.
8. Custom Analyzers¶
Applications can provide custom PiiAnalyzer Spring beans when Regex, Presidio,
or OpenNLP is not the right detector.
Custom analyzers participate in the same detection and resolution flow as the
built-in and optional analyzers, and their findings are enforced at the same
model, tool, and optional output privacy boundaries. A custom PiiAnalyzer may
be invoked concurrently by multiple requests, so it must be thread-safe and
reentrant. Apply finite timeouts to blocking work such as external service calls
and bound its own memory and other resource usage.
See Configuration for analyzer selection, provider IDs, entity aliases, confidence floors, and failure policies. See Custom Analyzers for implementation requirements and analysis of multiple texts.
Boundary Notes¶
A protected ChatClient protects supported message content before it is sent to
the model. This includes supported memory and RAG context that is sent to the
model. It does not automatically modify PII that is already stored in
chat-memory storage, vector stores, databases, logs, or traces.
Next Steps¶
- See Configuration for the complete property and API reference.
- See Privacy-Safe Runtime Observation to observe boundary outcomes without exposing PII or payloads.
- See the Sample / Demo Guide to check protection in Local Tool, RAG, and Streamable HTTP MCP scenarios.
- See Architecture for model, tool, session, and request lifecycle boundaries.
- See Evaluation for the reproducible privacy-boundary verification matrix and benchmarks.
- Review the Threat Model before production use.