Skip to main content
Azure API Management (APIM) is Microsoft’s managed API gateway. Its XML policy chain applies authentication, subscription keys, rate limits, and message rewrites on the inbound and outbound paths. When APIM fronts a model endpoint, those paths carry prompts and completions. This integration evaluates traffic for AI APIs published through APIM without changing application code. It does not cover direct access to third-party AI tools or expose individual shell commands and tool calls from an agent.

Integration capabilities

Before you start

Start with the policy in Observe mode. Findings appear in Activity without affecting traffic. Switch to Enforce after reviewing the results. See Policies.

1. Create the collector and API key

  1. Open Runtime → Collectors → Catalog → Gateway → Azure APIM and add the collector.
  2. On the Auth tab, create an API key. The raw tgk_… secret is shown only once, so store it before closing the panel.
  3. On the Policies tab, assign the policy that evaluates this collector’s traffic. A collector with no matching policy returns allow with no findings. See Collectors.

2. Screen the prompt on inbound

send-request with mode="new" builds a fresh call to POST /v1/evaluate and stores the response in a context variable. The <choose> block enforces the verdict: 403 on block and a body rewrite on transform.
preserveContent: true is not optional. Without it the policy consumes the request body and your backend receives an empty request. The same applies to context.Response.Body on the outbound side.

3. Screen the completion on outbound

Deploying step 2 alone evaluates prompts but not completions, so Output-phase rules do not run. Add a second send-request to <outbound>, set direction to output, and read context.Response.Body.
A guarded turn is therefore two evaluations, one per direction, carrying the same session_id.

4. Verify

Use a prompt that your policy should stop:
  1. Call the API with it.
  2. Expect 403 Blocked by TrustGuard in Enforce mode, or a normal response with a finding recorded in Observe mode.
  3. Confirm the event in TrustGuard Activity, under the APIM subscription id as consumer_id.
  4. Send a request that passes and confirm two events for the turn: one input and one output. A single event means the outbound policy is missing or is still sending direction: "input".

Reference

Coverage

The inbound policy applies transformed_payload.input, so it supports input redaction. The outbound sample handles block only and does not redact model output. It also does not buffer streamed completions or expose individual tool events. An ask verdict is recorded and allowed because APIM cannot prompt a user.

What is evaluated

Both sections call POST /v1/evaluate with the collector tgk_… key, and the policy’s detectors decide the verdict. direction selects which detector phase runs, so an Output-phase rule never fires on a call that sends input. TrustGuard returns 200 for every successful evaluation, including a block verdict. The APIM policy returns the 403. The complete serialized body, including the provider envelope, is sent as payload.input. TrustGuard also accepts a full provider body directly; the documented policy does not parse one out.

Configuration

The sample does not define fail-open or fail-closed behavior. If the evaluation times out or errors, no branch in <choose> handles the missing verdict. Before enabling Enforce, add a branch that either passes the request or returns a 5xx. Scope. Attach the policy at the global, product, API, or operation scope. At API scope, it covers every operation on that API. Per-operation policies must be maintained separately.

Attributes

The documented policy sends two identifying fields, plus the two routing fields:
  • consumer_id: context.Subscription?.Id, or "" when the API needs no subscription. Gates match it as consumer.id, and per-consumer policy overrides key on it.
  • session_id: the X-Session-Id request header, or "" when the caller does not send one. Use a stable, verified ID rather than the empty default when you need reliable conversation grouping.
  • protocol is always llm; direction is whichever section made the call.
For additional gate conditions, such as model.name, source.application, or a consumer tag, add an attributes object to the serialized body. See the evaluate API.

Troubleshooting