Azure Database for PostgreSQL flexible server — Entra authentication, roles for managed identities, private access or private endpoints, versions and extended support, errors

Running PostgreSQL flexible server without passwords — authConfig for Entra only, Entra admins, pgaadauth_create_principal for apps and groups, tokens as passwords from Node.js pg, the two exclusive network modes (VNet integration with a delegated /28+ subnet and a .postgres.database.azure.com zone, or public access plus private endpoints), the automatic paid extended support for 11–13 since August 2026 and 14 from February 2027, and the login errors.

markdownreferencev1F35G-1NEWstage: buildtrust: officialservice: postgresqlinterface: iacinterface: cliinterface: sdkAzure Database for PostgreSQL flexible server Entra authenticationauthConfig activeDirectoryAuth passwordAuthMicrosoft Entra authentication only PostgreSQLaz postgres flexible-server microsoft-entra-admin create--microsoft-entra-auth--password-authflexibleServers/administratorspgaadauth_create_principalpgaadauth_create_principal_with_oidazure_pg_adminhttps://ossrdbms-aad.database.windows.net/.defaultoss-rdbms tokentoken as password 5 to 60 minutesNode pg password functionEntra group sync 30 minutesVNet integration delegated subnet Microsoft.DBforPostgreSQL/flexibleServersprivate DNS zone .postgres.database.azure.comprivatelink.postgres.database.azure.comprivate endpoint not supported VNet integrationAzureActiveDirectory service tagPostgreSQL extended supportPostgreSQL 11 12 13 extended support August 1 2026PostgreSQL 14 standard support end January 31 2027PostgreSQL 18FATAL: password authentication failed for userno pg_hba.conf entry for hostPGSSLMODE requireMicrosoft.DBforPostgreSQL/flexibleServers@2025-08-01

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

PostgreSQL flexible server

Entra authentication

  • authConfig: activeDirectoryAuth: 'Enabled' and passwordAuth: 'Disabled' for Entra only (CLI --microsoft-entra-auth Enabled --password-auth Disabled; the CLI defaults are the reverse). Enable it at creation or later.
  • Entra admins (users, groups, service principals or managed identities): one at provisioning, more afterwards; the resource is flexibleServers/administrators/<objectId> (az postgres flexible-server microsoft-entra-admin create -g <rg> -s <server> --display-name <name> --object-id <id> --type Group). Don't run the app as the admin: it has CREATEDB and elevated rights.
  • App roles: connected as an Entra admin to the postgres database:
SELECT * FROM pgaadauth_create_principal('<managed identity display name>', false, false);
-- or, when display names collide:
SELECT * FROM pgaadauth_create_principal_with_oid('<role name>', '<object id>', 'service', false, false);
GRANT CONNECT ON DATABASE appdb TO "<managed identity display name>";

Arguments: role name (UPN for users, display name for groups and service principals), isAdmin, isMfa. A role linked to a group lets every member sign in with the group's role name; group membership syncs every 30 minutes.

  • Tokens are the password: scope https://ossrdbms-aad.database.windows.net/.default (CLI: az account get-access-token --resource-type oss-rdbms), valid 5–60 minutes, checked at sign-in. Microsoft says that from January 2027 tokens for audiences other than ossrdbms won't be accepted.
  • With private access, allow outbound to the AzureActiveDirectory service tag, and keep login.microsoftonline.com and graph.microsoft.com resolving publicly, or admin assignment and sign-in fail.

Network: pick one mode at creation

Private access (VNet integration)Public access (+ private endpoints)
PlacementA subnet delegated to Microsoft.DBforPostgreSQL/flexibleServers, only for these servers, /28 or larger (an HA server uses 4 addresses)No subnet; firewall rules (none = no access) and/or private endpoints (groupId postgresqlServer, zone privatelink.postgres.database.azure.com)
DNSA private zone whose name ends in .postgres.database.azure.com and isn't the server's namePrivate endpoint zone group
ConstraintsCan't move to another VNet or subnet; subnet can't grow once used; no private endpoints; don't force all Storage traffic through an NVACLI --public-access 0.0.0.0 admits all Azure services

