Skip to content
tnsaijava agent framework

PII input guardrails

TnsAI 0.14.0 (@since 0.14.0). TnsAI PR #168 (81b2fb95, TAN-3016) adds executable @InputGuardrail validators and sanitizers, including built-in PII detection. This ships in Maven Central 0.14.1.

This page is action input. It is not com.tnsai.quality.tracing.guardrail.PiiGuardrail (traced content scoring — Guardrails) and not the output Redaction SPI. Approval-token lifecycle is TAN-5857.

Annotation-first setup

import com.tnsai.annotations.InputGuardrail;
import com.tnsai.guardrails.pii.PiiInputSanitizer;
import com.tnsai.guardrails.pii.PiiInputValidator;

@InputGuardrail(
        validators = PiiInputValidator.class,
        sanitizers = PiiInputSanitizer.class,
        onFailure = InputGuardrail.FailureAction.SANITIZE)
public String handleContact(String message) {
    return message;
}

Both types need a public no-arg constructor. Applications may supply their own InputValidator / InputSanitizer implementations.

There is no FailureAction.REDACT. Redaction is SANITIZE plus PiiInputSanitizer.

Heuristic classes

Detection is high-precision and not a legal or jurisdiction-complete classifier. Raw matches stay in the current call and are not written into diagnostics.

ClassToken
Practical email shape[REDACTED_EMAIL]
International prefix or 10-digit local phone[REDACTED_PHONE]
IBAN country/check-digit shape (compact length 15–34)[REDACTED_IBAN]
Luhn-valid 13–19 digit payment-card shape[REDACTED_PAYMENT_CARD]
US SSN shape[REDACTED_NATIONAL_ID]
Checksum-valid 11-digit Turkish identity[REDACTED_NATIONAL_ID]

PiiInputValidator rejects when any class matches. It also inspects parameter names.

onFailure dispositions

Default is REJECT.

ValueAfter a validator rejects
SANITIZERun declared sanitizers in order, then re-validate
REJECTThrow GuardrailViolationException (INPUT_VALIDATOR_REJECTED)
REVIEWThrow GuardrailViolationException (NEEDS_REVIEW)
WARNLog and continue without rewriting

Containers, nested objects, custom-rendering enums, and custom number types fail closed — a type-preserving rewrite is not guaranteed. Flatten those payloads first. Runtime String values declared as Object are inspected. Booleans, default-rendering enums, and exact immutable JDK numbers use stable textual forms.

Production order

ActionExecutor on PR #168:

  1. Access control
  2. @BeforeAction on plaintext
  3. InputGuardrailEnforcer (PII lives here)
  4. Optional security encryption of parameters
  5. Action / LLM / tool / MCP body

Encryption after the guardrail is required. Ciphertext would hide PII from validators or fail a second pass.

The same enforcer covers Role actions, generic Object/SCOP dispatch, static @Tool methods, and MCP-exposed tools.

Bounded regex subset

The 1,024-character caps apply to blockPatterns / allowPatterns and the inspected input, not to the built-in PII Patterns.

Before matching, the enforcer rejects backreferences, nested quantifiers, comments mode (x), multi-token escapes, more than one non-fixed non-possessive backtracking quantifier, and more than one alternation group. Fixed repetitions and possessive quantifiers may repeat. One non-capturing alternation group, lookarounds, other inline flags, and lazy/possessive modifiers remain allowed.

  • Guardrails — three APIs that share the name
  • Redaction — output Redactor SPI
  • TAN-3016 / TnsAI #168 — implementation
  • TAN-5863 — this documentation
  • TAN-5857 — approval-token follow-up