OGuardAI
Security

Security Whitepaper

OGuardAI security architecture, trust boundaries, encryption model, and operational security properties

Version: 1.0 | Date: 2026-04-15


Executive Summary

OGuardAI is a semantic data protection runtime that sits between enterprise applications and AI providers. It replaces sensitive data with semantic tokens before data reaches any AI model, and deterministically restores values afterward. This document describes OGuardAI's security architecture, trust boundaries, encryption model, and operational security properties for enterprise auditors, security teams, and compliance officers.

Unlike conventional data masking tools that strip data and degrade AI utility, OGuardAI preserves semantic context through typed tokens ({{type:id}}). The AI model receives enough information to produce grammatically correct, contextually appropriate output without ever seeing raw sensitive data. After the model responds, OGuardAI deterministically restores the original values using an encrypted session mapping.

This whitepaper covers: the trust boundary model, encryption and session security, authentication and authorization, multi-tenant isolation, prompt security, the detection model, operational security, deployment security, and supply chain properties.


1. Trust Boundary Model

Architecture

OGuardAI defines two strict zones with a cryptographic boundary between them:

  • Trusted Zone (OGuardAI Runtime): Contains raw PII, token-to-value mappings, encryption keys, and session state. This zone is the server process itself -- a single Rust binary running in the customer's infrastructure.
  • Untrusted Zone (Everything Else): LLMs, external tools, logs, vector stores, SDKs, proxy targets, monitoring systems, and all network-facing interfaces. These zones ONLY ever receive tokenized text and encrypted session blobs.
+--------------------------------------------------------------+
|                      TRUSTED ZONE                            |
|                   (OGuardAI Runtime Process)                   |
|                                                              |
|   Raw PII --> Detect --> Tokenize --> Transform               |
|                                          |                   |
|   Token Map <--- Seal (AES-256-GCM) ----+                   |
|                                                              |
|   Unseal --> Repair --> Rehydrate --> Output Guard            |
|                                                              |
|   [Encryption Keys] [Session State] [Token Mappings]         |
+--------------------------+-----------------------------------+
                           |  Only tokenized text + encrypted
                           |  blobs cross this boundary
                           v
+--------------------------------------------------------------+
|                     UNTRUSTED ZONE                            |
|                                                              |
|   LLMs  |  Vector Stores  |  External Tools  |  Logs        |
|   SDKs  |  Proxy Targets  |  Agent Memory    |  SIEM        |
|                                                              |
|   [Sees ONLY: `{{email:e_001}}`, `{{person:p_001}}`, ...]       |
|   [Sees ONLY: encrypted session blobs]                       |
+--------------------------------------------------------------+

Data Flow Guarantee

The following invariants hold for every request processed by OGuardAI:

  1. User input enters the Trusted Zone via HTTP API (TLS-terminated at the load balancer or directly).
  2. Input is authenticated, rate-limited, and scanned for prompt injection attacks.
  3. PII is detected by builtin regex patterns and/or the optional Python NER sidecar.
  4. Detected entities are classified by type and replaced with semantic tokens ({{type:id}}).
  5. Policy is evaluated: entities may be tokenized (Level 2), hard-masked (Level 1), or blocked.
  6. Only tokenized text and safe metadata leave the Trusted Zone toward the LLM.
  7. The LLM response enters the Trusted Zone.
  8. Tokens in the response are repaired (3-stage: strict parse, format repair, fuzzy resolution).
  9. Tokens are rehydrated to original values using the session mapping.
  10. Output guard optionally re-scans for newly generated PII (LLM hallucinations).
  11. Final output leaves the Trusted Zone.

Raw PII NEVER crosses the trust boundary in any direction.

Side-Channel Protection

OGuardAI takes explicit measures to prevent PII leakage through side channels:

  • Logging: All tracing calls are verified to contain zero raw PII. Logs record only entity types, counts, policy names, timing metrics, and token IDs. The raw value is never present.
  • Error messages: All error types implement Display with messages that contain diagnostic context (error codes, entity types, counts) but never raw entity values.
  • Debug output: Token, TokenMap, and EntitySpan types implement custom Debug that redacts original_value fields. Even a developer debugging with {:?} formatting will not see raw PII.
  • Temp files: OCR temporary files use random file names and are cleaned up on drop via RAII pattern. No raw content persists on disk after processing.
  • HTTP error responses: 4xx and 5xx responses contain error descriptions and error codes. Request content is never echoed back in error responses.
  • Metrics: Exported metrics include request counts, latency histograms, and entity type counters. No PII values appear in metric labels or values.

2. Encryption & Session Model

Sealed Sessions (Default Backend)

