> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# DLP scanner — data classes & strict mode

> What the outbound message DLP scanner detects, how its categories and modes work, what happens when your organization is in strict mode, and how it differs from the transcript PII scrubber.

# DLP scanner — data classes & strict mode

The outbound message scanner runs on every channel (SMS, MMS, WhatsApp,
email, RCS, and IM routes) and flags regulated identifiers in a message body
before it dispatches. This page covers the data classes it detects, why its
false-positive rate is deliberately low, how a finding becomes a send gate,
and how it differs from the transcript scrubber that strips personal data out
of stored agent conversations.

<Note>
  The scanner is a **tenant-owned control**. Its categories and response mode
  are scoped to your organization, and on a send the policy enforcement mode
  you picked (`warn`, `strict`, or `off`) decides what a finding does. HIPAA
  and PCI-DSS define the obligation; this control is one way to enforce part
  of it on the message lane.
</Note>

## What the scanner detects

Four categories ship, each built to avoid false positives:

| Category      | Classes                                                                             | Precision check                                                                                                                                                                       |
| ------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `credit_card` | A full card number / PAN (Visa, Mastercard, Amex, Diners, Discover, JCB, UnionPay). | Luhn mod-10 checksum **and** the card network's prefix + length table. A random grouped number — a phone list, an order id — fails the checksum and is rejected.                      |
| `ssn`         | US Social Security number.                                                          | Requires an explicit dash or space separator, and the area/group/serial parts are validated against the SSA's never-assigned ranges (areas 000, 666, 900–999, group 00, serial 0000). |
| `iban`        | An IBAN or bank account in any of the \~90 supported countries.                     | ISO 7064 mod-97 checksum **and** the per-country registry length. Space-grouped IBANs printed in 4s are handled.                                                                      |
| `passport`    | A passport number. Opt-in, not scanned unless your organization asks.               | A bare 6–9 character token is too ambiguous to block by itself, so detection only fires when the token directly follows a `passport` context word and carries at least one digit.     |

The default set is `credit_card`, `ssn`, and `iban` — the payment and
identity data most likely to put a message outside PCI, HIPAA, or GDPR
policy. `passport` is added on request. You keep the default unless you opt
into `passport` or narrow the set for a conversation you have already vetted.

## Why checksum validation matters for a strict-mode organization

`strict` mode turns every scanner `block` verdict into a refused send. A
loose detector would take legitimate messages down with it. Every category
above validates a candidate twice — shape, then checksum or the registry
ranges — before it counts, so grouped digits, order ids, and tracking codes
don't trip the gate. The one class that shape alone can't pin (a bare
alphanumeric token) is kept out of the default set entirely rather than
risked on vague matching.

This is why `strict` is safe to leave on for the whole workspace: the scanner
refuses actual card/identity data, not numerals or account-shaped strings.

## How a finding becomes the verdict

The DLP rule rolls its hits up through the
[policy scanner](/compliance/policy-scanner), the pre-send gate that also
checks TCPA quiet hours, SHAFT content, spam keywords, opt-out phrasing, and
country sender rules. All channels run it, because a card number is sensitive
on SMS, WhatsApp, email, and RCS alike.

The scanner emits a `dlp` violation on a hit, and in its default `block` mode
the violation raises the verdict to `block`. What happens next depends on two
settings:

* **Your organization's policy enforcement mode** (the `warn` / `strict` /
  `off` switch covered in [the policy scanner page](/compliance/policy-scanner)):
  in `warn` (default) the send proceeds and the finding is recorded; in
  `strict` it is refused with `POLICY_VIOLATION`.
* **The DLP category mode** (`block` / `redact` / `warn` / `off`): `block`
  (default) raises the `block` verdict; `warn` flags without raising the
  verdict; `redact` strips the sensitive value before dispatch as a flagged
  send; `off` turns the DLP check out for your organization.

The DLP scanner ships as the `dlp-scanner` module in the
`@devotel/compliance` package; the send-path verdict comes from the sibling
policy scanner that folds every rule into one outcome.

## Privacy posture

A finding tells you where and what, not the matched value. Each hit carries a
character span (start and end offsets) and a category label only — the
scanner never returns the offending text. The same is true when you run
`redact`: matched spans are substituted with typed sentinel tokens
(`[REDACTED_CARD]`, `[REDACTED_SSN]`, `[REDACTED_IBAN]`,
`[REDACTED_PASSPORT]`). The detector therefore can't leak a card or identity
number into logs, response headers, or the audit trail, and it stays safe to
run on every send and on every keystroke of the compose-time linter.

## Putting it to work

**Enable a category.** By default the floor is `credit_card`, `ssn`, `iban`.
A HIPAA tenant that collects identity documents can opt into `passport`;
a PCI tenant who has already vetted a lane can reduce the categories to
exactly the cards and accounts its policies allow. The scanner accepts only
the four shipped categories.

**Compose a clean message.** A marketing body must not carry a PAN. When a
customer's payment or identity data is pasted in, the pre-send
`POST /api/v1/messages/lint` call flags it as `block` before anything dispatches, so the author rewrites the body. In `strict` mode the same
refusal comes back on the send call itself, so the message never got sent.

**Live linting and agent drafts.** The agent or dashboard compose UI calls
`/messages/lint` debounced as text is typed, and gets the same verdict and
violations back without sending anything. An AI agent draft goes through the
same call, so a generated card or identity number is caught before it ever
reaches a customer.

## DLP vs. the transcript scrubber

The DLP scanner is a **send gate**: it refuses or flags regulated data at
send time. The transcript scrubber (`@devotel/shared/utils/pii`, the
`redactPii` family) is a **storage gate**: it strips personal data from agent
conversation transcripts as they are inserted so the stored record never
holds the original text.

The tradeoffs differ with the job:

* The transcript scrubber is destructive — the original text is gone from
  the stored row — so it tolerates some false positives rather than hold up a
  conversation write.
* The DLP send gate must stay precise and auditable, so it validates twice
  and keeps the scan synchronous and offset-only; an AI agent or customer
  gets a `block`/`warn` verdict it can act on, not a silent rewrite.

Use both: the transcript scrubber keeps stored agent conversations clean, and
the DLP rule stops regulated data from leaving in the first place. The two
scopes meet only inside the scanner's send-path verdict.

## Related pages

* [Pre-send policy scanner](/compliance/policy-scanner) — verdicts,
  enforcement mode, and the other rules a send passes through
* [Send gates](/compliance/send-gates) — the gates that run alongside the scanner
* [HIPAA compliance](/compliance/hipaa) — the controls your healthcare posture runs under
* [PCI-DSS](/compliance/pci-dss) — payment data posture and scope
