How it works
Architecture for developers
What you need to know to debug a request. For visuals and the business framing, see /how-it-works.
Every request through Lucairn passes through a fixed sequence of services. Each one has a single job, runs in its own network namespace, and emits an audit record. If a request fails, the failure is locatable to one component.
Request flow (top to bottom)
- 1Client sends POST /v1/messages with
Authorization: Bearer lcr_live_*andX-Upstream-Key: sk-ant-*. - 2Gateway authenticates the Lucairn key, looks up the tier (Developer / Pro / Enterprise).
- 3Gateway forwards body to Sanitizer (gRPC). Sanitizer returns
{redacted_text, manifest}where manifest lists every entity replaced. - 4Gateway calls ID Bridge with the manifest; Bridge persists mapping rows scoped to this
request_idand returns a bridge claim signed by the Bridge's Ed25519 key. - 5Gateway calls Sandbox B with the redacted body; Sandbox B forwards to your upstream LLM using your
X-Upstream-Keyheader. Response comes back redacted. - 6Gateway optionally re-links on the Lucairn-native endpoint (Pro and Enterprise only — opt-in). Free-tier response keeps placeholders.
- 7Veil Witness assembles the canonical signable:
{request_id, sanitizer_manifest_hash, bridge_claim, sandbox_isolation_attestation, content_hash, witness_timestamp, protocol_version}. Signs with Ed25519. - 8Gateway returns the response with
metadata.dsa_compliance.certificate_urlpointing at the witness-signed certificate.
Components
Gateway
Entry pointAuthenticates your lcr_live_* API key, forwards your X-Upstream-Key header, classifies the request shape (Anthropic / OpenAI / Lucairn-native / MCP), and routes through the pipeline. The gateway never sees raw identity values — it operates on tokens after the sanitizer.
- → POST /v1/messages
- → POST /v1/chat/completions
- → POST /api/v1/proxy/messages
- → POST /api/v1/scan
Sanitizer
PII detection + redactionThree layers of detection on the request body: (L1) Presidio NER with custom recognizers, (L2) Quasi-Identifier risk scoring, (L3) on-GPU LLM PII Shield. Each detected entity gets replaced with a placeholder like [PERSON_1] or [EMAIL_2].
- → Internal: gRPC :50055
- → Layer toggles via `X-Lucairn-Sanitizer-Layers` header
ID Bridge (Sandbox A)
Identity-side mapping holderStores the placeholder ↔ raw-value mappings for the lifetime of the request. The mapping table lives here, not in Sandbox B. Free tier responses are returned with placeholders intact. Pro and Enterprise can opt into automatic re-linking; that re-linking happens in the gateway memory, never persisted alongside AI output.
- → Internal: gRPC :50052
- → Postgres `identity_mappings` table — INSERT/SELECT only
Sandbox B
AI inferenceRuns in its own Kubernetes namespace with NetworkPolicies that deny all egress except the upstream LLM provider you specified. It receives only the sanitized payload — never raw PII. If you compromise this sandbox you get tokens, not identities.
- → Outbound only: api.anthropic.com / api.openai.com / your self-hosted endpoint
Veil Witness
Certificate signerWatches the gateway emit a structured event for every request — sanitizer manifest, sandbox-isolation check, content hash, timestamps, bridge claim. The witness assembles a canonical 7-key signable, signs with Ed25519, and stores the certificate. Public key is published at /.well-known/veil-keys.json for offline verification.
- → GET /api/v1/veil/certificate/{request_id}
- → GET /api/v1/veil/certificate/{request_id}/summary
- → GET /.well-known/veil-keys.json
Audit Trail
Append-only event logEvery decision (auth, sanitizer hit, sandbox routing, certificate mint, re-linking attempt) gets a row in an append-only Postgres table with a hash chain. The application role has INSERT and SELECT only. Deletion only happens via a security-definer function for GDPR Article 17 erasure, which writes a separate signed erasure event.
- → GET /api/v1/account/audit (any tier — viewing is tier-agnostic; CSV export is Pro and Enterprise only)
- → POST /api/v1/audit/export
Debugging tips
If you see
[PERSON_N]in the response, the sanitizer redacted it correctly but you're on a tier without re-linking. Either pass the placeholder back yourself, or upgrade to Pro for opt-in re-linking.If you see
503 scanner_unavailable, the sanitizer is down. The gateway fail-closes — this is intentional. Watch /changelog for incident updates.If a certificate URL returns 404, the witness is down or the request_id is malformed. Cert IDs are URL-safe base64 of 16 bytes.
If your
lcr_live_*key auth fails, check that you copied the full key (no trailing newline) and that you're not using a retireddsa_*legacy key.The gateway emits Plausible-friendly health metrics on /healthz; container logs are the source of truth.
Related
Want to see this in action?
Book a working session — we'll walk through your use case together.