The sealed session backend is OGuardAI's default and recommended mode for stateless horizontal scaling. It operates as follows:

  • Algorithm: AES-256-GCM (authenticated encryption with associated data), per NIST SP 800-38D.
  • Key: 32-byte key derived from a configurable secret. The secret is set via session.secret in oguardai.yaml or the GUARDAI_SESSION_SECRET environment variable.
  • Nonce: 12-byte random nonce generated per seal operation. Each seal uses a fresh nonce, ensuring that identical payloads produce different ciphertext.
  • Authentication: 16-byte GCM authentication tag. The tag provides both confidentiality and integrity verification. If the tag verification fails during unseal, the entire blob is rejected (fail-closed).
  • Payload: JSON-serialized token map containing: token ID to original value mapping, entity metadata (type, gender, formality, language, role), and session metadata.

Sealed Envelope Structure

{
  "v": 1,
  "kid": 0,
  "sid": "uuid-v4",
  "tid": "acme-corp",
  "pid": "gdpr-strict",
  "ctr": 1,
  "exp": 1713142800,
  "lang": "de",
  "nonce": "<base64-12-bytes>",
  "ct": "<base64-encrypted-payload>",
  "tag": "<base64-16-bytes>"
}

The entire envelope is base64-encoded and returned to the client as an opaque string in the session_state field.

Key Management

  • Key rotation: Supported via a KeyRing with versioned key IDs. The kid (key ID) field in the sealed envelope identifies which key was used to encrypt the session. Multiple keys can be active simultaneously.
  • Per-tenant keys: Configurable in oguardai.yaml under tenants.{id}.session_secret. Each tenant can have its own encryption key, providing cryptographic isolation between tenants.
  • Backward compatibility: Sealed envelopes without a kid field default to key ID 0, ensuring older sessions remain decryptable after key rotation.
  • Fail-closed behavior: Wrong key, tampered data, expired session, or cross-tenant blob produces a session_expired error. The system never returns garbage data, partial decryption, or guessed values.

Session Lifecycle

  1. Created during transform: contains all detected entities and their original values.
  2. Carried by the client as an opaque encrypted blob (sealed backend) or referenced by session ID (redis/memory backend).
  3. Unsealed during rehydrate: tenant ID and expiry are validated before decryption proceeds.
  4. TTL enforced: Configurable (default 3600 seconds). Expired sessions are rejected with a clear error.
  5. Request counter: Included in the envelope for replay detection. Each rehydrate increments the counter.
  6. No server-side state (sealed backend): The client is the sole custodian of the session blob. The server retains nothing between requests.

Alternative Session Backends

BackendDescriptionUse Case
Sealed (default)AES-256-GCM encrypted blob, client-carriedStateless deployments, horizontal scaling
MemoryIn-process hash mapDevelopment and testing only
RedisExternal Redis store with TTL-based expiryMulti-instance deployments with shared state

3. Authentication & Authorization

Auth Providers

OGuardAI supports three authentication modes, configured via auth.mode in oguardai.yaml:

ProviderUse CaseConfiguration
DevDevelopment and testingAll scopes granted, no validation. Startup warning emitted.
API KeyService-to-service authenticationStatic keys configured in oguardai.yaml or environment variables. Keys compared using constant-time comparison (subtle::ConstantTimeEq) to prevent timing attacks.
JWTToken-based authenticationHS256 (HMAC) signatures, configurable issuer. Tokens validated on every request.

Scope Model

Authorization is scope-based. Each authenticated principal has one or more scopes that determine which endpoints they can access:

ScopeEndpoints
Transform/v1/transform, /v1/transform/stream, /v1/transform/file, /v1/transform/image
Rehydrate/v1/rehydrate, /v1/rehydrate/stream, /v1/rehydrate/file
Detect/v1/detect
Policy/v1/evaluate-policy
AdminAll endpoints including /v1/diagnostics

The Admin scope implicitly grants all other scopes. This enables a least-privilege model where services that only need to transform data do not receive rehydrate permissions.

Security Properties

  • All API endpoints require authentication unless explicitly configured otherwise.
  • Authorization checks occur at both the handler layer (middleware) and the service layer (defense in depth).
  • API keys are never logged, even partially. Only the key name or a hash appears in audit events.
  • Constant-time comparison is used for all secret comparisons (API keys, JWT signatures) to prevent timing side-channel attacks.

4. Multi-Tenant Isolation

OGuardAI provides multi-tenant isolation at multiple layers:

