Modes

Observe, Enforce, Block

Three sanitization postures. Pick one per API key. Match the strictness of the gateway to the strictness of the workload.

The Lucairn gateway sits between your application and the inference vendor. Every prompt passes through the sanitizer before it leaves your zone, and every response carries a signed certificate on the way back. The mode controls what happens when the sanitizer finds PII: log only, redact-and-rehydrate, or refuse. Each posture maps to a different compliance question — pick by what your auditor asks rather than by what feels safest in the abstract.

Observe

Coming soon

Log only. Sanitizer scans, certificate is emitted, response is unchanged.

Observe runs the same sanitizer pipeline as Enforce — Layer 1 known-entity matching, Layer 2 Presidio NER, optionally Layer 3 PII Shield — and records every finding on the certificate. It does not redact. The model receives the original prompt verbatim. The audit trail is identical to Enforce: you get the same signed certificate, the same redaction count, the same sanitizer-layer breakdown. The only thing that changes is the body of the request the vendor sees.

When to use it

An audit-readiness phase before you can change downstream consumers — you need to know what PII would be redacted before you flip the switch. A measurement window for tuning recognizers without affecting production behaviour. Vendor-onboarding evidence: you can show the regulator a body of certificates documenting how often PII enters the AI hop, without altering output.

Response shape

Identical to a stock SDK response, plus the metadata.dsa_compliance block carrying veil_certificate_url, veil_summary_url, redaction_count, sanitizer_layers, latency_ms. Body of content[0].text contains no placeholders.

Compliance + audit implications

Useful as evidence-without-side-effects. Does not satisfy GDPR Art 25 data-minimisation in production — identity still flows to the vendor. Treat as a transitional posture or a measurement layer, not a steady-state production mode for regulated workloads.

Configuration

# Coming soon — preview
# When shipped, configurable per API key:
# admin: PATCH /admin/keys/{key_id}  { "mode": "observe" }
# Today's closest primitive: mcp_system_policy=passthrough_audit
# (MCP system-prompt path only; see services/gateway/internal/auth/apikey.go).

Enforce

Default — live today

Sanitize and redact. The LLM sees [PERSON_N] placeholders; the response is rehydrated.

Enforce is the default mode and the structural property an auditor asks for. The sanitizer redacts every detected entity before the request leaves the gateway. The model sees [PERSON_1], [EMAIL_1], [IBAN_1], etc. — never the underlying values. On the way back, placeholders are rehydrated against Sandbox A only for tier-permitted callers. Sandbox B (the inference zone) has no network path to Sandbox A (the identity zone), so even a sanitizer miss cannot cross the bridge into a reusable identity-linked record.

When to use it

Production for regulated workloads. The default for any workflow under EU AI Act, GDPR, DORA, NIS 2, or HIPAA. The simplest answer to the question 'prove the LLM never saw identity in the clear'.

Response shape

Body of content[0].text references placeholders that are rehydrated for the caller. metadata.dsa_compliance carries the same fields as Observe. The signed certificate at veil_certificate_url documents which entities were redacted, by which sanitizer layer, with what manifest hash.

Compliance + audit implications

Maps directly to GDPR Art 25 (data protection by design) and Art 32 (security of processing). EU AI Act Art 10 + Art 12 + Art 14 + Art 15 mappings flow from the sanitizer pipeline plus the append-only audit chain. The signed claim is the artifact a regulator inspects.

Configuration

# Default — no configuration needed
# Every new API key starts in Enforce.
# To inspect:
# admin: GET /admin/keys/{key_id}  → mcp_system_policy: "sanitize"
# (or simply unset, which defaults to sanitize-and-redact).

Block

Coming soon

Refuse. Gateway returns HTTP 403 if any PII is detected. No inference happens.

Block is the strictest posture. Any PII detection by any sanitizer layer aborts the request before it reaches the inference vendor. The gateway responds with HTTP 403 and a structured error body listing the entities found. No inference happens, no inference token is consumed, no certificate-with-output is generated. A rejection-certificate is emitted instead so the audit chain still records that the prompt was attempted.

When to use it

Endpoints where the prompt should never contain identity at all — fully-anonymised research workflows, public-facing demo endpoints, internal classifiers that work on metadata only. Any workflow where the cost of a sanitizer miss is higher than the cost of a refused request.

Response shape

HTTP 403 with body { error: 'pii_detected', entities: [{ type, layer, count }], certificate_url }. The certificate URL still resolves and the rejection is recorded on the audit chain — proving 'we caught and refused' rather than 'nothing happened here'.

Compliance + audit implications

Strongest posture for workloads where leakage cost > availability cost. The rejection-certificate is itself audit evidence: a regulator can see that the gateway caught a PII-bearing prompt and refused, which is materially better than 'nothing in the logs'.

Configuration

# Coming soon — preview
# When shipped, configurable per API key:
# admin: PATCH /admin/keys/{key_id}  { "mode": "block" }
# Rejection responses follow the standard error envelope
# documented at /docs/api-reference.

Related reading

Want to see this in action?

Book a working session — we'll walk through your use case together.