Government & Public Sector
Protect citizen and personnel data at the highest security tier when using AI in public-sector workflows, with fail-closed redaction and masked restore for permitted entities
Protect citizen records, case data, and personnel information at the highest security tier when public-sector teams use AI for drafting, triage, and summarization.
The Problem
Public-sector work concentrates sensitive data: citizen identifiers, case files, clearance references, facility codes, and personnel records. The stakes for a leak are high, and the tolerance for sending raw identifiers to a third-party model is low or zero. At the same time, agencies want the same drafting and summarization gains as everyone else.
A permissive policy that tokenizes and restores everything is the wrong default here. The public-sector posture is the opposite: redact the highest-sensitivity identifiers so they cannot appear at all, tokenize the rest with masked restore, and expose no extra metadata to the model.
How OGuardAI Solves It
The shipped government policy is the strictest template. It redacts national IDs, passports, health identifiers, bank and card numbers, dates of birth, IP addresses, and clearance IDs, and it sets on_redact: reject, so a request that contains any of those values fails closed rather than being partially redacted. Everything else is tokenized and restored masked (abstract is the policy default only for a detected type that has no rule), and no gender, formality, language, or role metadata is exposed to the model.
Agency Application (case management, records)
|
v
OGuardAI Runtime (citizen/personnel data exists only here, transiently)
|
+---> Redacted types present? -> request rejected (fail closed)
+---> Otherwise tokenized text (no metadata) ---> LLM Provider
+---> Encrypted session blob -----------------> Your Application
|
v
Restored output (masked for permitted entities)
+---> Names and locations return masked, never as raw valuesDetected Entity Types
These are the entity types the shipped government policy governs.
| Entity Type | Examples | Default Action |
|---|---|---|
person ** | Officer and citizen names | Tokenize, restore masked |
location ** | Field offices, sites | Tokenize, restore masked |
company ** | Organizations, vendors | Tokenize, restore masked |
email | Contact email | Tokenize, restore masked |
phone | Contact numbers | Tokenize, restore masked |
address | Physical addresses | Tokenize, restore masked |
customer_id | Citizen / case identifiers | Tokenize, restore masked |
order | Reference numbers | Tokenize, restore masked |
url | Internal links | Tokenize, restore masked |
facility_code * | Facility and site codes | Tokenize, restore masked |
ssn | National insurance / social security | Redact, request rejected |
passport | Passport numbers | Redact, request rejected |
health_id | Health identifiers | Redact, request rejected |
iban | Bank accounts | Redact, request rejected |
credit_card | Card numbers | Redact, request rejected |
date_of_birth | DOB fields | Redact, request rejected |
ip | IP addresses | Redact, request rejected |
clearance_id * | Clearance references | Redact, request rejected |
Entity types marked with * are custom types defined via
custom_patternsin the policy, not built-in. See the Extending Entities guide for how to add custom types.
Entity types marked with ** are detected by the NER detector sidecar, which requires
detector.modeset tobothoradvanced. The built-in detector alone covers structured PII (email, phone, IBAN, card, identifiers, address, date of birth) but does not detect person, company, or location names. In builtin-only mode names are not tokenized and would reach the model, so pair this policy withdetection.required_forif you need names to fail closed. Treat name protection as a data-minimization control, not an absolute guarantee.
Example Policy
The government policy ships in policies/government/policy.yaml.
name: "government"
version: "1.0.0"
description: "Highest security government policy: redacts nearly all PII, abstract-only restore for permitted entities"
rules:
- entity_type: "ssn"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "passport"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "health_id"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "iban"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "credit_card"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "date_of_birth"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "person"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "email"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "phone"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "address"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "location"
protection_level: 2
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "company"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "customer_id"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "order"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
- entity_type: "ip"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "url"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
# Agency-defined entities (detected by custom_patterns below).
- entity_type: "clearance_id"
protection_level: 1
action: "redact"
conditions: []
- entity_type: "facility_code"
protection_level: 1
action: "tokenize"
restore_mode: "masked"
conditions: []
custom_patterns:
- entity_type: "clearance_id"
pattern: '\bCLR[-:\s]?\d{6,9}\b'
confidence: 0.9
context_words: ["clearance", "classified", "sci"]
- entity_type: "facility_code"
pattern: '\bFAC[-:\s]?[A-Z0-9]{4,8}\b'
confidence: 0.85
context_words: ["facility", "site", "installation"]
defaults:
protection_level: 1
action: "tokenize"
restore_mode: "abstract"
on_redact: "reject"
metadata_policy:
expose_gender: false
expose_formality: false
expose_language: false
expose_role: falseTwo settings define the strict posture. on_redact: reject means a request that contains any redacted type (SSN, passport, health id, IBAN, card, date of birth, IP, clearance id) is rejected outright rather than silently scrubbed, so those values never even enter a session. The default restore_mode: abstract is the fallback for any detected type without a rule; every permitted entity here has a rule that restores it masked, so names, locations, and contact details come back masked, not raw. The metadata_policy exposes nothing, so the model receives tokens with no gender, formality, language, or role hints.
Example API Call
Transform a case note (no redacted types present)
curl -X POST http://localhost:3000/v1/transform \
-H "Content-Type: application/json" \
-H "X-API-Key: your-key-here" \
-d '{
"input": "Case officer Maria Lang, field office Berlin, facility FAC-BX2231. Route correspondence to maria.lang@agency.gov.",
"policy": "government"
}'Response (tokenized)
{
"safe_text": "Case officer {{person:p_001:ad4f97591c16}}, field office {{location:loc_001:f947d7f49c56}}, facility {{custom:facility_code:x_001:46a3a6f26b58}}. Route correspondence to {{email:e_001:1bcaef1a4aff}}.",
"session_id": "01916e6c-9f3a-7000-8000-000000000005",
"session_state": "eyJ2IjoxLCJzaWQiOi...",
"entity_context": [
{ "token": "{{person:p_001:ad4f97591c16}}", "type": "person" },
{ "token": "{{location:loc_001:f947d7f49c56}}", "type": "location" },
{ "token": "{{email:e_001:1bcaef1a4aff}}", "type": "email" }
],
"stats": { "entities_detected": 4, "entities_transformed": 4, "entities_blocked": 0 }
}If the same note also contained an SSN, passport, IBAN, card number, date of birth, IP address, or clearance id, the transform would be rejected (on_redact: reject) with GUARDAI_POLICY_DENIED rather than partially redacted. The entity_context carries no metadata because the policy exposes none.
Data Protection Notes
| Requirement | How OGuardAI Addresses It |
|---|---|
| Least exposure | The highest-sensitivity identifiers are redacted, and on_redact: reject fails the whole request closed rather than transmitting them |
| No side-channel context | metadata_policy exposes no gender, formality, language, or role, so the model receives tokens only |
| Minimal restore | Permitted entities come back masked, not raw; restore_mode: abstract is the policy default only for a detected type without its own rule |
| Audit | Every transform and rehydrate emits structured events with entity types and counts, never raw values |
OGuardAI is one technical control within an agency's broader security and accreditation framework. It enforces fail-closed data minimization for detected entities in the AI pipeline; it does not, by itself, satisfy any specific accreditation or classification regime. Confirm the deployment against your authorizing framework.
Related Resources
- HR & Employee Data: Role-gated restore for personnel data
- Finance & PCI-DSS: Redaction and masked restore for financial PII
- Policy Authoring Guide: Redaction,
on_redact, and abstract restore - Security Guarantees: Trust boundary, fail-closed behavior, and failure modes