Introducing Agent Safe Governance for the AI Era

MSSQL Server with Integrated Security and Kerberos Authentication for Linux and macOS

Last updated: June 11, 2026

If your application runs on a Linux or macOS machine in an Active Directory environment, you can use integrated security to access your Microsoft SQL Server database. Integrated security uses an operating-system identity, rather than a username and password stored in Liquibase, to authenticate to MSSQL Server.

Kerberos is an authentication protocol that works based on tickets to provide strong authentication for client/server applications by using secret-key cryptography. The Kerberos authentication protocol does not store passwords locally or send them over the Internet.

On Linux and macOS, Kerberos (authenticationScheme=JavaKerberos) is the only integrated authentication mechanism available to the Microsoft JDBC driver. The NativeAuthentication scheme is available on Windows only, see MSSQL Server with Integrated Security and Kerberos Authentication for Windows.

Note: This page covers integrated (passwordless) authentication. If you want to connect with a username and password instead, you do not need Kerberos, see Using Liquibase with MSSQL Server.

Before you begin

  • Install Liquibase.

  • Ensure you have Java installed. Liquibase requires Java to run. If you used the Liquibase Installer, Java is included automatically. Otherwise, you must install Java manually.

  • Ensure SQL Server is joined to Active Directory and has a Service Principal Name (SPN) registered, for example MSSQLSvc/dbserver.mydomain.com:1433. See Use Active Directory authentication with SQL Server on Linux or ask your DBA.

    Note: For SQL Server on Amazon RDS joined to AWS Managed Microsoft AD, the SPN is registered automatically under the instance's AD machine name (for example EC2AMAZ-XXXXXXX.mydomain.com), not under the *.rds.amazonaws.com endpoint. See Connecting through a load balancer, CNAME, or RDS endpoint.

  • Ensure your machine can reach the Active Directory domain controllers (TCP/UDP 88 for Kerberos and DNS for the AD domain) and the SQL Server host (TCP 1433).

  • Have an Active Directory user with a login on the SQL Server instance (for example MYDOMAIN\lbuser).

  • Install the Kerberos client tools (kinit, klist) if they are not already present. On most Linux distributions they are in the krb5-workstation (RHEL family) or krb5-user (Debian family) package. macOS includes them (Heimdal) out of the box.

Procedure

1

Configure Kerberos

Create or verify the /etc/krb5.conf file. Hosts that are already joined to the domain typically have a working file; in that case, continue to step 2.

Example

loading

Note: The realm name (MYDOMAIN.COM) is your Active Directory domain name in UPPERCASE. It must be identical in default_realm, the [realms] section, and the [domain_realm] mappings.

(Optional) If you cannot edit /etc/krb5.conf, place the file anywhere and point both the Kerberos tools and Liquibase at it. You will also pass -Djava.security.krb5.conf=/path/to/krb5.conf to Liquibase in step 3.

loading
2

Obtain a Kerberos ticket

1. Set the KRB5CCNAME environment variable to a file-based ticket cache before running kinit:

loading

Note: The Java Virtual Machine that runs Liquibase can read Kerberos tickets only from a FILE: cache. Many modern systems default to a cache type that Java cannot read, KCM: on RHEL 8+ and Fedora (sssd-kcm), and the API: cache on macOS. If you skip this step, kinit and sqlcmd work but Liquibase fails to find the ticket.

2. Run the kinit command to obtain and cache the Kerberos ticket-granting ticket, then verify it with klist:

kinit lbuser@MYDOMAIN.COM
klist

Sample output

loading

The Ticket cache line must begin with FILE:. If it shows KCM: or API:, the KRB5CCNAME variable was not in effect when you ran kinit.

3. Keep KRB5CCNAME exported in the shell where you run Liquibase. Tickets expire (10 hours by default); re-run kinit when they do.

3

Configure the Liquibase connection

If your krb5.conf is not at the platform default location (/etc/krb5.conf), include the following JAVA_OPTS argument:

loading

No other JAVA_OPTS arguments are required for Kerberos.

4

Verify the connection

1. Run the liquibase status command to ensure the connection works:

liquibase status --verbose

Sample output

loading

