OGuardAI
Architecture

Architecture Overview

How OGuardAI is organized into three planes, the pipeline flow, trust boundary model, and session design

What is OGuardAI?

OGuardAI is a semantic data protection and transformation runtime for AI systems. It sits between your applications and language models, detecting sensitive entities in text, replacing them with deterministic semantic tokens, and restoring original values in model output, all governed by declarative policies. The result: your LLM produces grammatically correct, personalized output while working from tokens instead of detected raw PII.

Architecture Diagram

OGuardAI is organized into three planes:

+-----------------------------------------------------+
|                    Applications                       |
|  (Chatbots, RAG, Agents, CRM, Support, Docs)        |
+---------------------------+--------------------------+
                            |
+---------------------------v--------------------------+
|                 Integration Plane                     |
|  TS SDK | Python SDK | MCP | LangChain | Proxy       |
+---------------------------+--------------------------+
                            |
+---------------------------v--------------------------+
|                Runtime Plane (Rust)                    |
| +-----------+ +----------+ +-----------+             |
| | Detectors |>| Tokenizer|>|Transformer| --> LLM     |
| +-----------+ +----------+ +-----------+             |
|                                    |                  |
| +---------+ +----------+ +--------------+            |
| | Policy  | | Session  | | Rehydrator   | <-- LLM    |
| +---------+ +----------+ +--------------+            |
+------------------------------------------------------+

Runtime Plane (Rust)

The core engine, written in Rust for performance and safety:

CratePurpose
guardai-coreTypes, errors, runtime kernel
guardai-tokenizerSemantic token generation ({{type:id:cap}} format)
guardai-transformerPrompt transformation (replace spans with tokens)
guardai-rehydrateOutput rehydration (resolve tokens to values)
guardai-policyPolicy engine (YAML rules, conditional evaluation)
guardai-sessionSession backends (sealed AES-256-GCM, memory, and Redis encrypted at rest) plus the revocation store (file-persisted or Redis) and the replay store (in-memory or Redis)
guardai-detector-builtinsRust regex-based entity detectors
guardai-detector-clientBridge to Python NER detector service
guardai-authAuthentication middleware (API key, static JWT, and OIDC/JWKS)
guardai-token-robustness3-stage token repair (strict, deterministic, fuzzy)
guardai-output-guardSecond-pass scan for LLM-hallucinated PII
guardai-prompt-securityPrompt injection defense
guardai-provider-strategySafe entity context generation for LLM system prompts
guardai-large-textParagraph-boundary chunking for large documents
guardai-streamingSSE streaming for transform and rehydrate

Integration Plane

SDKs and framework adapters:

PackagePurpose
@oguardai/sdkTypeScript SDK with session management
oguardai-sdk (Python)Sync and async Python SDK
sdk-go (Go)Dependency-free Go SDK (guarded call and chat, sessions, streaming)
oguardai-sdk (Java)Java SDK on java.net.http (guarded call and chat, sessions, streaming)
@oguardai/mcp-serverMCP server for AI clients (Claude, Cursor, etc.)
LangChain adapterShips in both SDKs: @oguardai/sdk/integrations/langchain and the Python oguardai-sdk[langchain] extra
Vercel AI adapterShips in the TypeScript SDK: @oguardai/sdk/integrations/vercel (guardedGenerateText)

Platform Plane (Future)

SaaS/PaaS capabilities: tenant management, usage-based billing, managed sessions.

Pipeline Flow

Every request follows this pipeline:

1. INPUT           Raw text with PII
2. DETECT          Regex + optional NER: find names, emails, IDs, phones, addresses
3. CLASSIFY        Entity type, confidence score, language, metadata
4. POLICY CHECK    Block? Tokenize? Allow? What restore mode per entity?
5. TOKENIZE        Assign deterministic `{{type:id:cap}}` tokens, build session mapping
6. TRANSFORM       Replace spans in text, generate safe metadata for LLM

   === TRUST BOUNDARY === (detected, non-whitelisted raw PII tokenized before crossing)

