Use cases/Specialized

PII Redaction at the Gateway

Strip phone numbers, government IDs, and emails from inbound messages before they reach the LLM or your audit logs — KVKK / GDPR aligned.

Specializedmedium~30m setup
Plugins
pii-redactor
Channels
telegramwhatsappweb
Uses
pre_gateway_dispatch

When customers send messages, they include things they shouldn't: phone numbers, national IDs, account passwords, full emails. Most of the time, your agent doesn't need that data to answer — and storing raw PII in conversation logs is a compliance problem waiting to happen.

The pii-redactor plugin runs at the gateway boundary: every inbound message gets pattern-matched against a redactable set before any session work, LLM call, or audit log entry happens. By the time the agent sees the message, the PII is already replaced with placeholders.

What it does

  • Inspects every inbound message via pre_gateway_dispatch hook
  • Pattern-matches Turkish mobile (05XX-XXX-XX-XX), TC kimlik (11-digit), email
  • Replaces each match with [REDACTED_PHONE] / [REDACTED_TC] / [REDACTED_EMAIL]
  • Returns RewriteAction so the message is mutated in place — the LLM and audit log never see the raw data
  • Logs redaction events to ~/.flowly/pii-redactor/log.jsonl for compliance review

What you'll need

  • The bundled pii-redactor plugin enabled (or build your own — see below)

Setup

1. Enable the plugin

bash
flowly plugins enable pii-redactor
flowly service restart

Verify:

bash
flowly plugins list
# pii-redactor | enabled | provides_hooks: pre_gateway_dispatch

2. Test redaction

Send to your bot:

"Telefonum 0532 123 45 67, TC kimliğim 12345678901, ulaşırsanız sevinirim."

The agent receives:

"Telefonum [REDACTED_PHONE], TC kimliğim [REDACTED_TC], ulaşırsanız sevinirim."

Check audit log to confirm raw values didn't land:

bash
tail -1 ~/.flowly/pii-redactor/log.jsonl
# {"ts": ..., "session": "telegram:...", "redacted": {"phone": 1, "tc": 1, "email": 0}}

Only the counts are logged — the raw values aren't.

3. Customise patterns (if needed)

For other locales / domains — US SSN, IBAN, credit card, internal employee IDs — add patterns to the plugin's __init__.py:

python
_SSN_RE = re.compile(r"\b\d{3}-\d{2}-\d{4}\b")
_IBAN_RE = re.compile(r"\bTR\d{2}\s?(\d{4}\s?){5}\d{2}\b")
def _redact(text):
text = _PHONE_RE.sub("[REDACTED_PHONE]", text)
text = _SSN_RE.sub("[REDACTED_SSN]", text)
text = _IBAN_RE.sub("[REDACTED_IBAN]", text)
return text

Restart the gateway. New patterns apply to subsequent messages only — old conversations are not retroactively scrubbed.

4. Pair with audit retention

Configure the audit retention policy in ~/.flowly/config.json:

json
{
"audit": {
"enabled": true,
"retention_days": 90,
"max_size_mb": 500
}
}

Older entries auto-rotate. With redaction in place, even retained logs are PII-free.

Tips

  • Test patterns against real messages. A regex that's correct on paper may fail in practice — Turkish phone formats vary (+90 532 …, 0532-…, 5321234567). Run a sample of recent conversations through the redactor in dry-run mode first.
  • Don't redact what you need. If the agent legitimately needs the user's email to send a confirmation, don't redact email. Be specific about what's truly excess data.
  • Layer it. Redaction at the gateway + payload field whitelisting in your tools (don't pass user-provided fields you don't need) + audit log redaction. Three lines of defence.
  • KVKK / GDPR alignment is real. Even without enforcement, you reduce blast radius from a future breach. The cost of building this is one afternoon; the cost of not building it can be your business.
  • Document what's redacted. Customers should know — a one-liner in your terms or onboarding: "Personal data in messages is automatically redacted before processing." This is also a trust-building feature.