Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clojure/deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
com.mysql/mysql-connector-j {:mvn/version "9.0.0"}
com.microsoft.sqlserver/mssql-jdbc {:mvn/version "12.6.1.jre11"}
com.microsoft.azure/msal4j {:mvn/version "1.14.1"}
com.azure/azure-identity {:mvn/version "1.11.1"}
org.xerial/sqlite-jdbc {:mvn/version "3.46.0.0"}

com.opencsv/opencsv {:mvn/version "5.9"}
Expand Down
8 changes: 8 additions & 0 deletions clojure/test/pgloader/load_file/ast_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@
false))
"com.microsoft.aad.msal4j must be on the classpath for ActiveDirectoryPassword / ActiveDirectoryServicePrincipal auth")))

(deftest test-azure-identity-on-classpath
(testing "azure-identity is bundled — ActiveDirectoryDefault / AzCli / WorkloadIdentity auth modes are available"
(is (try (Class/forName "com.azure.identity.DefaultAzureCredentialBuilder")
true
(catch ClassNotFoundException _
false))
"com.azure.identity must be on the classpath for ActiveDirectoryDefault / ActiveDirectoryAzCli / ActiveDirectoryWorkloadIdentity auth")))

(deftest test-parse-postgresql-synthesises-jdbc-url
(testing "postgresql:// synthesises jdbc-url"
(let [m (parse-uri "postgresql://user:pass@pg:5432/mydb")]
Expand Down
92 changes: 75 additions & 17 deletions docs/ref/mssql.rst
Original file line number Diff line number Diff line change
Expand Up @@ -348,21 +348,33 @@ nor on the lack of support for regular expressions in the engine.
Azure SQL / Azure Active Directory Authentication
-------------------------------------------------

pgloader v4 uses the Microsoft JDBC driver (``mssql-jdbc``) and bundles
MSAL4J, so the following non-interactive Azure AD authentication modes work
out of the box. Always use a ``jdbc:sqlserver://`` URL for Azure SQL so that
``encrypt=true`` and ``authentication=`` reach the driver exactly as written:

``ActiveDirectoryPassword``
Authenticate with an Azure AD username and password::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryPassword;user=user@tenant.onmicrosoft.com;\
password=secret;encrypt=true;trustServerCertificate=false"
pgloader v4 uses the Microsoft JDBC driver (``mssql-jdbc``) and bundles both
MSAL4J and the Azure Identity library (``azure-identity``), so all
non-browser-dependent Entra ID authentication modes work out of the box.
Always use a ``jdbc:sqlserver://`` URL for Azure SQL so that ``encrypt=true``
and ``authentication=`` reach the driver exactly as written.

Quick reference:

+--------------------------------------+------------------------------------------------+
| Mode | Typical use case |
+======================================+================================================+
| ``ActiveDirectoryServicePrincipal`` | CI/CD — app registration (client ID + secret) |
+--------------------------------------+------------------------------------------------+
| ``ActiveDirectoryManagedIdentity`` | Azure VM / App Service / AKS — no credentials |
+--------------------------------------+------------------------------------------------+
| ``ActiveDirectoryDefault`` | Developer laptop: ``az login`` fallback chain |
+--------------------------------------+------------------------------------------------+
| ``ActiveDirectoryAzCli`` | Developer laptop: explicit ``az login`` token |
+--------------------------------------+------------------------------------------------+
| ``ActiveDirectoryWorkloadIdentity`` | Kubernetes OIDC workload identity |
+--------------------------------------+------------------------------------------------+
| ``ActiveDirectoryPassword`` | **Deprecated** — blocked by MFA enforcement |
+--------------------------------------+------------------------------------------------+

``ActiveDirectoryServicePrincipal``
Authenticate as an Azure AD application (client ID + client secret),
suitable for fully automated / CI pipelines::
Authenticate as an Azure AD application (client ID + client secret)
the recommended mode for CI/CD pipelines and automated migrations::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryServicePrincipal;\
Expand All @@ -371,16 +383,62 @@ encrypt=true"

``ActiveDirectoryManagedIdentity``
Authenticate using the managed identity of the Azure VM, App Service,
or container that pgloader runs in — no credentials in the URL::
AKS pod, or container that pgloader runs in — no credentials in the URL::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryManagedIdentity;encrypt=true"

``ActiveDirectoryDefault``
The recommended mode for developer workstations. Uses the Azure
Identity ``DefaultAzureCredential`` chain: environment variables →
workload identity → managed identity → **Azure CLI** → Azure PowerShell.
After a one-time ``az login``, no credentials need to appear in the URL::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryDefault;encrypt=true;trustServerCertificate=false"

This also works headlessly in WSL2: ``DefaultAzureCredential`` falls back
to ``AzureCliCredential``, which shells out to ``az account
get-access-token`` using your existing ``az login`` session — no browser
popup is needed.

``ActiveDirectoryAzCli``
Like ``ActiveDirectoryDefault`` but always uses the Azure CLI token
exclusively. Useful when you want a predictable, unambiguous credential
source on a developer machine::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryAzCli;encrypt=true;trustServerCertificate=false"

``ActiveDirectoryWorkloadIdentity``
For Kubernetes pods with OIDC workload identity federation::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryWorkloadIdentity;encrypt=true"

``ActiveDirectoryPassword``
.. note::

**Deprecated by Microsoft.** This mode is incompatible with mandatory
Entra ID multifactor authentication (MFA), which Microsoft now enforces
by default across most tenants. Attempting it in an MFA-required
tenant returns ``AADSTS50076``. Use ``ActiveDirectoryDefault`` or
``ActiveDirectoryServicePrincipal`` instead.

::

FROM "jdbc:sqlserver://myserver.database.windows.net:1433;databaseName=mydb;\
authentication=ActiveDirectoryPassword;user=user@tenant.onmicrosoft.com;\
password=secret;encrypt=true;trustServerCertificate=false"

.. note::

``ActiveDirectoryInteractive`` opens a browser window for an OAuth2
interactive login and **cannot** be used with pgloader, which runs
non-interactively.
``ActiveDirectoryInteractive`` makes MSAL4J open a system browser via
``xdg-open`` for an OAuth2 interactive login. It works on native Windows,
native macOS, and Linux desktops with a display server. It **fails** in
WSL2 (``linux_xdg_open_failed`` — WSL2 has no JVM-accessible browser
integration), headless Linux, Docker/Podman containers, and CI pipelines.
Use ``ActiveDirectoryDefault`` with an existing ``az login`` session instead.

The native ``mssql://`` scheme defaults to ``encrypt=false`` to match
on-premises SQL Server behaviour. For Azure SQL use the
Expand Down
Loading