Most AI apps start with an API key, because it is the quickest way to get a first answer from a model. But a key gives full access to the resource and can't be limited to one user or one action. Nobody can tell from the logs who used it.
That's why every app and every person should get only the role they need on your AI resources, with API keys turned off.
| Who | Microsoft Foundry resource | Azure OpenAI resource |
|---|---|---|
| The app, and developers who call the model | Foundry User | Cognitive Services OpenAI User |
| A client that only calls a published agent | Foundry Agent Consumer | - |
| The few people who deploy models | Foundry Account Owner | Cognitive Services OpenAI Contributor |
Figure: The built-in roles to reach for first
Search Index Data Reader| Identity | Access | On |
|---|---|---|
| northwind-api (the app) | API key in app settings | northwind-ai |
| Northwind Developers | Contributor | Northwind.Production |
❌ Figure: Bad example - The app holds a key with full access, and every developer can deploy models and change the whole resource group
| Identity | Access | On |
|---|---|---|
| northwind-api (managed identity) | Foundry User | northwind-ai |
| Northwind Developers | Foundry User | northwind-ai, project northwind-chat |
| Bob Northwind (Tech Lead) | Foundry Account Owner | northwind-ai |
| API keys | Disabled | northwind-ai |
✅ Figure: Good example - Each identity can do its own job and nothing more
Roles only apply when you sign in with Microsoft Entra ID. While keys are on, anyone holding a key skips them. Give the app a managed identity, then turn key access off.
// Foundry or Azure OpenAI resource (Microsoft.CognitiveServices/accounts)properties: {disableLocalAuth: true}
✅ Figure: Good example - Key access is off, so every call needs an identity with a role
Note: Turning keys off is not instant. It usually takes a few minutes and can take several hours, so test with the old key before you rely on it.