Microsoft Entra ID authentication is enabled for PostgreSQL Flexible Server
PostgreSQL Flexible Servers must set authConfig.activeDirectoryAuth to Enabled and keep at least one Microsoft Entra administrator assigned so database sessions inherit centrally governed identities instead of unmanaged PostgreSQL accounts.
Risk
Without Entra ID authentication, stolen local passwords bypass MFA and conditional access, enabling persistent database logins. Missing administrators leaves the feature unusable, blocking security teams from rotating duties and allowing unauthorized access or privilege escalation.
Run this check with Prowler
Run in Prowler Cloudprowler azure --checks postgresql_flexible_server_entra_id_authentication_enabledRecommendation
Federate PostgreSQL Flexible Server access through Microsoft Entra ID so MFA, conditional access, and centralized RBAC govern logins. Maintain at least one delegated administrator group and rotate membership through identity governance processes.
Remediation
CLI
az postgres flexible-server update --resource-group <resourceGroupName> --name <serverName> --active-directory-auth Enabled
az postgres flexible-server ad-admin create --resource-group <resourceGroupName> --server-name <serverName> --object-id <objectId> --display-name <displayName> --type UserTerraform
data "azurerm_client_config" "current" {}
resource "azurerm_postgresql_flexible_server" "example" {
name = "pg-flex"
resource_group_name = azurerm_resource_group.example.name
location = azurerm_resource_group.example.location
sku_name = "GP_Standard_D4s_v3"
administrator_login = "pgadmin"
administrator_password = "<complexPassword>"
storage_mb = 131072
version = "16"
authentication {
active_directory_auth_enabled = true
tenant_id = data.azurerm_client_config.current.tenant_id
}
}
resource "azurerm_postgresql_flexible_server_active_directory_administrator" "entra_admin" {
server_id = azurerm_postgresql_flexible_server.example.id
object_id = var.entra_object_id
principal_name = var.entra_principal_name
principal_type = "User"
tenant_id = data.azurerm_client_config.current.tenant_id
}NativeIaC
// Enable Microsoft Entra ID authentication on an existing PostgreSQL Flexible Server
resource server 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' existing = {
name: '<example_resource_name>'
}
// Update server to enable Entra ID authentication
resource serverUpdate 'Microsoft.DBforPostgreSQL/flexibleServers@2022-12-01' = {
name: server.name
location: server.location
properties: {
authConfig: {
activeDirectoryAuth: 'Enabled' // CRITICAL: Enables Entra ID authentication
tenantId: tenant().tenantId
}
}
}
// Add Entra ID administrator
resource entraAdmin 'Microsoft.DBforPostgreSQL/flexibleServers/administrators@2023-12-01-preview' = {
parent: server
name: '<objectId>' // CRITICAL: Object ID of the Entra ID principal
properties: {
principalName: '<displayName>' // User principal name or group display name
principalType: 'User' // CRITICAL: Can be 'User', 'Group', or 'ServicePrincipal'
tenantId: tenant().tenantId
}
dependsOn: [
serverUpdate
]
}Other
Check Code
from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.postgresql.postgresql_client import (
postgresql_client,
)
class postgresql_flexible_server_entra_id_authentication_enabled(Check):
def execute(self) -> Check_Report_Azure:
findings = []
for (
subscription,
flexible_servers,
) in postgresql_client.flexible_servers.items():
subscription_name = postgresql_client.subscriptions.get(
subscription, subscription
)
for server in flexible_servers:
report = Check_Report_Azure(metadata=self.metadata(), resource=server)
report.subscription = subscription
# Default to FAIL
report.status = "FAIL"
# Check if Entra ID authentication is enabled
# Note: active_directory_auth is already normalized to uppercase in service layer
if (
not server.active_directory_auth
or server.active_directory_auth != "ENABLED"
):
report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription_name} ({subscription}) has Microsoft Entra ID authentication disabled"
else:
# Authentication is enabled, now check for admins
admin_count = (
len(server.entra_id_admins) if server.entra_id_admins else 0
)
if admin_count == 0:
report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription_name} ({subscription}) has Microsoft Entra ID authentication enabled but no Entra ID administrators configured"
else:
report.status = "PASS"
admin_text = (
"administrator" if admin_count == 1 else "administrators"
)
report.status_extended = f"Flexible Postgresql server {server.name} from subscription {subscription_name} ({subscription}) has Microsoft Entra ID authentication enabled with {admin_count} {admin_text} configured"
findings.append(report)
return findings