Session Isolation

  • Tenant ID is cryptographically bound to the sealed session blob (included in the authenticated encryption envelope).
  • Attempting to rehydrate a session blob from tenant A using tenant B's context produces a PolicyDenied error. Cross-tenant blob reuse is prevented by the cryptographic binding.
  • Per-tenant encryption keys (optional) provide cryptographic separation: even if a blob were intercepted, it cannot be decrypted without the tenant's specific key.

Policy Isolation

  • Each tenant can have a different default policy, configured under tenants.{id}.default_policy in oguardai.yaml.
  • Policy evaluation is scoped to the tenant's policy. Tenant A's policy rules never affect tenant B's requests.

Rate Limit Isolation

  • Per-tenant rate limits are independently configured (tenants.{id}.rate_limit.requests_per_second, tenants.{id}.rate_limit.burst_size).
  • One tenant's traffic spike does not affect another tenant's rate limit budget.

Audit Isolation

  • All audit events are tagged with the tenant ID.
  • Log entries include tenant context for SIEM filtering and compliance reporting.

5. Prompt Security

OGuardAI includes a dedicated prompt security layer (guardai-prompt-security crate) that defends against prompt injection and data extraction attacks:

Input Scanning

Six regex patterns detect common attack vectors:

  1. Extraction attempts: Patterns that try to make the LLM reveal token mappings or system instructions.
  2. Instruction overrides: Attempts to inject "ignore previous instructions" or similar phrases.
  3. Indirect extraction: Attempts to discover what is behind, underneath, or hidden in a token or placeholder.
  4. Output manipulation: Attempts to make the LLM output, print, or return raw/original/unmasked data.
  5. Role-play injection: Attempts to make the LLM adopt a role that bypasses safety measures.
  6. System prompt extraction: Attempts to exfiltrate the system prompt or preamble.

Configurable Actions

When a prompt security pattern matches, the following actions are available:

ActionBehavior
warnLog the detection but permit the request (monitoring mode)
stripRemove the malicious sentences from the input; remainder is processed
blockReject the entire input with a PolicyDenied error

System Preamble

OGuardAI injects a system preamble into every LLM-facing prompt. This preamble instructs the model to:

  • Treat {{type:id}} tokens as opaque placeholders.
  • Never attempt to guess, decode, or reveal the values behind tokens.
  • Preserve tokens exactly as-is in the model's output.
  • Never generate new PII that was not present in the input.

Output Guard (Second-Pass Protection)

After the LLM responds, the output guard optionally performs a second detection pass on the LLM's output to catch:

  • Hallucinated PII: The LLM may generate realistic-looking but fabricated personal data (names, emails, phone numbers) that was not in the original input.
  • Token leakage: The LLM may partially reveal or reconstruct information from token metadata.

Per-entity-type actions are configurable:

ActionBehavior
AllowAllow the entity through unchanged
WarnLog a warning but pass the entity through unchanged
MaskReplace the hallucinated PII with a type label like [EMAIL]
BlockReject the entire output if hallucinated PII is detected

6. Detection Model

Builtin Detectors (Rust Regex)

The builtin detection engine provides 30+ pre-compiled regex patterns covering:

CategoryEntity Types
ContactEmail, phone (international formats), URL
FinancialIBAN (34 countries with checksum validation), credit card (Luhn algorithm validation), SSN
IdentityPassport numbers, health IDs, German tax ID (Steuerliche Identifikationsnummer), German social security number
PersonalDate of birth, physical address patterns
BusinessCustomer ID, order number
NetworkIPv4, IPv6 addresses

All patterns are pre-compiled at initialization using OnceCell / lazy_static. No regex compilation occurs on the request path.

Advanced Detectors (Python NER Sidecar)

The optional Python detector service provides NER-based detection for entities that regex cannot reliably capture:

  • GLiNER (zero-shot): Detects person names, company names, and locations without language-specific training data. Supports 30+ languages.
  • spaCy models: Language-specific NER models for higher accuracy on supported languages.

The Python sidecar communicates with the Rust runtime via HTTP (internal network only). It is deployed as a separate container.

Graceful Degradation

If the Python NER sidecar is unavailable (network failure, startup delay, crash):

  • The runtime falls back to builtin regex detection only.
  • A degraded status is reported in the health check response.
  • A warning is logged.
  • No request fails due to sidecar unavailability. The system degrades gracefully rather than failing.

Detection Confidence

Every detection result includes a confidence score (0.0 to 1.0):

  • Builtin regex patterns: confidence is pattern-specific (e.g., IBAN with valid checksum = 0.95, generic phone pattern = 0.7).
  • Python NER: confidence is model-reported.
  • A configurable threshold (default: 0.5) filters low-confidence detections.

7. Operational Security

