Strata PlatformDocs

Data-loss-prevention policy hook

An inline gate your organization can place in front of every chat turn. Strata sends the prompt (and, on the response side, the answer) to a policy engine you control, then obeys the verdict — allow, deny, hold, or redact — before a member ever sees a result.

Strata supplies the interception, transport, signing, enforcement, timeouts, shadow mode, staged rollout, and a circuit breaker. Your organization supplies the policy. An organization that never configures a hook is completely unaffected — this control does not exist until an admin turns it on.

Where it runs

The hook sits in front of every chat surface that can invoke a model: chat, scheduled agents, the Teams bot, the in-app support assistant, and the programmatic /v1 API. Voice mode is the one surface it cannot sit in front of (spoken audio reaches the model before any transcript exists, and the model speaks its answer as it writes it), so voice is switched off for members whose messages or answers are checked and enforced; shadow mode, a rollout that leaves a member out, and detectors that only record keep it on. Some model calls Strata makes for its own work are outside the check: see What it does not cover.

It is configured under Organization → Data and privacy → Advanced data protection, a collapsed card whose header shows the current status (for example Not configured, Shadow mode, Enforcing, or Circuit breaker tripped). It is gated by the canManageCompliance permission (an Owner-reserved class, the same as audit configuration) — turning it on can stop every member from chatting, and turning it off removes a control a compliance owner put there — so an admin who can see the organization's settings but lacks that permission sees Advanced data protection needs the "Manage compliance" permission. Ask an owner to grant it. in place of the card.

The hook's settings and Strata's own local detectors share one Save data protection button, which stays at the bottom of the window while a change is unsaved. The detectors are saved first; if the rest is then refused, the card says Content detection saved. Endpoint, answer and pilot settings couldn't save: … and marks the field the refusal is about. A save that changes nothing writes nothing. A saved change reaches every Strata server within the interval the confirmation states (Saved · reaches every server within 30 seconds by default).

The card is in the language chosen in Settings, its confirmations and each detector's own description and Will get wrong note included (a note keeps the cue words, code and sample values it quotes as the detector reads them), apart from a message from Strata's servers, such as why a save or a rule was refused or the marker that stands in for a masked value in Try it on some text. The code samples under For your developers stay exactly as your endpoint receives them, and a tripped circuit breaker quotes the endpoint's own error as the server recorded it.

Key

Zero configuration means zero change. With no hook registered, chat turns are byte-for-byte identical to a deployment that has never had this feature.

Two events

EventWhenVerdict
policy.promptBefore inference, on every turnAllow or deny. A denial stops the turn before any model is called.
policy.responseAfter inference, before the member sees the answerGoverns the response postures below.

The request body is signed with an HMAC shared secret so your endpoint can verify it came from Strata. The secret is write-only: no route ever returns it. An admin who loses it generates a new one, the same contract the API-key and SCIM surfaces use.

What is sent — and what is not

Each policy.prompt payload carries the member's prompt text, the text Strata has already extracted from any attachments, and an inventory of the images present in the turn (count, MIME type, byte size).

Raw file and image bytes are never sent. This is a deliberate, disclosed limitation: a screenshot of a spreadsheet is text to a human but pixels on the wire, so it is a bypass. The image inventory is the mitigation available without shipping pixels — a policy can refuse any turn that carries an image at all.

Warning

Because the prompt event carries text and an image inventory rather than raw bytes, a policy that must inspect file or image content cannot do so through the hook. Pair it with the org-level attachment and extension controls if that matters to you.

