Docs Home
Viewing docs for
Self-ManagedNot available for BYOC

Connecting to SQL Server with Integrated Security (Kerberos)

Connect Flink SQL to a Kerberos-secured SQL Server with no username or password, using the JDBC connector's JavaKerberos authentication mode.

On this page

Run a FlinkSQL deployment against a Kerberos-only Microsoft SQL Server with no username or password. This works identically for source and sink tables and needs no custom image or Helm chart change.

Applies to: Ververica Platform 3.1.1, VVR 4.5.0, Flink 1.20 (JDK 11), SQL Server 2019/2022, SQL deployments.

Components

Kerberos is a three-party protocol, not a direct Flink-to-SQL-Server secret:

  • KDC (Active Directory domain controller): issues tickets and holds the service principal names (SPNs) and accounts.
  • Client (the Flink TaskManager, using the mssql-jdbc driver): uses a keytab to get a ticket-granting ticket (TGT), then a service ticket for the SQL Server SPN.
  • SQL Server: validates the ticket with its own keytab, then maps the principal to a SQL login through AD/LDAP.

How the handshake works

  1. The TaskManager authenticates its principal against the KDC using the keytab (an AS-REQ) and receives a TGT.
  2. The TaskManager requests a service ticket from the KDC for the SQL Server SPN (MSSQLSvc/host:1433).
  3. The TaskManager connects to SQL Server and presents the service ticket. No username or password is sent.
  4. SQL Server resolves the principal to a SQL login through LDAP against the KDC, then authenticates the connection.

What You Need

  • A realm (for example EXAMPLE.COM) and a KDC hostname reachable from the Flink pods on TCP 88 and 389.
  • An SPN registered to the SQL Server service account, in the form MSSQLSvc/<SQL_HOST>:1433.
  • A client principal (for example flinksvc@EXAMPLE.COM) and its keytab.
  • A krb5.conf for the realm. See the appendix for a sample.
  • On SQL Server: an AD login for the principal, mapped to a DB user with rights on the target table.
  • Network reachability from the Flink pods to the KDC (ports 88, 389) and to SQL Server (port 1433).

Step 1: Connector Jars

VVR ships no SQL Server connector out of the box. Combine the Apache Flink JDBC connector with the Microsoft JDBC driver (versions shown are for Flink 1.20 / JDK 11):

JarUpload as
org.apache.flink:flink-connector-jdbc-core:3.3.0-1.20Custom Connector, SQL identifier jdbc
org.apache.flink:flink-connector-jdbc-sqlserver:3.3.0-1.20Additional Dependency
com.microsoft.sqlserver:mssql-jdbc:12.6.1.jre11Additional Dependency

Step 2: Register the Kerberos Configuration

Upload the keytab and krb5.conf to the artifact store, then register the configuration once per namespace using the REST API. In Ververica Platform 3.1.1 the console UI does not expose Kerberos, so the API is currently the only way to register it:

BASH
1POST /api/v2/kerberos-configs        (header: Workspace: <workspace>)

Step 3: FlinkSQL (No Username or Password)

Kerberos flags live in the url property; set serverSpn explicitly. A source table uses the same WITH clause (drop the PRIMARY KEY).

SQL
1CREATE TEMPORARY TABLE mssql_sink (
2  id BIGINT, payload STRING, ts TIMESTAMP(3),
3  PRIMARY KEY (id) NOT ENFORCED
4) WITH (
5  'connector'  = 'jdbc',
6  'url'        = 'jdbc:sqlserver://<SQL_HOST>:1433;databaseName=<DB>;integratedSecurity=true;authenticationScheme=JavaKerberos;serverSpn=<SPN>;encrypt=true;trustServerCertificate=false',
7  'table-name' = 'dbo.<TABLE>',
8  'driver'     = 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
9);

Step 4: Deployment Configuration