Rate Limiting

  • Configurable per-tenant token bucket rate limiter.
  • Parameters: requests_per_second and burst_size.
  • Disabled by default (startup warning emitted when disabled).
  • Returns HTTP 429 with a rate_limited error code when exceeded.

Startup Security Checks

On startup, OGuardAI inspects its own configuration and emits warnings for insecure defaults:

CheckWarning Condition
Session secretUsing the placeholder CHANGE_ME_32_BYTE_SESSION_SECRET
Auth modeRunning in dev mode (all requests have admin access)
Prompt securityPrompt security layer is disabled
Output guardOutput guard is disabled
Rate limitingRate limiting is disabled

These checks do not prevent startup -- they ensure operators are explicitly aware of production-readiness gaps.

Diagnostics

An admin-only /v1/diagnostics endpoint reports feature status:

  • Active session backend
  • Detector mode and sidecar connectivity
  • Loaded policies
  • Feature flags (prompt security, output guard, rate limiting)
  • No secrets, keys, or PII are included in diagnostic output.

Structured Logging

  • All logging uses the tracing crate with structured JSON-compatible output.
  • Required context fields on every log entry: session_id, entity_count, latency_ms, request_id.
  • Log output is compatible with standard SIEM systems (Splunk, Elasticsearch, Datadog).
  • Log levels are strictly enforced: debug for development details, info for significant actions, warn for recoverable issues, error for failures requiring attention.

Audit Events

Per-operation structured audit events include:

  • Tenant ID
  • Policy name and version
  • Entity type counts (e.g., {email: 2, person: 1})
  • Action taken (tokenized, blocked, removed)
  • Timing information
  • Request ID for correlation

Audit events never contain raw PII values.


8. Deployment Security

Self-Hosted Model

OGuardAI is designed for self-hosted deployment. In this mode:

  • Data residency: All data processing occurs within the customer's infrastructure. No data leaves the customer's network.
  • No subprocessors: No external services are contacted. The Rust server and optional Python sidecar run entirely within the customer's environment.
  • No phone-home: The server does not contact any external service for licensing, telemetry, or updates.

Container Hardening

The production Docker images follow container security best practices:

MeasureImplementation
Non-root executionUSER guardai (UID 1000)
Read-only filesystemreadOnlyRootFilesystem: true in Kubernetes security context
Minimal base imagedebian:bookworm-slim runtime image (no build tools)
Dropped capabilitiescapabilities.drop: [ALL] -- no Linux capabilities granted
No privilege escalationallowPrivilegeEscalation: false
Health checksBuilt-in health check endpoint at /v1/health

Network Security

  • Single port: The server exposes a single port (default: 3000).
  • TLS termination: Designed for TLS termination at the load balancer or ingress controller. The server handles plaintext HTTP within the cluster network.
  • CORS: The server currently uses permissive CORS (AllowOrigin::any()) suitable for development and API-first deployments. For browser-facing production deployments, configure explicit allowed origins at the reverse proxy or ingress layer.
  • Internal sidecar communication: The Python detector sidecar communicates over the internal cluster network on port 9090. This traffic does not need to be exposed externally.

Secrets Management

  • Session encryption secrets are injected via environment variables or Kubernetes secrets. They are never stored in configuration files committed to version control.
  • The Helm chart supports existingSecret references for integration with external secret managers (Vault, AWS Secrets Manager, etc.).
  • The GUARDAI_SESSION_SECRET environment variable takes precedence over the session.secret config field.

9. Supply Chain Security

Language Choice

OGuardAI's core runtime is written in Rust, which provides:

  • Memory safety: No buffer overflows, use-after-free, or data races at compile time. No garbage collector pauses.
  • No runtime dependencies: The compiled binary is self-contained. No JVM, interpreter, or runtime framework is required.
  • Predictable performance: No GC pauses, no JIT warmup. Latency is consistent from the first request.

Dependency Management

  • Minimal crate dependencies: The dependency tree is auditable via cargo audit.
  • Pinned versions: All dependency versions are pinned in Cargo.lock. No floating version ranges in production dependencies.
  • CI auditing: cargo audit runs in CI. Known vulnerabilities block merge.
  • License compliance: All dependencies are checked for license compatibility.

Native Code

  • No native code in the core runtime. The binary is pure Rust.
  • Exception: The optional OCR module uses Tesseract (C library) for image text extraction. This module is explicitly optional and not included in the default build.
  • Python sidecar: The optional NER detector uses Python with spaCy/GLiNER. It runs as a separate process and communicates via HTTP only -- it has no access to the Rust runtime's memory or encryption keys.

10. Token Safety Guarantees

Token Format