What it does not cover

  • What Strata reads during a turn. A file, an email, a web page, a query result or a Knowledge Base passage that a tool fetches goes to the model as part of its work. Only the member's message and the text of its attachments are checked on the way in, and, with a response posture on, the answer on the way out.
  • Some model calls Strata makes for its own work. Strata embeds a member's message to suggest a stored procedure, unless a check here can refuse that message; a vision model reviews generated PDF, Word, Excel and PowerPoint files for layout faults; a vision model reads the text in an image when Strata opens an Outlook attachment or a OneDrive or SharePoint image; and the Knowledge Base embeds the files it indexes and the searches made against it.
  • The support assistant's model. The in-app support widget goes through the check (surface support), and the assistant itself runs on a model Kronisys hosts, not in your own Azure AI Foundry.
  • Voice mode, which is switched off instead (see Where it runs).
  • The AI provider's own content filter. Separate from this hook, Azure AI Foundry filters requests to GPT and Grok deployments for categories such as hate, violence and prompt attacks. It does not filter Claude deployments; Claude declines some requests itself, and with the switch below on those are recorded too. With Alerts for blocked requests on (Organization → Data and privacy), the provider's blocks, Claude's own refusals and the matches of your custom rules are recorded in the audit log under Content safety, and the entry for a rule match that let the request through carries the same policy_event_id as this hook's own record.

Transport and wire format

Two independent choices:

  • Transport (Source, under Who answers) — either a customer-run HTTPS endpoint (Your own endpoint, a webhook you host) or a managed connection to a supported DLP vendor (A data-security vendor: Strata handles the vendor's transport; you supply the credential and region). The live vendor list and its per-vendor fields are shown in the admin panel.
  • Wire format (Contract) — either Strata's own contract (Strata, the default, and the one you pin api_version against) or an Anthropic inference-hooks-compatible frame (Compatible endpoint), so an endpoint already built for Anthropic's published contract works here unchanged. The current contract version is 2026-08-16.

The two are separate: wire format says which contract an endpoint speaks; transport says whether there is a customer-run endpoint at all. Enforcement — shadow mode, rollout, the breaker, fail-open/closed, the audit rows — is identical on both wires. The vendor transport needs no shared secret: the vendor's API key is its credential. Neither the Anthropic wire nor a data-security vendor has a response-side event (Prisma AIRS is asked about the member's message only), so on either the response postures are carried out by Strata's local detectors: with their answer rule set to act on the posture, or, for Mask, with their shipped default set while they are switched off. Switching onto either with a posture nothing would carry out is refused, with the reason. A webhook address on a vendor's own scan host is refused too.

Alert

The endpoint must be public HTTPS. Strata is a SaaS and cannot dial into a private network. Every outbound call is SSRF-guarded — the host is re-resolved and re-checked on every redirect hop, and private ranges and the cloud metadata endpoint are refused — the same guard that protects every other Strata webhook.

Prompt verdicts

The policy.prompt grammar is allow or deny. A hook cannot rewrite a prompt — rewriting the question a member typed and answering the rewritten one is not a control. On a deny, the reason your endpoint returns is shown to the member verbatim (control characters stripped, 300 characters maximum), so write it for them.

Response postures

Set one posture for the policy.response side:

PostureBehaviorMember exposure
OffNo response-side gate.—
HoldThe answer is buffered until a verdict returns; a blocked answer is never streamed.Never displayed.
RetractThe answer streams, then is retracted after the fact if the verdict is deny.May have already been seen.
MaskStrata's local detectors redact matched values in place with a fixed-width placeholder; an answer that cannot be rewritten safely escalates to a deny.Never displayed.

The cost of the response side is real: Strata streams over SSE, so the gate either holds the turn (higher latency, nothing leaks) or retracts after streaming (lower latency, the member may have glimpsed the text). You choose which trade to make.

