Skip to main content

Input Controls

Case Privacy

case-privacy replaces case, incident, and report numbers, such as Case No. ABC-1234, before the model sees them, and removes them from responses too. It matches one built-in pattern. It does not remove party or court names.

The redaction uses the shared redactor, which also replaces personal identifiers and card numbers in the same text. Test with synthetic identifiers first.

Configuration​

policy-config.yaml
pack:
  name: case-privacy-example
  version: 1.0.0
  enabled: true
policies:
  chain:
    - case-privacy
policy:
  case-privacy:
    action: redact

Identify matches​

InputMatches
Case No. ABC-1234Yes
incident # XYZ-9001Yes
report number 2024-CV-00123Yes
Case ABC-1234No. The number marker is missing.
Case No. ABNo. The identifier is too short.

To test these offline, add a case for each input. A match gives the case result redact with redact.applied, and a nested case_privacy.detected. A non-match gives allow with ok:

Add to policy-config.yaml
testing:
  suites:
    - name: case-privacy
      cases:
        - name: case-number
          input: {messages: [{role: user, content: "Case No. ABC-1234"}]}
          expected: {verdict: redact, reason_code: redact.applied}
        - name: no-number-marker
          input: {messages: [{role: user, content: "Case ABC-1234"}]}
          expected: {verdict: allow, reason_code: ok}

Then apply the file with the config-first workflow and check the replacement details to see the text that the provider receives.

Fields​

FieldTypeDefaultDescription
actionstringredactOnly redact is accepted.
detect_patternslist of stringscase_numberAccepted by lint, but ignored. The built-in pattern always applies.

How it works​

  1. The gateway joins the text of all request messages.
  2. The control matches its pattern, ignoring case: case, incident, or report, then no, no., number, or #, then an identifier of at least four letters, digits, or hyphens.
  3. A match returns redact with case_privacy.detected. Otherwise, allow with case_privacy.clean.
  4. On redact, the shared redactor replaces each identifier in the request with [REDACTED:ID] before dispatch.
  5. On every response, the shared redactor runs with the case-number pattern added. If it changes the response, the gateway records an output result with policy type case-privacy, verdict redact, and case_privacy.detected. This applies to streamed and buffered Chat Completions, Responses, and Messages responses.

Phase and verdicts​

ItemValue
Phaseinput, plus output redaction on each response
Request familiesChat Completions, Completions, Responses, Messages
Verdictsallow, redact
Reason codescase_privacy.detected (input and output), case_privacy.clean

When output redaction changes the response and no earlier control blocked or escalated, the decision is redact with redact.applied.

The output result names case-privacy only when the chain has no other redacting privacy policy. With pii-detector, hipaa-phi-detector, dlp-filter, or student-privacy in the chain, the result names that policy and uses its reason code. See Output redaction reason codes.

Limits and failure behavior​

  • The shared redactor also removes email addresses, phone numbers, card numbers, and other built-in PII. Add pii-detector to the chain to choose the marker format and detector modes.
  • Party, docket, and court names are not detected.
  • An identifier shorter than four characters does not match.
  • With stream: true, the gateway buffers and redacts the whole response before it sends it. With gateway 0.1.26 or later, the decision event records the same output result as for a buffered response, with "streaming": true in the details. The stream headers show the admission decision. See Redaction results in a stream.
  • Redaction hides text. It does not control access to case data or create legal confidentiality.

Next steps​