Chapter 6 of 6
Confirm the result#
Intended-path check#
With the same assigned user and model, send one small non-sensitive prompt from Code and one from Desktop. Confirm both return a streaming response and the gateway trace names the expected user, deployment, and request ID. Check that the claude-monthly:<upn>:<model> budget is shared across clients; use the returned quota headers through the approved diagnostic view. The remaining value is an estimate, so compare after both requests complete.
Use this body-free query in the connected Log Analytics workspace:
AppTraces
| where TimeGenerated > ago(30m)
| where Message == "Authenticated inference request"
| project TimeGenerated,
callerUpn = tostring(Properties.callerUpn),
tenantId = tostring(Properties.tenantId),
objectId = tostring(Properties.objectId),
requestId = tostring(Properties.requestId),
model = tostring(Properties.requestedModel)
Confirm the selected deployments also respond through count_tokens. A streaming response must arrive incrementally through its final message_delta and message_stop events. Observe normal token renewal during a pilot: Code must rerun the helper, and Desktop must refresh or request sign-in according to the tenant's session policy.
Blocked-path check#
Using the same approved nonproduction route, call Messages with no credential and a token issued for a different audience. Expect 401 and no Foundry invocation. An assigned user requesting a model absent from the budget map receives 403; malformed model JSON receives 400. Confirm an unassigned Desktop user cannot sign in to its Enterprise application.
If WAF is required, call APIM directly from outside the approved gateway path: the network control must reject it. Confirm a representative code prompt still passes through the WAF listener.
Delivery-owner checkpoint#
The delivery owner observes both clients succeeding and the blocked path before authorizing a wider device rollout. Stop if streaming is buffered, claims differ from the approved contract, telemetry contains payloads, or WAF can be bypassed. Resolve the failed hop before expanding the cohort.
| Symptom | Inspect |
|---|---|
| 401 | Token version, issuer, audience, scope, role, or helper failure |
| 403 | Missing UPN, zero/unmapped budget, or exhausted monthly quota |
| 400 on a new feature | Beta header and paired body fields across proxies |
| 404 | API suffix and exact Foundry deployment name |
| Response arrives at once | APIM forwarding and upstream proxy buffering |
| WAF rejects code | Matched rule, body size, and narrow false-positive exclusion |
After implementation#
The gateway owner operates the API, budget fragment, backend identity, and body-free diagnostics. The identity owner manages assignments and token contracts. The client owner maintains the exported Desktop profile and Code settings. Budget changes use the approved APIM policy change path and are checked against the effective policy.
Connect attribution and budget alerts to Session 11. Reconcile token usage against Marketplace charges. Review quota-denial and authentication-failure rates, and recheck protocol compatibility after client or WAF ruleset upgrades.
To restore, the gateway owner reinstates the prior API policy, operations, and diagnostics from the approved change store. The client owner restores the prior managed settings through MDM. Restoring a policy does not restore a consumed quota counter.
To retire, first remove this route from managed clients and disable its API. Check the optional-module-claude-foundry-ai-gateway change marker and exact scope in the customer record. Remove the module-owned API and fragment only after confirming no other API uses the fragment or backend. The identity owner removes only this route's assignments and consent; the role owner removes the APIM Foundry role only when no remaining workload needs it. Keep the shared APIM, Foundry deployments, WAF, and telemetry resources.
This gateway controls inference through this route. It does not prevent users with independent credentials from calling another provider, and it does not govern Code or Desktop's local tools. Direct-egress features such as fast-mode checks need a separate network decision.