Redact Sensitive Data

After classifying text, use the ClassificationRedactor to mask or block sensitive data based on configurable policies. Redaction replaces detected content with a specified character, while blocking rejects the entire text.

Basic Redaction

from ai_guard import AIGuardClient
from ai_guard.api import AIPlatform, ClassificationRequest, ClassifierDescriptionDefault
from ai_guard.redact import ClassificationRedactor, RedactPolicy, RedactAction, RedactKind

# Initialize and classify
client = AIGuardClient(
    "https://ai-guard.example.com:4443",
    token="your-api-key",
    agent_id="my-agent",
    platform=AIPlatform.AMAZON_BEDROCK,
)

text = "phone 321-507-0525 number"
request = ClassificationRequest(
    context={"actor": "user"},
    classifier_description=ClassifierDescriptionDefault(),
    text=text,
)
response = client.classify(request)

# Define a redaction policy
policy = RedactPolicy(
    actions=[
        RedactAction(kind=RedactKind.REDACT, classifier="US_PHONE_NUMBER"),
    ],
    default=RedactKind.NONE,
    redactor=" ",
)

# Apply redaction
redactor = ClassificationRedactor(policy=policy)
result = redactor.redact(text=text, classification=response)

print(result.text)     # "phone              number"
print(result.actions)  # [RedactAction(kind=REDACT, classifier="US_PHONE_NUMBER")]

Redaction Policy

A RedactPolicy defines how each classifier match should be handled.

Parameters

ParameterTypeRequiredDescription
actionslist[RedactAction]YesList of actions mapped to specific classifiers
defaultRedactKindYesDefault action for classifiers not explicitly listed
redactorstrYesSingle character used to replace each character of redacted text

RedactAction

Each RedactAction maps a classifier to a specific redaction behavior:

RedactAction(kind=RedactKind.REDACT, classifier="US_PHONE_NUMBER")
ParameterTypeDescription
kindRedactKindThe action to take: NONE, REDACT, or BLOCK
classifierstrThe classifier name to apply this action to

Redaction Kinds

KindBehaviorDescription
RedactKind.NONEPass throughText passes through unchanged
RedactKind.REDACTMaskEach character of the matched text is replaced with the redactor character
RedactKind.BLOCKBlock entirelyThe entire text is blocked. Returns an empty string immediately
⚠️

Block Priority

If any match triggers a BLOCK action, the entire text is blocked regardless of other actions. Block always takes priority over redact and pass-through.

Common Policy Patterns

Redact All Detected PII

Set the default to REDACT so all classified matches are masked:

policy = RedactPolicy(
    actions=[],  # No overrides needed
    default=RedactKind.REDACT,
    redactor="*",
)

Block Specific Classifiers, Redact Everything Else

policy = RedactPolicy(
    actions=[
        RedactAction(kind=RedactKind.BLOCK, classifier="US_SSN"),
        RedactAction(kind=RedactKind.BLOCK, classifier="CREDIT_CARD_NUMBER"),
    ],
    default=RedactKind.REDACT,
    redactor="*",
)

Redact Only Specific Classifiers, Pass Through the Rest

policy = RedactPolicy(
    actions=[
        RedactAction(kind=RedactKind.REDACT, classifier="US_PHONE_NUMBER"),
        RedactAction(kind=RedactKind.REDACT, classifier="EMAIL_ADDRESS"),
    ],
    default=RedactKind.NONE,
    redactor="#",
)

Working with Redaction Results

The redact() method returns a result with the modified text and a list of actions that were applied:

result = redactor.redact(text=text, classification=response)

# The redacted text
print(result.text)

# List of actions applied
for action in result.actions:
    print(f"Applied {action.kind} for {action.classifier}")

Detecting Blocked Content

result = redactor.redact(text=text, classification=response)

if result.text == "":
    print("Content was blocked due to sensitive data")
elif result.actions:
    print(f"Content was redacted: {result.text}")
else:
    print(f"Content passed through: {result.text}")

End-to-End Example

A complete example that classifies a user prompt, applies redaction, and handles blocked content:

from ai_guard import AIGuardClient
from ai_guard.api import AIPlatform, ClassificationRequest, ClassifierDescriptionDefault
from ai_guard.redact import ClassificationRedactor, RedactPolicy, RedactAction, RedactKind

client = AIGuardClient(
    "https://ai-guard.example.com:4443",
    token="your-api-key",
    agent_id="my-agent",
    platform=AIPlatform.AMAZON_BEDROCK,
)

# Define policy: block SSNs, redact phone numbers, pass through everything else
policy = RedactPolicy(
    actions=[
        RedactAction(kind=RedactKind.BLOCK, classifier="US_SSN"),
        RedactAction(kind=RedactKind.REDACT, classifier="US_PHONE_NUMBER"),
    ],
    default=RedactKind.NONE,
    redactor="*",
)
redactor = ClassificationRedactor(policy=policy)

# Process user input
user_input = "Call me at 321-507-0525 or email me"

request = ClassificationRequest(
    context={"actor": "user"},
    classifier_description=ClassifierDescriptionDefault(),
    text=user_input,
)
response = client.classify(request)
result = redactor.redact(text=user_input, classification=response)

if result.text == "":
    print("⚠ Content blocked β€” sensitive data detected")
elif result.actions:
    print(f"Redacted: {result.text}")
else:
    print(f"Clean: {result.text}")
# Output: "Redacted: Call me at ************ or email me"

What's Next?