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).

Your app
Noirdoc gateway
Model provider
INSPECT
Detect, redact & block
Noirdoc Shield redacts sensitive values as [PERSON] or [IBAN], or blocks secrets & prompt injections
FORWARD
Forward sanitised input
Only sanitised inputs reach the model provider; no mapping state is stored
RESPOND
Stream directly
The response returns with zero hold-back latency and no reverse substitution

Flow

Noirdoc Shield uses a stateless one-way design:

  1. 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.
  2. Block or redact in-place: if a filter configured with block matches – by default secrets and prompt injections – the gateway rejects the request before forwarding with status code 403 and error code shield_violation. Matches from filters configured with redact are replaced in-place by fixed placeholders such as [PERSON], [IBAN] or [CUSTOM].
  3. 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.
  4. 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:

KeyPortal labelAllowed actionsDefaultPlaceholders & scope
secretsSecrets & API Keysoff, redact, blockblock[SECRET] – API keys, private keys, cloud tokens, credentials and high-entropy secrets
piiFinancial & Contact Dataoff, redact, blockredact[IBAN], [CREDIT_CARD], [EMAIL], [PHONE], [TAX_ID], [TAX_NUMBER], [VAT_ID], [SSN], [DATE_OF_BIRTH]
nerNames & Addressesoff, redact, blockredact[PERSON], [ADDRESS]
injectionPrompt Injectionoff, blockblockBlocking only (redact is not supported). Evaluated only on untrusted roles (user and tool / function results); system, developer and assistant are exempt.
customCustom Blocklistoff, redact, blockredact[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):

ValuePortal labelMeaning
default_offOn demandShield is off by default and turned on selectively per key, tag or header (default for new organisations).
default_onActive by defaultShield inspects every supported request unless turned off by key, tag or header (API alias advisory).
enforcedEnforcedShield 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:

  1. Active filters check: if all five protection filters are set to off, Shield is inactive. Setting enforced while all five filters are off is rejected with status code 422 (shield_policy_invalid).
  2. Organisation enforced: Shield is always active and cannot be turned off by key, tag or header.
  3. API key (shield_mode): the key’s Noirdoc Shield setting (On on or Off off) applies; Inherit (inherit) defers to the next tier.
  4. Request tags (X-Noirdoc-Tags): if attached tags define shield_mode, any on wins over off; inherit defers.
  5. Request header and organisation default: X-Noirdoc-Shield: on or off (case-insensitive) overrides the organisation default; without the header, default_on activates Shield and default_off leaves 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 Base64 data: URLs or Anthropic text document blocks) 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_id or 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 code shield_uninspectable_content.
    • Under default_on or selective activation (on without enforced), Shield inspects and redacts all text segments in the request, forwards the uninspectable attachment alongside the sanitised text and returns X-Noirdoc-Shield: partial; redacted=<n> with X-Noirdoc-Masked: false.

Supported endpoints

Noirdoc Shield covers generative model endpoints, retrieval endpoints and a standalone inspection endpoint:

EndpointShield inspectionNotes
/v1/chat/completionsyesMessages, text parts, JSON string values in tool_calls and inline UTF-8 text files under 4 MiB
/v1/responsesyesinstructions, input, function call arguments and outputs; preflight token counting on /v1/responses/input_tokens skips Shield at €0
/v1/messagesyessystem, messages, tool blocks, text document blocks and citations; preflight token counting on /v1/messages/count_tokens skips Shield at €0
/v1/embeddingsyesSingle strings, string arrays, multimodal text fields and token ID arrays decoded via tiktoken
/v1/rerankyesquery, instruction and documents[]
POST /v1/shield/inspectyesStandalone inspection without calling a model, for example before external tools or vector stores (see Shield (/v1/shield))
/v1/audio/transcriptions, /v1/audio/speechnoAudio endpoints are not inspected by Shield
/v1/images/generationsnoImage generation is not inspected by Shield
/v1/files, /v1/skillsnoFile 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 to POST /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 as 422 shield_uninspectable_content).
  • Price catalogue: GET /v1/prices exposes 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:

HTTP
Deprecation: true
Sunset: Mon, 30 Nov 2026 23:59:59 GMT
X-Noirdoc-Masked: true

Key behavioural differences between Noirdoc Shield and legacy masking:

AspectNoirdoc ShieldLegacy masking (sunset 30.11.2026)
Direction & stateOne-way redaction ([PERSON], [IBAN]) or blocking, 100% statelessReversible pseudonyms (<<PERSON_1>>) with encrypted Redis session mapping
StreamingImmediate pass-through with zero hold-back latencySentence-level buffering for reverse substitution in the stream
Protection scopeSecrets, PII, names/addresses, prompt injection and custom blocklist (re:)Personal data and names/addresses
EndpointsChat, Responses, Messages, Embeddings, Rerank and POST /v1/shield/inspectChat Completions, Responses and Messages only
FilesInline UTF-8 text attachments under 4 MiBBase64 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 (while X-Noirdoc-Mask continues to control legacy masking until the organisation switches).
  • Per API key or request tag: set shield_mode to on on selected keys or tags.
  • Standalone: call POST /v1/shield/inspect directly.

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.