Skip to main content
The Azure Content Safety policy sends the request text to the Analyze Text operation of Azure AI Content Safety and applies the verdict at the gateway. Azure scores four harm categories — Hate, Violence, Self-harm and Sexual content — and the policy refuses the request when any category you enforce reaches the severity you set for it. It blocks, or it allows. It cannot mask, redact or rewrite anything. And it never sees the model’s answer: this policy has no response leg at all. Everything below is about what goes in.
The endpoint is the value that will go wrong. The gateway POSTs the URL you configure exactly as you typed it and appends nothing — no operation path, no api-version. The endpoint the Azure portal shows on Keys and Endpoint is the resource root, not an operation, so it is accepted when you save the policy and then fails on every single request.
You will not see Azure’s 404. Any non-2xx from Azure becomes one generic gateway error, so the symptom is every request failing with nothing naming the cause.
2024-09-01 is the version to use today, and it will not be the version forever. Microsoft deprecated every other Analyze Text version on 1 March 2025, leaving it the only generally available one. Their own policy then deprecates a GA version 90 days after its successor ships, so check Azure’s Analyze Text reference before you paste this in — a version Azure has retired fails the same way a wrong path does, with one generic gateway error.
This policy puts a synchronous call in front of every request. What that costs depends on your region, your resource tier and the size of the conversation, so measure it in your own environment rather than assuming.

Part 1 — Set up Azure AI Content Safety (TBD)

This walkthrough is being written against a real account. Until then, follow Azure’s own documentation to create the resource, and come back for Part 2.
Everything in this part happens in your own Azure subscription. TrustGate never creates or changes anything there. These are the values the policy will ask you for: Nothing else about the resource is configured from TrustGate. There is no blocklist, no custom term list and no per-category configuration on the Azure side that this policy reads.

Part 2 — Give the gateway a key

The policy authenticates with the resource’s subscription key. Copy it from the resource and paste it into the policy.
The key is stored as provided and is shown again whenever the policy is reopened. Treat it like any other credential. Because the resource issues two keys, you can rotate by pasting the second one into the policy and then regenerating the first.

Part 3 — Configure the policy in TrustGate

Open PoliciesLibraryAzure Content Safety.

Azure connection

The console checks that the endpoint is an absolute http(s) URL, and nothing more. Whether that URL is an operation Azure will answer is between you and Azure.

Category thresholds

Severity scale4 levels - 0,2,4,6 (the default) or 8 levels - 0-7. This is sent to Azure with every call and decides the severities it returns. It also decides which thresholds you may pick below: 2, 4 or 6 on the four-level scale, 1 to 7 on the eight-level one. The console offers only the legal values, and a threshold that becomes illegal when you switch scale is snapped to the nearest one that is — so re-read the thresholds after changing the scale. Then one row per category: Hate, Violence, Self-harm, Sexual content. The toggle decides whether the category is sent to Azure at all; Block at is the severity at which it blocks. A category breaches when the severity Azure returns is greater than or equal to its Block at value. A new policy starts with all four categories enabled at Block at 4. At least one category must stay enabled or the policy will not save. A category you turn off is not sent to Azure and is never scored, so there is no “score it but do not block on it” for a single category. Recording without blocking is what Observe does, and it applies to the whole policy.

When content is blocked

Block message — returned to the caller in the 403 body. Left empty, the body carries request blocked by Azure Content Safety.

Stage and mode

This policy runs on the request leg, and that is not a choice. Screening the request on its way to the model is the only thing it can do, so the form draws no selector for it — there is nothing to select between. Start in Observe, which records every decision without refusing anything, read the severities Azure actually returns for your traffic, and only then set the thresholds and switch to Enforce.

How the decision is made

1

The whole conversation becomes one string

The system prompt, if present, and the text of every message in the request are joined with newlines and sent as a single value. Roles are not sent. Tool definitions, tool calls and tool results are not sent. Attachments are not sent.Sending the whole conversation is what lets this policy catch something assembled across several turns. It is also what makes it collide with Azure’s length limit — see Limits.
2

Azure scores the enabled categories

One Analyze Text call per request, carrying the categories you enabled and the severity scale you chose. A request whose text is empty after joining is forwarded without calling Azure at all.
3

Any category at or above its threshold refuses the request

The request never reaches the model. The caller gets 403, and the response names every category that breached, with the severity Azure returned and the threshold it crossed. The wording is your Block message, or the default.Those category names are Azure’s own — Hate, Violence, SelfHarm and Sexual — rather than the labels this form shows, so a colleague reporting a refusal may name a category you do not recognise from the console.

Modes and failures

In Enforce this policy fails closed, and there is no setting to change that. Every failure collapses into the same 502: a wrong key, a wrong endpoint, a throttled resource and a conversation past Azure’s length limit are indistinguishable to the caller, and the response carries no detail about which one it was. Validate in Observe, and account for this when sizing availability.

Limits

  • Request leg only. There is no response leg, so this policy cannot see, score or block what the model says — not for streaming responses, not for any response. This is a larger limit than anything you can configure on it. If you need output screening, pair it with a guardrail that has a response leg.
  • It blocks; it cannot mask. No anonymisation and no rewriting. Sensitive content is refused or forwarded, never redacted.
  • Four categories, and nothing else. No blocklists, no custom term lists, no jailbreak or prompt-shield detection, no protected-material detection.
  • Azure’s length limit applies to the whole conversation. Azure documents a 10,000-character limit on Analyze Text. The policy sends the joined conversation and never truncates it, so a long enough conversation is rejected by Azure — and because the policy fails closed, that is a 502 on that turn and on every turn after it, because a conversation only grows. Treat this policy as suited to short exchanges until you have measured your own.
  • Subscription key only. No Microsoft Entra ID, no managed identity.
  • Text only. Files, images and audio are not sent to Azure.
  • LLM traffic only. The policy does not apply to MCP (Model Context Protocol) tool calls.
Microsoft documents the Analyze Text limit as a default maximum of 10,000 characters, and tells callers to split longer text themselves. Being a default, it may be raised on your resource — but nothing in this policy splits anything, so until you have confirmed otherwise on your own resource, treat 10,000 as the ceiling this policy works within.

Verify the policy

Open the Playground, pick the application the policy applies to, and send these prompts in this order. Starting with the control means a failure tells you something specific.
1

Control — the path works at all

Expect a normal reply and the decision allowed.In Enforce, this step is also the endpoint test. A harmless prompt that comes back 502 means the gateway could not get an answer out of Azure: wrong endpoint, wrong key, or the resource unreachable. Fix that before going on — nothing below will work until this does.
2

Observe — read the severities before you trust the thresholds

Switch the policy to Observe and send content you consider borderline for your application. Nothing is refused, and the decision recorded is reported when a category breached and allowed when none did.This is how you find out what severities Azure returns for your traffic rather than guessing. Set Block at from what you see here.
3

Enforce — blocking works

Back in Enforce, send something that should breach a category you enabled.Expect 403, the decision block, and no time at the provider in the timing breakdown. That the provider leg is empty is the evidence that matters: the request never reached the model. Read the categories the refusal names to confirm it fired on the one you expected.
Every decision is emitted as a metadata event, in Observe mode too, where nothing is blocked. See the event schema for the fields recorded.

Troubleshooting