Versions

18 down to 11 are offered. 11, 12 and 13 have been in paid extended support since August 1, 2026 (billing from September 1, 2026; ends March 31, 2027, November 13, 2027 and November 12, 2028). 14's standard support ends January 31, 2027. Enrolment is automatic and charged only while a server runs; upgrade the major version to leave it.

Bicep (Entra only, private access)

// PostgreSQL flexible server: Microsoft Entra only, private (VNet-integrated), with an Entra admin group
param location string = resourceGroup().location
param serverName string
param delegatedSubnetId string // subnet delegated to Microsoft.DBforPostgreSQL/flexibleServers, /28 or larger
param privateDnsZoneId string // a zone ending in .postgres.database.azure.com, linked to the VNet
param adminGroupName string
param adminGroupObjectId string

resource pg 'Microsoft.DBforPostgreSQL/flexibleServers@2025-08-01' = {
  name: serverName
  location: location
  sku: {
    name: 'Standard_D4ds_v5'
    tier: 'GeneralPurpose'
  }
  properties: {
    version: '17'
    authConfig: {
      activeDirectoryAuth: 'Enabled'
      passwordAuth: 'Disabled' // Entra only; the hub's reading is that no administratorLogin is then needed
      tenantId: tenant().tenantId
    }
    network: {
      delegatedSubnetResourceId: delegatedSubnetId
      privateDnsZoneArmResourceId: privateDnsZoneId
    }
    storage: {
      storageSizeGB: 64
      autoGrow: 'Enabled'
    }
    highAvailability: {
      mode: 'ZoneRedundant'
    }
  }
}

resource entraAdmin 'Microsoft.DBforPostgreSQL/flexibleServers/administrators@2025-08-01' = {
  parent: pg
  name: adminGroupObjectId
  properties: {
    principalType: 'Group'
    principalName: adminGroupName
    tenantId: tenant().tenantId
  }
}

Node.js

import pg from "pg";
import { DefaultAzureCredential } from "@azure/identity";

const credential = new DefaultAzureCredential();
const SCOPE = "https://ossrdbms-aad.database.windows.net/.default"; // PostgreSQL and MySQL flexible servers

// The role must exist: SELECT * FROM pgaadauth_create_principal('<identity display name>', false, false);
export const pool = new pg.Pool({
  host: `${process.env.PG_SERVER}.postgres.database.azure.com`,
  database: "appdb",
  user: process.env.PG_USER ?? "", // the role name: UPN for users, display name for groups and identities
  // A function, so every new pooled connection gets a fresh token (tokens last 5–60 minutes)
  password: async () => (await credential.getToken(SCOPE)).token,
  ssl: { rejectUnauthorized: true },
  max: 10,
  idleTimeoutMillis: 30_000,
});

export async function main(): Promise<void> {
  const { rows } = await pool.query<{ now: Date }>("SELECT now() AS now");
  console.log(rows[0]?.now);
  await pool.end();
}

Read replicas, major version upgrades and elastic clusters: reference/postgresql/replicas-upgrades-and-clusters.md. Retired database services: reference/databases/retired-and-replacements.md.

Errors

MessageCause → fix
FATAL: password authentication failed for user "<user-name>"Wrong password; for Entra: expired or wrong-audience token, a user name that doesn't match the role exactly (case-sensitive), or no pgaadauth_create_principal role
FATAL: no pg_hba.conf entry for host "y.y.y.y", user "<user-name>", database "postgres", no encryption (right after the first error)libpq retried without TLS after the TLS attempt failed: set PGSSLMODE=require (or ssl in the client) so you see the real error
Deployment fails naming the private DNS zoneThe zone name equals the server name, or the zone's subscription lacks the Microsoft.DBforPostgreSQL provider registration
Timeouts from inside the VNetThe hub's reading: an NSG or UDR on the delegated subnet, or DNS not resolving through the linked zone (guides/networking/diagnose-connectivity.md)

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