Skip to content

[SEA-NodeJS] Kernel backend: mTLS, custom HTTP headers & User-Agent#420

Open
msrathore-db wants to merge 1 commit into
mainfrom
msrathore/sea-mtls-headers-useragent
Open

[SEA-NodeJS] Kernel backend: mTLS, custom HTTP headers & User-Agent#420
msrathore-db wants to merge 1 commit into
mainfrom
msrathore/sea-mtls-headers-useragent

Conversation

@msrathore-db
Copy link
Copy Markdown
Contributor

@msrathore-db msrathore-db commented Jun 5, 2026

What

Wires the SEA/kernel path's remaining TLS-adjacent connection options through to the napi binding, completing the TLS surface started in #416 (checkServerCertificate + customCaCert). Shapes and semantics mirror the Python connector's use_kernel path (session.py + backend/kernel/client.py, latest main #825).

  • mTLS client identityclientCertPem / clientKeyPem (PEM string or Buffer), normalised to Buffers and routed to TlsConfig::client_cert_pem / client_key_pem. Both-or-neither enforced up front. (Python forwards tls_client_cert / tls_client_key; encrypted-key password unsupported in both — the kernel has no field for it.)
  • Independent hostname verificationcheckServerCertificateHostname (kernel skip_hostname_verification), for full parity with Python's tls_verify_hostname: skip only the hostname-vs-SNI check while still validating the chain. The master checkServerCertificate=false subsumes it (disables everything), exactly like Python's tls_verify=False.
  • Custom HTTP headers + User-Agent — headers cross the FFI as an ordered list (Array<{name,value}>, the napi HeaderEntry shape matching the kernel core Vec<(String,String)> and Python's List[Tuple]): caller customHeaders first, then the connector's composed User-Agent appended last (always emitted via the same buildUserAgentString the Thrift path uses, with userAgentEntry folded in; the kernel folds the last User-Agent into its base DatabricksJDBCDriverOSS/... UA, preserving the result-disposition gating token). Reserved names Authorization / x-databricks-org-id are dropped before the FFI hop, matching Python's _KERNEL_MANAGED_HEADERS double-wall.

Adds buildSeaHttpOptions, extends buildSeaTlsOptions / SeaTlsOptions, factors PEM normalisation into a shared helper, and adds the new fields to InternalConnectionOptions.

Parity

Verified against the latest databricks-sql-python main (#825), which wires TLS/mTLS/http_headers/User-Agent through KernelDatabricksClient. Server-cert verification now has full granular parity: master toggle (checkServerCertificatetls_no_verify) plus the independent checkServerCertificateHostnametls_verify_hostname.

Dependency

Depends on databricks/databricks-sql-kernel#127 (exposes clientCertPem / clientKeyPem / customHeaders / checkServerCertificateHostname). KERNEL_REV is bumped to that branch's HEAD and native/sea/index.d.ts regenerated; KERNEL_REV must be repointed to the squashed kernel commit once #127 merges.

Testing

npm test -- tests/unit/sea/connectionOptions.test.ts — 33 passing (mTLS pairing/validation, hostname toggle, ordered header pass-through, reserved-name dropping, User-Agent composition/ordering). tsc --noEmit + eslint clean on changed files. Additionally ran an FFI smoke test against the rebuilt native binding: every new field (mTLS Buffers, ordered customHeaders, both TLS toggles) marshals across the boundary, and a wrong header shape (plain map) is rejected by the binding ("Given napi value is not an array on ConnectionOptions.customHeaders"). (Pre-existing examples/ + optional-lz4 failures are unrelated.)

This pull request and its description were written by Isaac.

@msrathore-db msrathore-db force-pushed the msrathore/sea-mtls-headers-useragent branch from 68dbb3d to 1607ce0 Compare June 5, 2026 01:11
@msrathore-db msrathore-db force-pushed the msrathore/sea-mtls-headers-useragent branch from 1607ce0 to b0cf092 Compare June 5, 2026 01:31
@msrathore-db msrathore-db force-pushed the msrathore/sea-mtls-headers-useragent branch from b0cf092 to cdcf766 Compare June 5, 2026 01:40
@msrathore-db msrathore-db force-pushed the msrathore/sea-mtls-headers-useragent branch from cdcf766 to 84924c9 Compare June 5, 2026 01:56
Wire the SEA/kernel path's remaining TLS-adjacent connection options
through to the napi binding, matching the Python connector's use_kernel
path (session.py + backend/kernel/client.py):

- mTLS client identity: `clientCertPem` / `clientKeyPem` (PEM string or
  Buffer), normalised to Buffers and routed to the kernel
  `TlsConfig::client_cert_pem` / `client_key_pem`. Both-or-neither
  enforced up front with an actionable error.
- Independent hostname-verify toggle: `checkServerCertificateHostname`
  (kernel `skip_hostname_verification`) for full parity with Python's
  `tls_verify_hostname` — skip only the hostname check while still
  validating the chain. The master `checkServerCertificate=false` still
  subsumes it.
- Custom HTTP headers + User-Agent: headers cross the FFI as an ordered
  list (`Array<{name,value}>`, the napi `HeaderEntry` shape matching the
  kernel core `Vec<(String,String)>` and Python's `List[Tuple]`): caller
  `customHeaders` first, then the connector's composed `User-Agent`
  appended last (always emitted; the kernel folds the last User-Agent into
  its base `DatabricksJDBCDriverOSS/...` UA). Kernel-managed reserved names
  `Authorization` / `x-databricks-org-id` are dropped before the FFI hop,
  matching Python's `_KERNEL_MANAGED_HEADERS` double-wall.

Adds `buildSeaHttpOptions`, extends `buildSeaTlsOptions`/`SeaTlsOptions`,
and factors PEM normalisation into a shared helper. Bumps KERNEL_REV and
regenerates `native/sea/index.d.ts`. Unit tests cover mTLS
pairing/validation, the hostname toggle, ordered header pass-through,
reserved-name dropping, and User-Agent composition/ordering; verified the
real native binding marshals every new field across the FFI and rejects a
wrong header shape.

Depends on the kernel napi change exposing clientCertPem / clientKeyPem /
customHeaders / checkServerCertificateHostname; KERNEL_REV must be
repointed to that commit once merged.

Co-authored-by: Isaac
Signed-off-by: Madhavendra Rathore <madhavendra.rathore@databricks.com>
@msrathore-db msrathore-db force-pushed the msrathore/sea-mtls-headers-useragent branch from 84924c9 to cfe3b3f Compare June 5, 2026 08:41
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.

1 participant