Share via

Create Self Service AI using Azure Foundry with user token monitoring and limit

Stavros Koureas 16 Reputation points
2026-06-17T15:04:03.5533333+00:00

There is the need to have a process where a user requests access for AI usage, we as administrators approve requests, the users get the api keys, be aware of available APIs and configure them within AI Tools.

The only close way to do this seems to be Azure API Management Service connected with Azure Foundry (aka AI Gateway). There we can define the available APIs like completions, responses, messages, etc and configure polices.

One challenge is that in order this to work the Client should sent the subscription key either via Header or via Query parameter while the Subscription required is set to true.

APIM

This works nice from Postman by sending the subscription key as header Ocp-Apim-Subscription-Key, or as header api-key as long it matches with the configuration in APIM.

But there are some AI Tools like VSCode which emmit the Header as "Authorization" and even this matches with configuration in APIM, it would be unable to parse the key as the Header "Authorization" is combination of "Bearer" and the key, like the below:

Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

So I tried tone of ways like building an inbound policy like the below, which extracts the key even from "Authorization" header from the part after the Bearer, or from "api-key" header or from "Ocp-Apim-Subscription-Key" header. Then I try to override the Ocp-Apim-Subscription-Key as I need the APIM update the context.Subscription?.Key, but this does not happen.

        <set-variable name="clientKey" value="@{
                var auth = context.Request.Headers.GetValueOrDefault("Authorization", "");
                if (auth.StartsWith("Bearer ")) {
                    var token = auth.Substring(7).Trim();
                    if (token != "") { return token; }
                }

                var apiKey = context.Request.Headers.GetValueOrDefault("api-key", "").Trim();
                if (apiKey != "") { return apiKey; }

                var subKey = context.Request.Headers.GetValueOrDefault("Ocp-Apim-Subscription-Key", "").Trim();
                if (subKey != "") { return subKey; }

                return "";
            }" />
        <set-header name="Ocp-Apim-Subscription-Key" exists-action="override">
            <value>@((string)context.Variables["clientKey"])</value>
        </set-header>

So for debugging purposes, if we use the below outbound policy, we will see that the clientKey is populated

<return-response>
	<set-status code="200" reason="DEBUG" />
	<set-body>@((string)context.Variables["clientKey"])</set-body>
</return-response>

But if we use the below outbound policy, we will see that the context.Subscription is null

<return-response>
	<set-status code="200" reason="DEBUG" />
	<set-body>
	   @{ return "Subscription Key=" + (context.Subscription?.Key); }
	</set-body>
</return-response>

So it seems that the evaluation of context.Subscription happends before and does not re-evaluated.
As a result apps like VSCode GitHub Copilot will be unable to be validated properly and also monitored.

The policy works to extract subscription key and use it for example to limit the tokens per subscription based on another policy on this variable but it does not contribute into APIMs internal mechanism.

APIM2

Any idea?

Azure API Management
Azure API Management

An Azure service that provides a hybrid, multi-cloud management platform for APIs.


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.