This issue has been assessed as high severity. Review affected configurations immediately.
Azure AI services have scaled from experimental APIs to core enterprise infrastructure in under two years. Azure OpenAI alone now underpins productivity tooling, customer service platforms, and internal knowledge retrieval systems across thousands of organisations. The security configuration posture of these services hasn’t kept pace with the deployment rate.
CVE-2026-45499, patched in Microsoft’s July 2026 Patch Tuesday with a CVSS score of 9.9, highlighted a specific risk: SSRF within the Azure OpenAI API surface that enabled privilege escalation within the service. Microsoft cloud-mitigated the fix, but the vulnerability class — service endpoints with broad internal network reach — is inherent to how AI APIs are architectured. This guide covers the misconfiguration patterns that create exploitable conditions, and the remediation steps for each.
Misconfiguration 1: Key-Based Authentication Enabled
Azure OpenAI and AI Search support two authentication modes: API keys and Microsoft Entra ID (formerly Azure AD) identity-based authentication. API keys are enabled by default and are static, shared credentials that provide full access to the service.
The problem with key-based authentication is operational: keys get embedded in application config files, committed to repositories, included in Docker images, and shared across teams. They don’t rotate automatically and they don’t carry the contextual access controls that Entra ID-based authentication supports.
Check for key-based auth being the only method:
# List Azure OpenAI accounts with key auth status
az cognitiveservices account list \
--query "[?kind=='OpenAI'].{Name:name, RG:resourceGroup, KeyAuth:properties.disableLocalAuth}" \
--output table
disableLocalAuth: false (or null) means key-based authentication is currently enabled. Setting it to true enforces Entra ID-only access.
Disable key-based auth and enforce managed identity:
az cognitiveservices account update \
--name <your-aoai-resource> \
--resource-group <rg> \
--custom-headers "Content-Type=application/json" \
--set properties.disableLocalAuth=true
For AI Search, the equivalent:
az search service update \
--name <search-service> \
--resource-group <rg> \
--disable-local-auth true
For applications accessing Azure OpenAI, replace key-based auth with a system-assigned managed identity and assign the Cognitive Services OpenAI User role:
# Assign role to the calling app's managed identity
az role assignment create \
--assignee <managed-identity-object-id> \
--role "Cognitive Services OpenAI User" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.CognitiveServices/accounts/<aoai-name>
Misconfiguration 2: Public Endpoint Without Network Restriction
By default, Azure AI services expose a public endpoint accessible from any IP address. For development this is convenient; for production this means your AI service API is reachable from the internet by anyone with credentials (or who has found a way to bypass them, as SSRF vulnerabilities demonstrate).
Check for publicly accessible AI services:
# Check Azure OpenAI network ACL - should show Deny as default action
az cognitiveservices account show \
--name <aoai-resource> \
--resource-group <rg> \
--query "properties.networkAcls" \
--output json
A defaultAction: Allow with no IP rules means the endpoint is unrestricted.
Restrict to private endpoint or specific IP ranges:
For enterprise deployments, private endpoints are the correct control — they remove the service from public address space entirely:
# Create private endpoint for Azure OpenAI
az network private-endpoint create \
--name aoai-pe \
--resource-group <rg> \
--vnet-name <vnet> \
--subnet <subnet> \
--private-connection-resource-id $(az cognitiveservices account show --name <aoai-resource> --resource-group <rg> --query id -o tsv) \
--group-id account \
--connection-name aoai-connection
Once a private endpoint exists, disable public network access:
az cognitiveservices account update \
--name <aoai-resource> \
--resource-group <rg> \
--public-network-access Disabled
Misconfiguration 3: Overly Permissive RBAC
Azure AI services have several built-in roles. The misconfiguration pattern is assigning Cognitive Services Contributor or Owner at the resource group or subscription scope when Cognitive Services OpenAI User at the resource scope is sufficient.
Cognitive Services Contributor can rotate API keys, export models, and modify service configuration. An attacker who compromises an identity with this role can extract or rotate credentials, pivot to model fine-tuning endpoints, and modify the service in ways that affect downstream consumers.
Audit current role assignments:
# List all role assignments scoped to Azure OpenAI resources
az role assignment list \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.CognitiveServices/accounts/<aoai-name> \
--include-inherited \
--query "[].{Principal:principalName, Role:roleDefinitionName, PrincipalType:principalType}" \
--output table
Investigate any Owner, Contributor, or Cognitive Services Contributor assignments that should only be querying the API. Least-privilege mapping:
| Use case | Correct role |
|---|---|
| Call API (inference only) | Cognitive Services OpenAI User |
| Deploy models, manage deployments | Cognitive Services OpenAI Contributor |
| Manage service configuration, keys | Cognitive Services Contributor (admin only) |
Misconfiguration 4: AI Search with Semantic Ranker and Unrestricted Data Sources
Azure AI Search with semantic ranking often indexes sensitive enterprise data — SharePoint libraries, Cosmos DB collections, SQL databases. The security misconfiguration here is a poorly scoped indexer that pulls data the calling application shouldn’t have access to, then serves it via the API to any authenticated consumer.
The attack path: an attacker or compromised identity queries the AI Search API with carefully constructed queries targeting data the calling user shouldn’t be able to retrieve. The semantic ranking model surfaces relevant results from indexed data that the calling application’s permissions model wasn’t designed to restrict.
Audit indexer data sources and their scope:
# List all indexers and their data sources in Azure AI Search
az search indexer list \
--service-name <search-service> \
--resource-group <rg> \
--query "[].{Name:name, DataSource:dataSourceName, Schedule:schedule}" \
--output table
Review each data source connection string for scope. Indexers connecting with admin-level database credentials to entire databases or storage accounts are a data exposure risk — they should connect with read-only credentials scoped to the specific tables or containers the search index requires.
Misconfiguration 5: Content Safety and Prompt Shield Disabled
Azure OpenAI provides Content Safety filtering and Prompt Shield (prompt injection detection) as configurable controls. Disabling these for performance reasons — a common developer optimisation — removes the primary protection against prompt injection attacks where external data passed to the model contains adversarial instructions.
For applications that pass untrusted data to Azure OpenAI (document Q&A, web scraping pipelines, customer input), disabling content safety controls means prompt injection attacks can manipulate the model’s output, potentially exfiltrating context data or causing the model to produce harmful outputs on behalf of an attacker.
Check content safety configuration via Azure AI Foundry:
# Show content filter policy applied to a deployment
az cognitiveservices account deployment show \
--name <aoai-resource> \
--resource-group <rg> \
--deployment-name <deployment-name> \
--query "properties.model.contentFilterPolicy" \
--output json
Applications processing untrusted input should use the strictest content filter policy available and enable Prompt Shield explicitly in their API call headers: "api-key-use-type": "content-safety".
Azure Policy for Baseline Enforcement
For organisations with multiple Azure AI service instances, Azure Policy provides centralised enforcement of these controls:
{
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.CognitiveServices/accounts"
},
{
"field": "Microsoft.CognitiveServices/accounts/properties.disableLocalAuth",
"notEquals": true
}
]
},
"then": {
"effect": "Deny"
}
}
Microsoft’s Azure Security Benchmark policy initiative includes definitions for Cognitive Services including [Preview]: Cognitive Services accounts should disable local authentication methods. Assigning this built-in policy at the subscription level prevents new deployments with key auth enabled and flags non-compliant existing resources for remediation.
Detection: Unusual Azure OpenAI API Usage
Microsoft Defender for Cloud generates alerts on Azure AI services for anomalous API patterns. Enable Defender for AI (preview in 2026) to surface:
- Jailbreak attempt alerts via prompt analysis
- Sensitive data detected in model responses
- Credential enumeration patterns on the API endpoint
Beyond Defender, forward Azure OpenAI diagnostic logs (Audit, RequestResponse) to Log Analytics and alert on:
AzureDiagnostics
| where ResourceType == "COGNITIVESERVICES/ACCOUNTS"
| where OperationName == "Azure.CognitiveServices.ModelProbeRequestPost"
| where StatusCode !in ("200", "201")
| summarize FailureCount = count() by CallerIPAddress, tostring(CorrelationId)
| where FailureCount > 50
| sort by FailureCount desc
High failure rates from a single caller IP against the inference endpoint suggest credential testing or automated probing. A burst of 4xx responses from an unfamiliar IP warrants immediate key rotation.