Rollout, fail mode, and the circuit breaker

  • Shadow mode — evaluate and record, but enforce nothing, including when your endpoint errors. Denials are written to the audit log as policy_hook_denied with enforced: false, so you can read exactly what would have been blocked. Shadow mode overrides every other setting; leave it on until the list looks right.
  • Staged rollout — a percentage of members. Bucketing is deterministic per member, so a member is consistently in or out of the rollout rather than flipping turn to turn.
  • Fail mode — fail-closed is the default: if your endpoint or vendor errors or times out, the turn is refused. The same setting decides what happens when Strata's own detectors cannot run, so it is shown to every organization, with or without an endpoint. Fail-open trades enforcement for availability, and every endpoint or vendor failure is still recorded as policy_hook_error so a silent gap is still a visible one. Turning on fail-closed enforcement asks you to confirm first, and so does a save that changes who answers (the source, the endpoint URL, the vendor or its region) while fail-closed enforcement is on, naming the new endpoint or vendor.
  • Circuit breaker — after 5 consecutive transport failures, Strata stops calling your endpoint or vendor and writes a policy_hook_error event, and everyone whose role holds Manage compliance gets one inbox notice for the trip. The tripped state is persisted and never recovers on its own: it clears when a person presses Reset breaker, or saves a changed endpoint, vendor or key. A save that changes neither leaves it tripped. Local content detectors keep running while the breaker is open, because they are local and cannot fail in a transport sense.
  • Timeout — the per-call budget, 200 to 10,000 ms. It is added to the start of every checked turn, so keep it tight. A vendor left on the default waits its own budget (4,000 ms for Prisma AIRS), and the field shows that; a number you type is used as typed, 2,000 included.

What is written to the audit log

Every decision lands on the tamper-evident audit log. None of these rows store the prompt, the answer, or any matched value:

EventMeaning
policy_hook_deniedA prompt was refused (or, in shadow mode, would have been — enforced: false).
policy_hook_errorA transport failure, timeout, or breaker trip.
policy_hook_response_deniedAn answer was refused. Carries the posture, the answer's length, the file inventory, and a disclosure field (user_may_have_seen_it under Retract, never_displayed under Hold and Mask, delivered_shadow_mode in shadow mode).
policy_hook_response_maskedAn answer was masked and released. Carries the detector, the match count, and the character offsets in the original answer — never the values.

Each row carries an event_id so you can correlate a Strata decision with your own endpoint's logs.

Changes to the configuration are recorded too, before and after: policy_hook.updated (including who answers, the vendor, its region and security profile, and whether a per-member identifier is sent to it; a new secret or vendor key is recorded as rotated, never its value; a breaker the change cleared is noted), policy_hook.removed (what was removed and what was kept), policy_detectors.updated (which detectors and which of your rules, by id, never a pattern or keyword) and policy_hook.breaker_reset. A save that changes nothing writes no row. The card sums up the last 7 days of these rows in one line, with a link to the audit log's Data policy filter for admins who can read the log.

Local detectors

Independently of a customer endpoint, Strata ships local content detectors (Content detection, first in the card) you can enable on the prompt side (On a member's message: Off, Record only or Block the message) and the response side (On the model's answer: Off, Record only or Act on the answer posture). These drive the Mask posture (with the detectors switched off, Mask uses their shipped default set, not your list, rules or confidence floor), and they let an organization run a response-side gate on the Anthropic wire or a data-security vendor, neither of which has a response event, or with no endpoint configured at all. An organization with no endpoint saves its shadow mode, rollout, answer posture and failure setting with the same Save data protection. A detector's refusal tells the member which kind of value was found, never the value.

Troubleshooting

  • Every chat turn is failing after you enabled the hook. You are fail-closed and your endpoint is erroring or timing out. Check the policy_hook_error rows for the cause, or switch to shadow mode while you fix it.
  • The card's status reads Endpoint secret unreadable. The stored shared secret can't be decrypted on this server (a pruned key version), so every request fails. Enter a new secret under Who answers and save. Vendor key unreadable is the same failure for a vendor's API key.
  • A breaker has tripped. Strata stopped calling the endpoint or vendor after 5 consecutive failures, and everyone with Manage compliance got an inbox notice. Fix the endpoint, then use Reset breaker, or save the corrected endpoint, vendor or key. It will not recover on its own.
  • You want to see what a policy would block without blocking anything. Turn on shadow mode and read the policy_hook_denied rows with enforced: false.

Related