Repository navigation
Configure tokenLimit and contentSafety policies on AI Gateway models and MCP ToolServer #28
Description
Summary
Restore first-class AI Gateway policies (tokenLimit and contentSafety) on catalog models and contentSafety policy on the GitHub MCP ToolServer for the standalone RP (Microsoft.ApiManagement/aigateways@2025-09-01-preview).
Verified Live RP Wire Contract (Microsoft.ApiManagement/aigateways@2025-09-01-preview)
Both workspaces/default/modelProviders/foundry/models/{model} and workspaces/default/toolServers/github accept properties.policies on PUT:
-
Model Policies (
Microsoft.ApiManagement/aigateways/workspaces/modelProviders/models@2025-09-01-preview)tokenLimitrequirescounterKeyas an array (['identity']), not a string ('Identity'fails withValidationError: Invalid field 'counterKey' specified).contentSafetysetshateSeverity,selfHarmSeverity,sexualSeverity, andviolenceSeverityto'Medium'(or configurable viamodel.?contentSafetySeverity ?? 'Medium').
policies: model.?policies ?? [ { type: 'tokenLimit' period: 'minute' count: model.?tokenLimit ?? 10000 counterKey: [ 'identity' ] } { type: 'contentSafety' hateSeverity: model.?contentSafetySeverity ?? 'Medium' selfHarmSeverity: model.?contentSafetySeverity ?? 'Medium' sexualSeverity: model.?contentSafetySeverity ?? 'Medium' violenceSeverity: model.?contentSafetySeverity ?? 'Medium' } ]
-
Root
infra/main.bicepModel Policy Inputs- In
infra/main.bicep, passtokenLimit: deployment.capacity * 1000(so20000TPM forgpt-latestandgpt-6-sol, and200000TPM forgpt-mini-latest) andcontentSafetySeverity: 'Medium'into each entry offoundryModels.
- In
-
MCP ToolServer Content Safety Policy (
toolServers/github)Microsoft.ApiManagement/aigateways/workspaces/toolServers@2025-09-01-previewacceptsproperties.policies:"policies": [ { "type": "contentSafety", "hateSeverity": "Medium", "selfHarmSeverity": "Medium", "sexualSeverity": "Medium", "violenceSeverity": "Medium" } ]
- Because
infra/scripts/configure-ai-gateway.shandinfra/scripts/configure-ai-gateway.ps1perform aPUTonworkspaces/default/toolServers/githubduringpostprovisionto inject the read-only GitHub MCP credential, include thispoliciesarray in thetool_server_body/$toolServerBodyin bothinfra/scripts/configure-ai-gateway.shandinfra/scripts/configure-ai-gateway.ps1.
Files to Update
infra/ai-gateway/main.bicep:- Add
policiesdefault (tokenLimitwithcounterKey: ['identity']andcontentSafetywith'Medium'severities) onfoundryCatalogModels.
- Add
infra/main.bicep:- Pass
tokenLimit: deployment.capacity * 1000on each entry infoundryModels.
- Pass
infra/scripts/configure-ai-gateway.sh&infra/scripts/configure-ai-gateway.ps1:- Include
"policies": [{"type": "contentSafety", "hateSeverity": "Medium", "selfHarmSeverity": "Medium", "sexualSeverity": "Medium", "violenceSeverity": "Medium"}]in thePUTpayload fortoolServers/github.
- Include
tests/test-ai-gateway-model-registration.sh&tests/test-apim-lifecycle.sh:- Update
tests/test-ai-gateway-model-registration.sh(which previously assertedactual_model_policies == "null") to assert thatfoundryCatalogModelsincludes bothtokenLimit(counterKey: ["identity"],period: "minute") andcontentSafety(Mediumseverities), and thatinfra/main.biceppassestokenLimit(mul(variables('gatewayModelDeployments')[copyIndex()].capacity, 1000)). - Add assertions in
tests/test-apim-lifecycle.shverifying thatconfigure-ai-gateway.shandconfigure-ai-gateway.ps1include thecontentSafetypolicy ontoolServers/github.
- Update
README.md/IMPLEMENTATION_NOTES.md:- Ensure documentation reflects that
tokenLimit(scaled to deployment capacity) andcontentSafety(Medium) policies are configured on models andcontentSafety(Medium) is configured on the GitHub MCP ToolServer.
- Ensure documentation reflects that
Additional Requirement: Add Monthly Cost Limit (costLimit) Policy on Models
Also include a default $10.00 / month per caller identity costLimit policy on each catalog model in infra/ai-gateway/main.bicep (verified against the live Microsoft.ApiManagement/aigateways@2025-09-01-preview RP):
policies: model.?policies ?? [
{
type: 'tokenLimit'
period: 'minute'
count: model.?tokenLimit ?? 10000
counterKey: [
'identity'
]
}
{
id: 'monthly-caller-budget'
type: 'costLimit'
period: 'month'
amount: model.?costLimit ?? 10
counterKey: [
'identity'
]
}
{
type: 'contentSafety'
hateSeverity: model.?contentSafetySeverity ?? 'Medium'
selfHarmSeverity: model.?contentSafetySeverity ?? 'Medium'
sexualSeverity: model.?contentSafetySeverity ?? 'Medium'
violenceSeverity: model.?contentSafetySeverity ?? 'Medium'
}
]- Note:
costLimit.idis required by the live RP ("id": "monthly-caller-budget"),periodis'month',amountis10(ormodel.?costLimit ?? 10), andcounterKeyis['identity']. - Pass
costLimit: 10(or a root parametermodelMonthlyCostLimit int = 10) ininfra/main.bicepfor each entry infoundryModels, and assertcostLimitintests/test-ai-gateway-model-registration.shas well.
Activity