The connection identity (MYDOMAIN\lbuser@jdbc:sqlserver://...) confirms Liquibase connected as the Active Directory user.

(Optional) For positive proof that the session authenticated with Kerberos, and not NTLM or SQL authentication, run:

loading

Sample output

loading

2. You can now run any Liquibase command. For example:

liquibase update

Sample output

loading

Connecting through a load balancer, CNAME, or RDS endpoint

Kerberos issues service tickets for a specific SPN. If the hostname in your JDBC URL is not the name the SPN was registered under — common with Amazon RDS endpoints (*.rds.amazonaws.com), CNAME aliases, and load balancers — authentication fails with No valid credentials provided (Mechanism level: Server not found in Kerberos database (7)) even though the ticket from kinit is valid.

You have two options:

1. Connect using the AD-registered name (preferred when your network can resolve it):

loading

2. Keep the alias in the URL and override the SPN with the serverSpn property:

loading

To find the registered SPN, ask your DBA, or run setspn -L <machine-account> from any domain-joined Windows machine.

macOS notes

macOS ships the Heimdal Kerberos implementation rather than MIT Kerberos. The procedure above is identical on macOS, with two caveats:

Ticket cache: the macOS default ticket cache is the API:/KCM cache, which the JVM cannot read. The export KRB5CCNAME=FILE:... step is mandatory on macOS, not just recommended.

Forcing TCP to the KDC: if your network blocks UDP port 88, Heimdal and Java require different configuration:

  • For kinit (Heimdal): use kdc = tcp/dc1.mydomain.com:88 in the [realms] section.

  • For Liquibase (Java): use plain kdc = dc1.mydomain.com:88 and add udp_preference_limit = 1 to [libdefaults].

Java does not understand the tcp/ prefix and Heimdal does not honor udp_preference_limit, so in this situation maintain two krb5.conf files, one for kinit (selected with KRB5_CONFIG) and one for Liquibase (selected with -Djava.security.krb5.conf). On networks where UDP 88 is open, a single shared file works for both.

Unattended execution with a keytab

For CI/CD pipelines and scheduled jobs where running kinit interactively is not possible, store the principal's key in a keytab file and refresh the ticket non-interactively.

Note: Use only AES encryption types. The RC4 (arcfour-hmac) and DES encryption types are deprecated and rejected by current Active Directory and Kerberos clients.

1. Create the keytab with the MIT ktutil utility:

loading

Note: The key version number (-k) must match the account's msDS-KeyVersionNumber attribute in Active Directory, and the keytab must be regenerated whenever the account password changes.

2. Verify the keytab and obtain a ticket from it:

loading

3. Run Liquibase exactly as described in Configure the Liquibase connection in step 3.

Protect the keytab file like a password file (chmod 600) and store it outside version control.

Troubleshooting

Symptom

Likely cause and fix

Kerberos Login failed: Integrated authentication failed ... LoginException (Cannot get any of properties: [user, USER] from con properties ...)

The JVM found no ticket. Ensure KRB5CCNAME points to a FILE: cache, the ticket is not expired (klist), and the variable is exported in the same shell that runs Liquibase

No valid credentials provided (Mechanism level: Server not found in Kerberos database (7)), typically only via an alias, load balancer, or RDS endpoint

SPN mismatch, the URL hostname is not the name the SPN is registered under. Connect via the AD machine name or add serverSpn= to the URL (see above)

KrbException: Encryption type ... is not supported/enabled

Deprecated encryption types in a keytab or krb5.conf. Remove allow_weak_crypto, RC4, and DES configuration, and regenerate keytabs with AES

Cannot locate KDC / Cannot contact any KDC

The [realms] section is wrong or DNS SRV lookups are failing. Verify dig SRV _kerberos._tcp.MYDOMAIN.COM resolves, or list KDCs explicitly in [realms]

Works with sqlcmd -E but Liquibase fails to find a ticket

sqlcmd can read KCM/API caches; Java cannot. Re-run kinit with KRB5CCNAME=FILE:... set

Clock skew too great

Kerberos requires client and KDC clocks within 5 minutes. Enable NTP time synchronization

To see detailed Kerberos negotiation logs while diagnosing a problem, add -Dsun.security.krb5.debug=true to JAVA_OPTS. Remove it for normal operation.