The canonical token format is {{type:id}} (e.g., {{email:e_001}}). This format is:

  • Deterministic: The same entity in the same session always produces the same token. Token assignment is ordered by (start, end, type, normalized_value) to ensure determinism regardless of detection order or parallelism.
  • Non-reversible from format: The token ID (e_001) reveals nothing about the original value. Only the encrypted session mapping can resolve it.
  • Type-preserving: The type prefix (email, person, phone) gives the LLM enough context to produce grammatically correct output.

Token Robustness

LLMs frequently corrupt token syntax in their output (dropped braces, added spaces, case changes). OGuardAI employs a 3-stage repair pipeline:

  1. Strict parse: Exact {{type:id}} match.
  2. Format repair: Fix common corruptions (missing braces, extra whitespace, case normalization).
  3. Fuzzy resolution: Levenshtein distance matching for severely corrupted tokens. Single-candidate-only policy: if ambiguous, the token is left unresolved rather than guessed.

Fail-Safe Properties

  • Hallucinated tokens: Tokens not present in the session mapping are logged and left unresolved. They are never fabricated or guessed.
  • Expired sessions: Produce clean session_expired errors. No partial decryption or fallback behavior.
  • Ambiguous resolution: When fuzzy matching finds multiple candidates, the token is left as-is. No guessing.
  • Restore values: Come ONLY from the session mapping. OGuardAI never fabricates, infers, or generates PII.

11. Compliance Alignment

GDPR (General Data Protection Regulation)

  • Article 4(1) -- Personal Data: OGuardAI detects and protects personal data as defined by GDPR, including names, email addresses, phone numbers, and national identifiers.
  • Article 5(1)(f) -- Integrity and Confidentiality: AES-256-GCM encryption of session state ensures confidentiality. GCM authentication tags ensure integrity.
  • Article 25 -- Data Protection by Design: OGuardAI's architecture enforces protection by default. No configuration is required to activate tokenization.
  • Article 32 -- Security of Processing: Encryption at rest (sealed sessions), access control (scoped authentication), and audit logging address Article 32 requirements.

HIPAA (Health Insurance Portability and Accountability Act)

  • Safe Harbor De-identification: OGuardAI can be configured to detect and mask all 18 HIPAA identifiers through its entity type system and policy engine.
  • Technical Safeguards: Encryption (AES-256-GCM), access controls (scoped auth), and audit controls (structured logging) align with HIPAA technical safeguard requirements.

SOC 2 Type II

  • CC6.1 -- Logical Access: Scoped authentication with API keys or JWT tokens.
  • CC6.6 -- External Threats: Prompt security layer defends against injection attacks.
  • CC6.7 -- Data Transmission: Session state is encrypted in transit (TLS) and at rest (AES-256-GCM).
  • CC7.2 -- System Monitoring: Structured logging and audit events provide continuous monitoring capabilities.

12. Threat Model Summary

ThreatMitigation
LLM sees raw PIITokenization replaces all PII before LLM receives input
LLM hallucinates PIIOutput guard detects and masks/blocks newly generated PII
Session blob tamperingAES-256-GCM authentication tag detects any modification
Cross-tenant data accessTenant ID bound to sealed blob; wrong tenant rejected
Session replayRequest counter in sealed envelope; nonce per seal operation
Prompt injection6-pattern input scanner with configurable block/strip/warn actions
Token extraction from LLMSystem preamble instructs LLM to treat tokens as opaque
PII in logsCustom Debug impls redact values; no raw PII in any log path
PII in error messagesAll error types verified to contain no raw entity values
Timing side-channel on authConstant-time comparison for all secret comparisons
Expired session exploitationTTL enforcement with fail-closed behavior
Key compromiseKey rotation with versioned key IDs; per-tenant keys isolate blast radius

Appendix A: Configuration Security Checklist

Before deploying OGuardAI in production, verify the following:

  • session.secret is set to a unique 32-byte secret (not the default placeholder)
  • auth.mode is set to api_key or jwt (not dev)
  • prompt_security.enabled is true
  • output_protection.enabled is true
  • rate_limit.enabled is true with appropriate per-tenant limits
  • TLS is configured at the load balancer / ingress level
  • The Python detector sidecar (if used) is on an internal network only
  • Container runs as non-root with read-only filesystem
  • GUARDAI_SESSION_SECRET is injected via Kubernetes secret or secret manager
  • CORS allowed origins are restricted at the reverse proxy or ingress layer for browser-facing deployments
  • Audit logs are forwarded to a SIEM system
  • cargo audit / pip-audit / npm audit pass with zero known vulnerabilities

This document is maintained alongside the OGuardAI source code. For the latest version, see the repository at docs/security-whitepaper.md.