App to a database with a managed identity — Azure SQL, Cosmos DB, PostgreSQL, MySQL and Managed Redis side by side

The keyless handoff from an Azure-hosted app to each managed database — what turns the app's managed identity into a database principal (CREATE USER FROM EXTERNAL PROVIDER, a Cosmos sqlRoleAssignment, pgaadauth_create_principal, CREATE AADUSER, a Redis access policy assignment), the token scope, the switch that turns passwords or keys off, the private DNS zone — and the known-bad configurations with the error each produces and which side is wrong.

markdownpatternv1SF89-S31Ystage: buildtrust: officialservice: sqlservice: cosmos-dbservice: postgresqlservice: mysqlservice: redisservice: managed-identityinterface: iacinterface: sdkmanaged identity databasepasswordless database Azurewhich Azure role for database data accessAzure SQL managed identity userCosmos DB managed identity data rolePostgreSQL managed identity roleMySQL managed identity AADUSERRedis managed identity access policytoken scope database.windows.netcosmos.azure.comossrdbms-aad.database.windows.netredis.azure.comOwner can't read database datadisplay name mismatch database useruser-assigned identity client ID database

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

App to a database with a managed identity

None of these databases reads Azure RBAC for data. Owner or Contributor on the resource manages it; reading rows, items or keys needs a principal inside the database's own permission system. Use a user-assigned identity so the database principal survives redeploys, and pass its client ID to ManagedIdentityCredential (or AZURE_CLIENT_ID for DefaultAzureCredential).

Known-good

DatabaseMake the identity a principalToken scope (SDKs request it)Keys or passwords offPrivate DNS zone
Azure SQLCREATE USER [<identity name>] FROM EXTERNAL PROVIDER; in the app database, then roles. The server identity needs Graph read permissionshttps://database.windows.net/.defaultEntra-only authenticationprivatelink.database.windows.net
Cosmos DB for NoSQLsqlRoleAssignments with Built-in Data Contributor (…0002) at / or /dbs/<db><account endpoint>/.default (fallback https://cosmos.azure.com/.default)disableLocalAuth: trueprivatelink.documents.azure.com
PostgreSQL flexiblepgaadauth_create_principal('<identity name>', false, false) as an Entra admin, then GRANThttps://ossrdbms-aad.database.windows.net/.defaultauthConfig.passwordAuth: 'Disabled'Private access: a zone ending .postgres.database.azure.com; endpoints: privatelink.postgres.database.azure.com
MySQL flexibleCREATE AADUSER '<identity name>'; as the Entra admin, then GRANT. The server needs a user-assigned identity with Graph permissionshttps://ossrdbms-aad.database.windows.net/.default (cleartext plugin)aad_auth_only = ONprivatelink.mysql.database.azure.com
Azure Managed RedisaccessPolicyAssignments with accessPolicyName: 'default' and the identity's object IDhttps://redis.azure.com/.defaultaccessKeysAuthentication: 'Disabled'privatelink.redis.azure.net

TypeScript for each: guides/sql/connect-from-typescript.md, reference/cosmos-db/errors.md, reference/postgresql/flexible-server.md, reference/mysql/flexible-server.md, reference/redis/managed-redis.md.

Known-bad

ConfigurationWhat you seeWrong side
Only an Azure role (even Owner) on the database resourceSQL 18456; Cosmos 403 does not have required RBAC permissions; PostgreSQL password authentication failed; Redis auth failureDatabase: no principal
SQL user created in master instead of the app database4060 or 18456Database
Name in CREATE USER / pgaadauth_create_principal doesn't match the identity (a different identity's name, wrong case)Login failsDatabase
System-assigned identity recreated with the appWorked yesterday, 18456 today: new object IDIdentity choice
DefaultAzureCredential on a host with several identities and no AZURE_CLIENT_IDToken for the wrong identityApp
Cosmos role assigned with az role assignment createStill 403Identity: wrong permission system
App creates Cosmos containers at start-up with an Entra token403 substatus 5300App: do it in Bicep
PostgreSQL client without TLS settingsno pg_hba.conf entry … no encryption hides the real errorApp
MySQL client without the cleartext pluginLogin fails although the token is validApp
Redis groups in the user list, or a token never refreshedGroups aren't supported; connections drop when the token expiresDatabase / app
Keys disabled before every client switchedOld clients fail at once (Redis drops all connections when the setting changes)Rollout order
Private endpoint without its zone linked to the app's VNetSQL 47073, Cosmos 403 path message, timeoutsNetwork (reference/networking/private-endpoints-and-dns.md)

Read this document as markdown — the same bytes an agent receives.