Skip to content

Data Minimization: deterministic redaction for ETL, RAG, and ChatClient (no extra LLM calls) #6052

Description

@LordKay-sudo

Related issues (searched; not duplicates)

I searched the issue tracker before opening this:

  • #1081 / #1011 — broad behavioral guardrails; no shipped deterministic redaction SPI
  • #1184 — Bedrock provider guardrails, not framework-agnostic minimization
  • #5615 — guardrails for tool calls, not ingest/RAG prompt content
  • #5671, #5903, #5776DocumentPostProcessor for reorder/rerank, not PII/secret redaction

None of the above provide a built-in, dependency-free way to minimize sensitive/proprietary data before it reaches an LLM across ingest, retrieval, and chat.


Expected Behavior

Spring AI provides a small, optional Data Minimization building block (module or package) with:

  1. A pluggable DataMinimizationPolicy (detectors + replacement strategy) that performs no LLM calls
  2. SanitizingDocumentTransformer — implements DocumentTransformer for ETL (redact before embed/index)
  3. SanitizingDocumentPostProcessor — implements DocumentPostProcessor (redact retrieved chunks before QueryAugmenter)
  4. DataMinimizationAdvisor — implements CallAdvisor / StreamAdvisor (final gate on the assembled Prompt)

Built-in v1: RegexSensitiveDataDetector + ReplacementStyle (MASK, REMOVE). TOKENIZE (especially reversible tokenization) deferred to a follow-up. Optional fail-closed mode.

Example (same policy bean wired in all three places):

var policy = DataMinimizationPolicy.builder()
    .detector(RegexSensitiveDataDetector.defaults())
    .replacement(ReplacementStyle.MASK)
    .build();

// ETL — before vector store
vectorStore.write(new SanitizingDocumentTransformer(policy).transform(reader.read()));

// RAG — after retrieval, before generation
var ragAdvisor = RetrievalAugmentationAdvisor.builder()
    .documentRetriever(retriever)
    .documentPostProcessors(new SanitizingDocumentPostProcessor(policy))
    .build();

// Chat — non-RAG paths and final prompt gate
var client = ChatClient.builder(model)
    .defaultAdvisors(DataMinimizationAdvisor.builder(policy).build())
    .build();

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions