Skip to content

feat(plugin-mssql): add Windows Authentication (Kerberos) on macOS#1890

Merged
datlechin merged 1 commit into
mainfrom
feat/mssql-kerberos-auth
Jul 16, 2026
Merged

feat(plugin-mssql): add Windows Authentication (Kerberos) on macOS#1890
datlechin merged 1 commit into
mainfrom
feat/mssql-kerberos-auth

Conversation

@datlechin

Copy link
Copy Markdown
Member

Windows Authentication (Kerberos) for SQL Server

Closes #1879.

Adds Windows Authentication (Kerberos) to the SQL Server driver on macOS. On macOS, "Windows Authentication" for SQL Server means Kerberos (ticket-based); NTLM/SSPI is Windows-only, so this is the path Azure Data Studio, DataGrip, and DBeaver all use.

What it does

The connection form gains an Authentication picker: SQL Server Authentication (unchanged default) or Windows Authentication (Kerberos). When Kerberos is selected:

  • The built-in SQL Username and Password fields hide, replaced by an optional Kerberos Principal (user@REALM.COM) and a Keychain-backed Password.
  • Blank principal and password uses the existing kinit ticket (single sign-on) via FreeTDS's GSS_C_NO_CREDENTIAL path. This is the default and what most macOS users want.
  • A filled-in principal and password makes the driver acquire a ticket with gss_aapl_initial_cred, write it to a private ccache, point KRB5CCNAME at it for the connect, then release it.
  • An inline caption explains the two modes, and a warning appears if the host is an IP address (Kerberos SPNs are registered against hostnames, not IPs).
  • Kerberos failures are classified into actionable messages (no ticket, SPN not registered, clock skew, expired ticket) instead of a raw driver error.

How it works

  • Empty-username trigger. FreeTDS selects Kerberos when the login username is empty. MSSQLConnectionOptions.init blanks the username and password whenever authMethod == .windows, at the single choke point both the macOS plugin and iOS share, so a synced or imported connection can't leak a stale SQL username into the GSS path.
  • Concurrency. The filled-in-credential path mutates the process-global KRB5CCNAME, so MSSQLKerberosConnectGate serializes all Windows-auth connects behind a shared async lock and restores the previous value after each connect. All GSS code is macOS-only and isolated in the plugin.
  • iOS. The iOS FreeTDS build stays Kerberos-free; the iOS driver rejects a Windows-auth connection with a clear message before touching the network.
  • PluginKit. ConnectionField gains a hidesUsername flag (mirroring hidesPassword) as a builder-set property, so the public initializer is unchanged. The ABI check confirms this is additive, so no currentPluginKitVersion bump.
  • Registry defaults. MSSQL is a registry-only plugin, so the connection form is driven by the app's built-in metadata in PluginMetadataRegistry+RegistryDefaults.swift, not by the installed bundle. The three fields (Authentication dropdown, Kerberos Principal, Kerberos Password) are declared both there and in MSSQLPlugin.swift, and the two declarations must stay in sync. That is why the picker shows in the form even before the 1.1.0 plugin is installed, while the plugin bundle supplies the connect-time GSS behavior.

Build and release (required for the feature to work at runtime)

The bundled FreeTDS was built without GSSAPI, so this is dormant until the static library is rebuilt. scripts/build-freetds.sh now passes --enable-krb5 to the macOS slices (iOS stays krb5-free) and emits the flat committed archives the plugin links. The pbxproj change (the only binary-diff file) adds -framework GSS to the MSSQL plugin target's OTHER_LDFLAGS in both Debug and Release, and bumps its MARKETING_VERSION to 1.1. The two new plugin sources (MSSQLKerberosConnectGate.swift, MSSQLKerberosCredentials.swift) are picked up by the target's filesystem-synchronized group, so they need no pbxproj entry.

bash scripts/build-freetds.sh
scripts/publish-libs.sh libsybdb_arm64.a libsybdb_x86_64.a libsybdb_universal.a libsybdb.a
git add Libs/checksums.sha256 && git commit -m "build: rebuild libsybdb with Kerberos (GSS) support"
# after the app change ships, cut the registry plugin (bumped to 1.1.0):
git tag -a plugin-mssql-v1.1.0 -m "plugin-mssql-v1.1.0" && git push origin plugin-mssql-v1.1.0

The iOS xcframework is unchanged, so no iOS re-upload.

Testing

Verified locally:

  • New unit tests: MSSQLConnectionOptionsAuthMethodTests (Windows blanks credentials, SQL passes them through, authMethod(from:) parsing), MSSQLKerberosClassifierTests (one per failure kind), a UsernameHidingTests suite, an empty-username case in MSSQLLoginParametersTests, and a deterministic iOS MSSQLDriverWindowsAuthTests (rejection before any network).
  • SwiftLint --strict: clean. PluginKit ABI check: additive only.
  • The GSS interop file typechecks against the real GSS.framework.

Not covered by automated tests (needs a real environment):

  • The FreeTDS Kerberos handshake itself: the C path can't be unit-tested, so the empty-username-triggers-GSS behavior and the Kerberos error-string classifications need confirming against a live Kerberos-secured SQL Server.
  • No TableProUITests case was added for the Authentication picker and field hiding: the flow depends on live plugin metadata and a real Kerberos server, so it isn't deterministic in UI automation. The field-hiding logic is covered by the UsernameHidingTests unit suite instead.

Known limitation (follow-up)

FreeTDSConnection.connect() still has no cancellation path. Because MSSQLKerberosConnectGate serializes all Windows-auth connects through one shared lock held across the whole connect, a connect stalled on an unreachable KDC can make Cancel unresponsive up to the login timeout and blocks every other Windows-auth connection attempt until then, not just its own tab. Fixing that properly needs a FreeTDS fork, so it is tracked separately in #1889 rather than bundled here.

Docs and changelog

Updated docs/databases/mssql.mdx (new Windows Authentication section, troubleshooting, revised limitations) and added a changelog entry.

@datlechin
datlechin merged commit b91c731 into main Jul 16, 2026
4 checks passed
@datlechin
datlechin deleted the feat/mssql-kerberos-auth branch July 16, 2026 16:05

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 579fd045ca

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

fieldId: MSSQLConnectionOptions.AdditionalFieldKey.authMethod,
values: ["windows"]
)
).withHidesUsername(true),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Gate MSSQL plugin on the new PluginKit API

When the registry publishes this MSSQL plugin, older TablePro builds whose currentPluginKitVersion is still 18 will pass the bundle compatibility check because Plugins/MSSQLDriverPlugin/Info.plist still only declares TableProPluginKitVersion 18, but this static metadata now calls the newly added ConnectionField.withHidesUsername symbol. Those older hosts do not have that symbol in their bundled TableProPluginKit, so activating the 1.1 plugin can fail before users get a clean compatibility error. Please bump the plugin compatibility or add a TableProMinAppVersion for the first app version that contains this API.

Useful? React with 👍 / 👎.

@mintlify

mintlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
TablePro 🟡 Building Jul 16, 2026, 4:04 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Windows Authentication / Kerberos to Microsoft SQLServer

1 participant