7. LLM PROCESSES   Model sees tokens + safe metadata (plus any whitelisted values)
8. LLM RESPONDS    Response contains tokens: "Sehr geehrte `{{person:p_001:ad4f97591c16}}`..."

   === TRUST BOUNDARY ===

9. TOKEN REPAIR    3-stage: strict parse -> deterministic repair -> fuzzy resolve
10. REHYDRATE      Restore values per policy: full/partial/masked/formatted/abstract/none
11. OUTPUT GUARD   Re-scan for NEW PII the model hallucinated (not from input)
12. FINAL OUTPUT   Business-ready, personalized, compliant

Trust Boundary Model

The trust boundary is the legal and technical foundation of OGuardAI. By design, detected raw PII is tokenized before it crosses it; an explicit policy whitelist is the one deliberate exception.

ZoneContainsNever Contains
Trusted Zone (OGuardAI runtime)Raw PII, token mappings, encryption keys, policy rules--
Untrusted Zone (LLMs, tools, logs, vector stores){{type:id:cap}} tokens, safe metadata, encrypted session blobs, plus any policy-whitelisted valuesDetected, non-whitelisted raw PII, real names, real emails, real IDs
Boundary CrossingTokenized text + entity_context metadataAny detected, non-whitelisted raw sensitive value

What crosses the boundary

Outbound (to LLM):

  • Tokenized text: "Contact `{{person:p_001:ad4f97591c16}}` at `{{email:e_001:1bcaef1a4aff}}`"
  • Entity context (safe metadata only): [{token: "`{{person:p_001:ad4f97591c16}}`", type: "person", gender: "female"}]

Inbound (from LLM):

  • LLM output with tokens: "Dear `{{person:p_001:ad4f97591c16}}`, thank you for..."

Never crosses (unless explicitly whitelisted):

  • Raw values: "Julia Schneider", "julia@example.com"
  • Token-to-value mappings
  • Encryption keys

Crate Dependency Graph

Apps (binaries)
  oguardai-server   depends on guardai-runtime plus the server-only crates
  oguardai-proxy    depends on guardai-runtime plus a subset
  oguardai-cli      depends only on guardai-core + guardai-api-types (thin HTTP client)

guardai-runtime   the protection kernel; aggregates the pipeline crates:
  guardai-tokenizer, guardai-transformer, guardai-rehydrate, guardai-policy,
  guardai-token-robustness, guardai-output-guard, guardai-session,
  guardai-provider-strategy, guardai-detector-builtins

guardai-core      shared types; guardai-api-types depends on core

Self-contained crates (no internal dependencies):
  guardai-auth, guardai-prompt-security, guardai-streaming,
  guardai-large-text, guardai-document-ingest

# See the Crate Graph page for the full, exact dependency edges.

Session Model

Sessions bind token-to-value mappings for the duration of a transform-rehydrate cycle.

Default: Sealed sessions. AES-256-GCM encrypted blobs returned to the client. No server-side state required. The client is the sole custodian of the encrypted session blob.

Other backends: in-memory (dev/test) and Redis (encrypted at rest, shared cross-replica for HA). A Redis session backend also requires a Redis replay backend, and any Redis or multi-replica HA deployment requires revocation_backend=redis (with high_availability=true) so a value revoked on one replica cannot be restored through another; server startup rejects the unpaired configurations. Managed/persistent SaaS backends remain planned.

Performance (indicative)

These are indicative figures from local profiling, not guarantees. Actual latency depends on hardware, the NER model, and text length.

OperationBuilt-in Detectors (regex)With Python NER
Transform (short text)~1-2ms~80ms p50, up to several hundred ms p99
Transform (large doc, chunked)~3-15mstens to hundreds of ms, length-dependent
Rehydrate~1-3ms~1-3ms
Sealed session encrypt/decrypt<1ms<1ms
Token repair (3-stage)<1ms<1ms

The two detector modes differ by orders of magnitude: the built-in regex path runs in single-digit milliseconds, while the NER path (GLiNER on CPU) adds model inference in the tens-to-hundreds of milliseconds. Either way, OGuardAI adds little overhead compared to the LLM call itself (typically 500-5000ms).