Output Controls
Legal Privilege
legal-privilege blocks a model answer that contains a confidentiality marker, such as attorney-client privilege or privileged and confidential, before your application receives it.
It matches literal text. It does not decide whether anything is legally privileged. It runs only with stream: false.
Configuration
Save this as policy-config.yaml:
policy-config.yaml
pack:
name: legal-privilege
version: "1.0.0"
enabled: true
policies:
chain:
- legal-privilege
policy:
legal-privilege:
privilege_markers:
- "attorney-client privilege"
- "privileged and confidential"
- "work product"
- "for legal review only"Verify the result
Apply it to a test agent with the config-first workflow and use controlled provider responses:
| Provider response | Nested result |
|---|---|
For legal review only: draft summary. | Blocked with legal.privilege_detected |
The network production system is ready. | Blocked too, because the text contains work product |
Hello. | Allowed with legal.clean |
Compare the client response with the runtime event. If ordinary text causes matches, use longer and more distinctive markers.
Fields
| Field | Type | Default | Description |
|---|---|---|---|
privilege_markers | string[] | Built-in list | Substrings that block an answer. Case does not matter. Without the field, the four markers of the example above apply. |
action | block | block | The only value. A match always blocks. |
How it works
- The gateway takes the text of the buffered response.
- It lowercases the text and looks for each marker as a substring.
- A match blocks with
legal.privilege_detected. Otherwise, the answer is allowed withlegal.clean. - The details record whether a marker matched and how many markers are active.
Phase and verdicts
| Item | Value |
|---|---|
| Input phase | Not checked |
| Output phase | The buffered response text |
| Verdicts | allow, block |
| Reason code without a match | legal.clean |
| Reason code for a match | legal.privilege_detected |
Examples
Use built-in defaults
policy-config.yaml
pack:
name: legal-defaults
version: "1.0.0"
enabled: true
policies:
chain:
- legal-privilege
policy:
legal-privilege: {}Replace the markers
Your list replaces the defaults, so include any default markers that you still need.
policy-config.yaml
pack:
name: litigation-review
version: "1.0.0"
enabled: true
policies:
chain:
- legal-privilege
policy:
legal-privilege:
privilege_markers:
- "attorney-client privilege"
- "work product"
- "for legal review only"
- "settlement draft"
- "outside counsel only"Limits and failure behavior
- Only answers are checked, never requests.
- A match always blocks. There is no redact or escalate mode.
- Substring matching finds markers inside other words:
work productmatchesnetwork production. - With
stream: true, the control does not run. - A
whencondition does not limit this control. Use routes. - For broader legal-data protection, combine it with
case-privacy,upl-filter, andpii-detector.
Next steps
- UPL Filter: legal-advice patterns in answers.
- Case Privacy: case, incident, and report numbers.