Concepts
Noirdoc Shield
How Noirdoc Shield inspects inbound prompts statelessly on German infrastructure, redacts or blocks sensitive content and forwards responses with zero hold-back latency.
Noirdoc Shield inspects inbound requests on German infrastructure before any data leaves the gateway towards a model provider. Depending on your protection filters, Shield either redacts detected values in-place with fixed category placeholders such as [PERSON] or [IBAN], or blocks the request before forwarding with HTTP status code 403 (shield_violation).
Flow
Noirdoc Shield uses a stateless one-way design:
- Inspect on German infrastructure: the gateway extracts text segments from the request (including inline UTF-8 text attachments under 4 MiB) and runs your organisation’s active protection filters before opening a request to the model provider. Inspected fields (Shield) lists the exact fields per endpoint.
- Block or redact in-place: if a filter configured with
blockmatches – by default secrets and prompt injections – the gateway rejects the request before forwarding with status code 403 and error codeshield_violation. Matches from filters configured withredactare replaced in-place by fixed placeholders such as[PERSON],[IBAN]or[CUSTOM]. - Forward sanitised input: only the sanitised text reaches the model provider. Unlike legacy masking, Shield stores no mapping table in Redis and injects no system prompt into the conversation.
- Stream directly: the gateway passes the model’s response straight through. There is no reverse substitution in the model’s output and zero sentence-buffering latency during streaming.
You send
Write to Anna Schmidt that the payment to DE89 3704 0044 0532 0130 00 has arrived.
The model sees
Write to [PERSON] that the payment to [IBAN] has arrived.
When all inspectable content in the request has been checked by Noirdoc Shield, the response carries X-Noirdoc-Shield: redacted=<n> (the number of redacted spans, 0 when nothing matched) and X-Noirdoc-Masked: true. If a non-enforced request includes attachments that Shield cannot inspect as text alongside text fields, the text fields are still inspected and redacted, and the response carries X-Noirdoc-Shield: partial; redacted=<n> and X-Noirdoc-Masked: false.
Detection is automated and reduces the risk of accidentally transmitting secrets, personal data and prompt injections, though it does not replace reviewing what your application sends.
Protection filters
Under Models → Shield (and via /v1/shield/policy), admins configure five independent protection filters:
| Key | Portal label | Allowed actions | Default | Placeholders & scope |
|---|---|---|---|---|
secrets | Secrets & API Keys | off, redact, block | block | [SECRET] – API keys, private keys, cloud tokens, credentials and high-entropy secrets |
pii | Financial & Contact Data | off, redact, block | redact | [IBAN], [CREDIT_CARD], [EMAIL], [PHONE], [TAX_ID], [TAX_NUMBER], [VAT_ID], [SSN], [DATE_OF_BIRTH] |
ner | Names & Addresses | off, redact, block | redact | [PERSON], [ADDRESS] |
injection | Prompt Injection | off, block | block | Blocking only (redact is not supported). Evaluated only on untrusted roles (user and tool / function results); system, developer and assistant are exempt. |
custom | Custom Blocklist | off, redact, block | redact | [CUSTOM] – up to 100 entries of 2 to 256 characters each (case-insensitive literal substrings or re: regular expressions) |
While injection deliberately evaluates only user and tool segments so that your own developer instructions do not trigger false positives, secrets, pii, ner and custom inspect every role in the request.
For the Custom Blocklist (custom_patterns), you can configure up to 100 entries of 2 to 256 characters each:
- Plain strings without a prefix (for example
"Projekt Helios") match case-insensitive literal substrings. - Regular expressions prefixed with
re:(for example"re:AZ-[0-9]{4}-[0-9]{5}") compile as linear-time regular expressions. Look-around assertions and backreferences are not supported, and the pattern must not match the empty string.
Policy and precedence
Under Models → Shield, admins choose the organisation’s Default Setting (mode / shield_policy):
| Value | Portal label | Meaning |
|---|---|---|
default_off | On demand | Shield is off by default and turned on selectively per key, tag or header (default for new organisations). |
default_on | Active by default | Shield inspects every supported request unless turned off by key, tag or header (API alias advisory). |
enforced | Enforced | Shield is mandatory on every request and cannot be turned off by API key, request tag or request header. |
On every request, the gateway evaluates five tiers in order:
- Active filters check: if all five protection filters are set to
off, Shield is inactive. Settingenforcedwhile all five filters areoffis rejected with status code 422 (shield_policy_invalid). - Organisation
enforced: Shield is always active and cannot be turned off by key, tag or header. - API key (
shield_mode): the key’s Noirdoc Shield setting (Ononor Offoff) applies; Inherit (inherit) defers to the next tier. - Request tags (
X-Noirdoc-Tags): if attached tags defineshield_mode, anyonwins overoff;inheritdefers. - Request header and organisation default:
X-Noirdoc-Shield: onoroff(case-insensitive) overrides the organisation default; without the header,default_onactivates Shield anddefault_offleaves it inactive.
On organisations running Noirdoc Shield, X-Noirdoc-Mask continues to work as a legacy alias for X-Noirdoc-Shield. On pre-existing organisations that are still on legacy masking during the transition period, X-Noirdoc-Mask controls legacy masking while X-Noirdoc-Shield: on explicitly selects Noirdoc Shield for that request. The gateway strips both headers before forwarding.
Files and attachments
Whether requests may carry file, image or audio parts at all is controlled by Allow file and image attachments in requests (allow_file_content) under Models → Shield in Advanced Settings. When turned off, any request containing attachments is rejected with status code 403 (file_content_not_allowed).
When file attachments are allowed and Noirdoc Shield is active for a request, behaviour depends on the attachment format:
- Inline UTF-8 text attachments under 4 MiB (
text/*, JSON, XML, CSV, Markdown, YAML passed as Base64data:URLs or Anthropic textdocumentblocks) are decoded, inspected across all active filters and redacted in-place before forwarding. - Binary documents, media, external references and large files – including PDF, DOCX, XLSX, PPTX, images, audio, video, files referenced by
file_idor URL and inline text of 4 MiB or larger – cannot be inspected by Shield:- Under
enforced, the gateway rejects the request before forwarding with status code 422 and error codeshield_uninspectable_content. - Under
default_onor selective activation (onwithoutenforced), Shield inspects and redacts all text segments in the request, forwards the uninspectable attachment alongside the sanitised text and returnsX-Noirdoc-Shield: partial; redacted=<n>withX-Noirdoc-Masked: false.
- Under
Supported endpoints
Noirdoc Shield covers generative model endpoints, retrieval endpoints and a standalone inspection endpoint:
| Endpoint | Shield inspection | Notes |
|---|---|---|
/v1/chat/completions | yes | Messages, text parts, JSON string values in tool_calls and inline UTF-8 text files under 4 MiB |
/v1/responses | yes | instructions, input, function call arguments and outputs; preflight token counting on /v1/responses/input_tokens skips Shield at €0 |
/v1/messages | yes | system, messages, tool blocks, text document blocks and citations; preflight token counting on /v1/messages/count_tokens skips Shield at €0 |
/v1/embeddings | yes | Single strings, string arrays, multimodal text fields and token ID arrays decoded via tiktoken |
/v1/rerank | yes | query, instruction and documents[] |
POST /v1/shield/inspect | yes | Standalone inspection without calling a model, for example before external tools or vector stores (see Shield (/v1/shield)) |
/v1/audio/transcriptions, /v1/audio/speech | no | Audio endpoints are not inspected by Shield |
/v1/images/generations | no | Image generation is not inspected by Shield |
/v1/files, /v1/skills | no | File uploads and skill payloads are not inspected by Shield; listing, metadata, downloading and deleting remain allowed even under enforced |
On uninspected endpoints (/v1/audio/*, /v1/images/generations and content-carrying requests on /v1/files and /v1/skills), requests under enforced – as well as requests sending X-Noirdoc-Mask: on, and X-Noirdoc-Shield: on on /v1/images/generations – are rejected with status code 403 (masking_not_supported_for_endpoint) rather than forwarded uninspected.
| Status | Code | Meaning |
|---|---|---|
| 403 | shield_violation | Noirdoc Shield blocked the request before forwarding to the provider because an active protection filter configured with block matched; message names the triggered rule (secrets, pii, ner, injection or custom). |
| 403 | masking_not_supported_for_endpoint | The endpoint supports neither Noirdoc Shield nor legacy masking, yet the policy is enforced or the request sends X-Noirdoc-Mask: on (and on /v1/images/generations also X-Noirdoc-Shield: on). During the legacy masking transition until 30.11.2026, this also affects /v1/embeddings and /v1/rerank on pre-existing organisations that have not switched to Shield yet. |
| 422 | shield_uninspectable_content | The Shield policy is enforced, and the request carries content that Shield cannot inspect as text (binary_document such as PDF or Office, media_not_inspectable such as images, audio or video, file_reference by ID or URL, file_too_large at 4 MiB or above, file_not_decodable or unrecognised_content). The gateway did not forward the request. |
Billing
Noirdoc Shield is billed at a flat +€0.40 per 1M inspected input tokens across all five protection filters, with no per-filter add-ons.
- When Shield is billed: whenever Shield inspects text – on providers managed by Noirdoc, on your own provider keys (BYOK, deducted from organisation credit or invoiced), on requests stopped with
403 shield_violation(since Shield ran and protected the request) and on standalone calls toPOST /v1/shield/inspect. - When Shield is not billed: when Shield is inactive for the request, on preflight token-counting endpoints (
/v1/messages/count_tokens,/v1/responses/input_tokens) or when a request is rejected before Shield runs (such as422 shield_uninspectable_content). - Price catalogue:
GET /v1/pricesexposes the rate under the top-level"shield"field ({"price_input": "0.40", "price_unit": "per1MTokens", "currency": "EUR", "price_currency": "EUR"}), see Models & pricing.
Legacy masking
Pre-existing organisations that already used or configured legacy reversible masking before Noirdoc Shield launched remain on legacy masking during a transition period until 30 November 2026 (2026-11-30T23:59:59Z). Throughout this transition period, every legacy-masked response includes RFC 8594 deprecation headers alongside X-Noirdoc-Masked: true:
Deprecation: true
Sunset: Mon, 30 Nov 2026 23:59:59 GMT
X-Noirdoc-Masked: trueKey behavioural differences between Noirdoc Shield and legacy masking:
| Aspect | Noirdoc Shield | Legacy masking (sunset 30.11.2026) |
|---|---|---|
| Direction & state | One-way redaction ([PERSON], [IBAN]) or blocking, 100% stateless | Reversible pseudonyms (<<PERSON_1>>) with encrypted Redis session mapping |
| Streaming | Immediate pass-through with zero hold-back latency | Sentence-level buffering for reverse substitution in the stream |
| Protection scope | Secrets, PII, names/addresses, prompt injection and custom blocklist (re:) | Personal data and names/addresses |
| Endpoints | Chat, Responses, Messages, Embeddings, Rerank and POST /v1/shield/inspect | Chat Completions, Responses and Messages only |
| Files | Inline UTF-8 text attachments under 4 MiB | Base64 file analysis for PDF, DOCX, XLSX and optional OCR (file_analysis_mode) |
| Pricing | +€0.40 / 1M inspected input tokens | €0 surcharge during the transition period |
During the transition period, legacy organisations can test Noirdoc Shield side by side without switching the whole organisation:
- Per request: send
X-Noirdoc-Shield: on(whileX-Noirdoc-Maskcontinues to control legacy masking until the organisation switches). - Per API key or request tag: set
shield_modetoonon selected keys or tags. - Standalone: call
POST /v1/shield/inspectdirectly.
Admins can switch their organisation permanently in one click under Models → Shield (Switch to Noirdoc Shield now) or by writing to PUT /v1/shield/policy or PATCH /v1/shield/policy (legacy_mask_active: false). Switching is one-way, and the existing policy mode (default_off, default_on or enforced) carries over to Shield. After 2026-11-30T23:59:59Z, all remaining legacy organisations automatically run on Noirdoc Shield.