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.
| Class | Token |
|---|---|
| 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.
| Value | After a validator rejects |
|---|---|
SANITIZE | Run declared sanitizers in order, then re-validate |
REJECT | Throw GuardrailViolationException (INPUT_VALIDATOR_REJECTED) |
REVIEW | Throw GuardrailViolationException (NEEDS_REVIEW) |
WARN | Log 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:
- Access control
@BeforeActionon plaintextInputGuardrailEnforcer(PII lives here)- Optional security encryption of parameters
- 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.
Related
- Guardrails — three APIs that share the name
- Redaction — output
RedactorSPI - TAN-3016 / TnsAI #168 — implementation
- TAN-5863 — this documentation
- TAN-5857 — approval-token follow-up
Guardrails — three different things
TnsAI uses the word guardrail for three distinct APIs in three modules. They are not interchangeable: different types, different call sites, different imports. Pick by when you need to gate something.
Evaluation
The Evaluation module provides a three-layer system for measuring agent quality: evaluators that score responses, a benchmark engine that runs test datasets, and reporting tools for quality gates, trend analysis, and regression detection.