OGuardAI
Use Cases

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 values

Detected Entity Types

These are the entity types the shipped government policy governs.

Entity TypeExamplesDefault Action
person **Officer and citizen namesTokenize, restore masked
location **Field offices, sitesTokenize, restore masked
company **Organizations, vendorsTokenize, restore masked
emailContact emailTokenize, restore masked
phoneContact numbersTokenize, restore masked
addressPhysical addressesTokenize, restore masked
customer_idCitizen / case identifiersTokenize, restore masked
orderReference numbersTokenize, restore masked
urlInternal linksTokenize, restore masked
facility_code *Facility and site codesTokenize, restore masked
ssnNational insurance / social securityRedact, request rejected
passportPassport numbersRedact, request rejected
health_idHealth identifiersRedact, request rejected
ibanBank accountsRedact, request rejected
credit_cardCard numbersRedact, request rejected
date_of_birthDOB fieldsRedact, request rejected
ipIP addressesRedact, request rejected
clearance_id *Clearance referencesRedact, request rejected

Entity types marked with * are custom types defined via custom_patterns in 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.mode set to both or advanced. 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 with detection.required_for if 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: false

Two 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

RequirementHow OGuardAI Addresses It
Least exposureThe highest-sensitivity identifiers are redacted, and on_redact: reject fails the whole request closed rather than transmitting them
No side-channel contextmetadata_policy exposes no gender, formality, language, or role, so the model receives tokens only
Minimal restorePermitted entities come back masked, not raw; restore_mode: abstract is the policy default only for a detected type without its own rule
AuditEvery 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.