Architecture

Privian architecture

How Privian masks sensitive data before prompts reach LLM providers and rehydrates responses before returning them to your application.

Overview

A privacy-first LLM gateway

Privian is a privacy-first LLM gateway that sits between your application and LLM providers. Every prompt passes through one masking hop before egress: sensitive values are replaced with deterministic placeholders, the masked prompt is sent to the provider, and the response is rehydrated in-memory before it returns to your application. The provider never sees the original values.

Request flow

End-to-end request flow

Client application
        │
        ▼
┌────────────────────────────────────────────┐
│              Privian gateway               │
│                                            │
│   1. Request validation (auth, schema,     │
│      body cap, rate limit, quota)          │
│   2. Sensitive-data detection              │
│   3. Masking → placeholders + token map    │
│   4. Provider routing (BYOK credential     │
│      resolved server-side)                 │
└────────────────────────────────────────────┘
        │  masked prompt only
        ▼
   LLM provider (OpenAI / Anthropic / …)
        │  raw response
        ▼
┌────────────────────────────────────────────┐
│   5. Rehydration: placeholders → values    │
│   6. Token map discarded                   │
└────────────────────────────────────────────┘
        │
        ▼
Client application (rehydrated response)

The flow is fixed and ordered: validation → detection → masking → routing → provider call → rehydration. Errors in validation, auth, quota or rate limiting fail before any provider call is made.

Provider view

What the LLM provider sees

Original prompt (from your app)

Summarize the ticket: Customer Michael Olsen
emailed michael@example.com about ticket #4821
and mentioned card 4111 1111 1111 1111.

Masked prompt (sent to provider)

Summarize the ticket: Customer PERSON_1
emailed EMAIL_1 about ticket #4821
and mentioned card CREDIT_CARD_1.

Placeholders are deterministic within a request — the same value reuses the same token — so the model can still reason about structure and reference, but never sees the underlying identifier.

Rehydration

Restoring values on the response

When the provider returns its response, Privian replaces every placeholder with the corresponding original value using the per-request token map. The map is held in an in-memory EntityStore scoped to that single request and is discarded once rehydration completes. There is no cross-request reuse and nothing is persisted.

BYOK

BYOK and provider routing

Privian uses a Bring Your Own Key model. You add provider credentials in the dashboard; Privian routes each request to the right provider based on a namespaced model identifier:

  • openai/gpt-5.5 → routed to OpenAI with your OpenAI key
  • anthropic/claude-sonnet-4.5 → routed to Anthropic with your Anthropic key

Provider credentials are encrypted with AES-256-GCM at rest. The plaintext key is discarded immediately after encryption. Only safe metadata leaves the server — the last four characters and a non-reversible HMAC fingerprint — never ciphertext, IV, or plaintext.

Data handling

What is stored, and what isn't

Data typeUsed forStored?Notes
Raw promptsDetection & masking in-memoryNoDiscarded after the request returns.
Masked promptsSent to the LLM providerNoThis is the only prompt form the provider sees.
Token map (placeholder → value)RehydrationNoIn-memory EntityStore, scoped to a single request.
Rehydrated responsesReturned to the clientNoNot persisted by the gateway.
BYOK provider credentialsOutbound provider callYes — encrypted (AES-256-GCM) at restPlaintext is discarded immediately after encryption. Metadata exposes last4 + fingerprint only.
Gateway API keysAuthenticating your requestsYes — SHA-256 hash onlyPlaintext keys are shown once at creation and never recoverable.
Usage / observability eventsCounters, latencies, rollupsYes — sanitized, no payload contentEntity counts, model, status, timing. No raw text, no entity values.

Detection

Supported masking types

The current detector covers the following entity types out of the box:

  • PERSONPersonal names
  • EMAILEmail addresses
  • PHONEPhone numbers
  • IP_ADDRESSIPv4 and IPv6 addresses
  • CREDIT_CARDPayment card numbers (Luhn-validated)
  • IBANInternational bank account numbers
  • SSN_USUS Social Security numbers
  • SIN_CACanadian SIN
  • JWTJSON Web Tokens
  • OPENAI_API_KEYOpenAI API keys
  • GITHUB_TOKENGitHub personal/access tokens
  • AWS_ACCESS_KEY_IDAWS access key IDs
  • AWS_SECRET_ACCESS_KEYAWS secret access keys
  • GENERIC_API_KEYGeneric API-key patterns
  • ENV_SECRETEnv-style secret assignments
  • SECRET_TOKENOther secret-like tokens

Norwegian fødselsnummer is not yet supported. Custom user-defined entity types are not yet supported.

Transparency

Current beta limitations

  • No OpenAI messages[] API

    Privian accepts a flat prompt string, not OpenAI-style messages arrays.

  • No OpenAI SDK drop-in

    Integrate via a small JSON contract over HTTPS. SDK compatibility is not yet exposed.

  • No tool / function calling

    Tool and function calling are not supported in the current beta.

  • No native provider streaming

    stream: true uses artificial chunking over the already-rehydrated response.

  • No custom entity types yet

    The detector covers a fixed set of built-in entity types.

  • No Norwegian fødselsnummer

    Planned, not yet implemented.

  • No prompt-injection claim

    Privian does not currently claim to block prompt injection or jailbreaks.

FAQ

Frequently asked questions

What does the LLM provider actually see?
The provider receives the masked prompt only — sensitive values are replaced with deterministic placeholders such as PERSON_1 and EMAIL_1 before the outbound provider call. Original values are restored in-memory inside the gateway before the response is returned to your application.
Does Privian store raw prompts or responses?
No. Raw prompts, raw entity values, the per-request token map, and rehydrated responses are not persisted. Only sanitized observability counters, rollup metrics, hashed gateway API keys and encrypted BYOK credentials are stored.
How is the placeholder mapping handled?
Mappings are held in an in-memory EntityStore scoped to a single request and discarded once the response is rehydrated. There is no cross-request reuse and nothing is persisted.
Which providers and models are supported?
OpenAI, Anthropic, Google and DeepSeek via BYOK. Models are addressed using provider-namespaced identifiers such as openai/gpt-5.5 or anthropic/claude-sonnet-4.5.