Skip to main content
emnode
Compliance Medium severity MCSB IM-1

Microsoft Defender for Cloud · Azure Database for PostgreSQL

Azure Database for PostgreSQL should have a Microsoft Entra administrator provisioned

Written and reviewed by Emnode · Last reviewed

What does the recommendation "Azure Database for PostgreSQL should have a Microsoft Entra administrator provisioned" check?

Flags any Azure Database for PostgreSQL server that has no Microsoft Entra administrator assigned, which means the instance can only be reached through native PostgreSQL password logins. It verifies that an Entra principal, which can be a user, a group, or a service principal, is provisioned as administrator so that Entra ID authentication is available on the server. The check is narrow on purpose: it does not confirm that Entra-only authentication is enforced, it does not check whether individual database roles have been mapped to Entra identities, and it ignores password complexity, TLS settings, and firewall rules, all of which are governed by separate controls. The administrator is a single account at the server level, not a per-database grant, so one assignment satisfies the recommendation for every database that server hosts. The historical control covered single servers, but that tier was retired on 28 March 2025, so in practice this now applies to the flexible server tier, where the administrator setting lives on the authConfig of the Microsoft.DBforPostgreSQL/flexibleServers resource.

Why does "Azure Database for PostgreSQL should have a Microsoft Entra administrator provisioned" matter?

Without an Entra administrator the database falls back to local PostgreSQL accounts whose passwords sit entirely outside your identity platform: they cannot be governed by conditional access, multi-factor authentication, or the central joiner, mover, and leaver processes that protect every other system. A shared admin credential then tends to outlive the person who created it, gets pasted into deployment scripts, and is rarely rotated. That gap is exactly how a leaked connection string or an orphaned service account turns into unaudited, standing access to production data, the kind of finding that escalates a routine breach into a reportable one. Provisioning an Entra administrator lets you centralise authentication, revoke access the moment someone leaves, require MFA at the directory, and tie every privileged login back to a named identity, which is what auditors and incident responders expect to see for a system that holds customer records.

How do I fix "Azure Database for PostgreSQL should have a Microsoft Entra administrator provisioned"?

  1. Enable Entra authentication on the server: set authConfig.activeDirectoryAuth to 'Enabled' on the Microsoft.DBforPostgreSQL/flexibleServers resource (Security then Authentication in the portal), keeping password auth on during migration if you still need it.
  2. Provision the administrator with the CLI, choosing a group rather than a single user so access stays manageable: az postgres flexible-server ad-admin create --resource-group <rg> --server-name <server> --display-name '<group name>' --object-id <entra-object-id> --type Group.
  3. To make this the default for new estates, assign the built-in audit policy by exact display name rather than a hardcoded GUID: pid=$(az policy definition list --query "[?displayName=='A Microsoft Entra administrator should be provisioned for PostgreSQL flexible servers'].name" -o tsv); az policy assignment create --name pg-entra-admin --policy "$pid" --scope <scope>.

Remediation script · bash

# 1. Lock the wire and the network on a production PostgreSQL flexible server.
RG=db-prod-rg
SRV=ordersprod-pg

# Enforce encrypted connections (dynamic, no restart needed).
az postgres flexible-server parameter set \
  --resource-group "$RG" --server-name "$SRV" \
  --source user-override \
  --name require_secure_transport --value ON

# Pin the minimum TLS version.
az postgres flexible-server parameter set \
  --resource-group "$RG" --server-name "$SRV" \
  --source user-override \
  --name ssl_min_protocol_version --value TLSv1.2

# Disable public network access.
az postgres flexible-server update \
  --resource-group "$RG" --name "$SRV" \
  --public-access Disabled

# 2. Turn on the pgaudit trail and connection throttling.
for p in "pgaudit.log=role,ddl,misc" \
         "pgaudit.log_client=ON" \
         "pgaudit.log_level=log" \
         "pgaudit.log_statement=on" \
         "pgaudit.log_statement_once=on" \
         "connection_throttle.enable=on"; do
  az postgres flexible-server parameter set \
    --resource-group "$RG" --server-name "$SRV" \
    --source user-override \
    --name "${p%%=*}" --value "${p#*=}"
done

# 3. Provision a Microsoft Entra administrator and disable password sign-in.
az postgres flexible-server ad-admin create \
  --resource-group "$RG" --server-name "$SRV" \
  --display-name "dba-team" \
  --object-id "$(az ad group show --group dba-team --query id -o tsv)" \
  --type Group
az postgres flexible-server update \
  --resource-group "$RG" --name "$SRV" \
  --microsoft-entra-auth Enabled --password-auth Disabled

# 4. Ratchet it shut: deny any future PostgreSQL flexible server with public access.
# Look the built-in policy up by its EXACT display name, never paste a guessed GUID.
PID=$(az policy definition list \
  --query "[?displayName=='Public network access should be disabled for PostgreSQL flexible servers'].name" \
  -o tsv)
az policy assignment create \
  --name deny-public-pg-flex \
  --policy "$PID" \
  --params '{"effect":{"value":"Deny"}}' \
  --scope "/subscriptions/00000000-0000-0000-0000-000000000000"

Full walkthrough (console steps, edge cases and verification) in the lesson Harden Azure MySQL and PostgreSQL.

Is "Azure Database for PostgreSQL should have a Microsoft Entra administrator provisioned" a false positive?

A flexible server that is being decommissioned or only ever holds non-sensitive scratch data may legitimately run without an Entra administrator while you migrate it off. Document the exception and scope it with a policy exemption on that resource rather than disabling the assignment estate-wide, so every other server keeps the requirement.