YAML
1spec:
2  template:
3    spec:
4      artifact:
5        kind: SQLSCRIPT
6        versionName: vera-4.5-jdk11-flink-1.20
7        sqlScript: |-
8          -- DDL from Step 3 (+ INSERT INTO mssql_sink SELECT ... for a sink)
9        additionalDependencies:
10          - s3i://<ARTIFACT_STORE>/artifacts/namespaces/<ns>/flink-connector-jdbc-sqlserver-3.3.0-1.20.jar
11          - s3i://<ARTIFACT_STORE>/artifacts/namespaces/<ns>/mssql-jdbc-12.6.1.jre11.jar
12      flinkConfiguration:
13        security.kerberos.login.contexts: Client,KafkaClient,SQLJDBCDriver
14      kerberosConfig:
15        kerberosEnabled: true
16        kerberosClusterName: kerberos
17        principal: <PRINCIPAL>
18        keytabPath:   s3i://<ARTIFACT_STORE>/artifacts/namespaces/<ns>/flinksvc.keytab
19        krb5ConfPath: s3i://<ARTIFACT_STORE>/artifacts/namespaces/<ns>/krb5.conf
  • security.kerberos.login.contexts must include SQLJDBCDriver.
  • kerberosConfig needs both: a kerberosClusterName matching the config registered in Step 2 (an unregistered name fails with ResourceDoesNotExist), and the inline keytabPath + krb5ConfPath + principal (omitting the paths fails the appmanager). In Ververica Platform 3.1.1, the paths are effectively given twice: once in the registered config, once inline. Both are required.

Step 5: Deploy and Verify

Start the deployment. The JobManager starts first, then the TaskManager (an artifact-fetcher init container stages the jars, keytab, and krb5.conf), then the job runs.

BASH
1sqlcmd -S <SQL_HOST> -E -d <DB> -Q "SELECT COUNT(*) FROM dbo.<TABLE>;"
2kubectl -n <ns> exec <jobmanager-pod> -c flink-main-container -- ls /flink/usrlib/   # all 3 jars present

TLS

encrypt=true is required by SQL Server 2022. In production, keep trustServerCertificate=false and add the SQL Server CA to the JVM truststore using env.java.opts (-Djavax.net.ssl.trustStore=...).

Notes and Limitations (Ververica Platform 3.1.1)

  • Kerberos configuration is API-only: the console UI has no Kerberos page. Register the config using POST /api/v2/kerberos-configs and set kerberosConfig on the deployment through the YAML view or the API.
  • A pod template on a SQL deployment causes “Failed to create the Kubernetes resources: empty” and no pod starts. Use the native kerberosConfig field instead.
  • Dependencies must be in the artifact store (s3i://); https:// URLs are not fetched.
  • Editing an existing SQL deployment might not take effect, since configuration is cached per SQL file and the YAML view merges. If a change does not apply, create a new SQL file or a fresh deployment.
  • The SQL editor validator cannot load the dialect, so it might report a dialect error even when the deployment runs fine. Rely on an actual run to confirm.

Generalizing Beyond SQL Server

This pattern is not specific to Microsoft SQL Server: it generalizes to any Kerberos-secured JDBC target, including Oracle (Kerberos/GSS-API authentication) and PostgreSQL (GSSAPI authentication). The keytab, krb5.conf, kerberosConfig registration, and security.kerberos.login.contexts steps above stay the same across drivers. The differences are driver-specific: the JDBC URL flags (for example, Oracle's oracle.net.authentication_services=(KERBEROS5) versus PostgreSQL's gsslib=gssapi), the login-context name the driver expects, and which driver JAR to stage as an Additional Dependency alongside the jdbc Custom Connector.

Appendix: Sample krb5.conf

TEXT
1[libdefaults]
2    default_realm = EXAMPLE.COM
3    dns_lookup_realm = false
4    dns_lookup_kdc = false
5    rdns = false
6    dns_canonicalize_hostname = false
7    udp_preference_limit = 1
8[realms]
9    EXAMPLE.COM = {
10        kdc = dc1.example.com
11        admin_server = dc1.example.com
12    }
13[domain_realm]
14    .example.com = EXAMPLE.COM
15    example.com = EXAMPLE.COM
Was this helpful?