feat: mssql integrated auth (gssapi) (#7760)

* feat: mssql integrated auth (kerberos/ntlm)

* install krb5 headers

* also make it work for windows

---------

Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
This commit is contained in:
Alexander Petric
2026-02-05 13:35:31 -05:00
committed by GitHub
parent 309de58134
commit afa6e7ab5b
10 changed files with 163 additions and 20 deletions
+4 -4
View File
@@ -33,10 +33,10 @@ jobs:
with:
fetch-depth: 0
- name: install xmlsec1
- name: install xmlsec1 and gssapi
run: |
sudo apt-get update
sudo apt-get install -y libxml2-dev libxmlsec1-dev
sudo apt-get install -y libxml2-dev libxmlsec1-dev libkrb5-dev
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
@@ -100,10 +100,10 @@ jobs:
token: ${{ secrets.WINDMILL_EE_PRIVATE_ACCESS }}
fetch-depth: 0
- name: install xmlsec1
- name: install xmlsec1 and gssapi
run: |
sudo apt-get update
sudo apt-get install -y libxml2-dev libxmlsec1-dev
sudo apt-get install -y libxml2-dev libxmlsec1-dev libkrb5-dev
- name: Substitute EE code (EE logic is behind feature flag)
run: |
+2 -2
View File
@@ -75,10 +75,10 @@ jobs:
npm install
npm run generate-backend-client
- name: install xmlsec1
- name: install xmlsec1 and gssapi
run: |
sudo apt-get update
sudo apt-get install -y libxml2-dev libxmlsec1-dev
sudo apt-get install -y libxml2-dev libxmlsec1-dev libkrb5-dev
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
+2 -2
View File
@@ -68,11 +68,11 @@ jobs:
with:
workspaces: "./backend -> target"
- name: Install xmlsec build-time deps
- name: Install xmlsec and gssapi build-time deps
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
pkg-config libxml2-dev libssl-dev \
pkg-config libxml2-dev libssl-dev libkrb5-dev \
xmlsec1 libxmlsec1-dev libxmlsec1-openssl
- name: Run update-sqlx script
+1 -1
View File
@@ -97,7 +97,7 @@ ARG features=""
COPY --from=planner /windmill/recipe.json recipe.json
RUN apt-get update && apt-get install -y libxml2-dev=2.9.* libxmlsec1-dev=1.2.* clang=1:14.0-55.* libclang-dev=1:14.0-55.* cmake=3.25.* && \
RUN apt-get update && apt-get install -y libxml2-dev=2.9.* libxmlsec1-dev=1.2.* libkrb5-dev clang=1:14.0-55.* libclang-dev=1:14.0-55.* cmake=3.25.* && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
+125 -5
View File
@@ -1632,6 +1632,26 @@ dependencies = [
"syn 2.0.114",
]
[[package]]
name = "bindgen"
version = "0.71.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
dependencies = [
"bitflags 2.9.4",
"cexpr",
"clang-sys",
"itertools 0.10.5",
"log",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash 2.1.1",
"shlex",
"syn 2.0.114",
]
[[package]]
name = "bindgen"
version = "0.72.1"
@@ -6104,6 +6124,17 @@ dependencies = [
"unicode-width 0.2.2",
]
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.17"
@@ -6113,7 +6144,7 @@ dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasi 0.11.1+wasi-snapshot-preview1",
"wasm-bindgen",
]
@@ -7916,6 +7947,28 @@ dependencies = [
"cc",
]
[[package]]
name = "libgssapi"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e668df13f2e97f3eed52d9301f6b1c4c1ccfccc30eab9e6628e4a8c1fc3546"
dependencies = [
"bitflags 2.9.4",
"bytes",
"lazy_static",
"libgssapi-sys",
]
[[package]]
name = "libgssapi-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7518e6902e94f92e7c7271232684b60988b4bd813529b4ef9d97aead96956ae8"
dependencies = [
"bindgen 0.71.1",
"pkg-config",
]
[[package]]
name = "libloading"
version = "0.7.4"
@@ -8331,6 +8384,12 @@ dependencies = [
"digest 0.10.7",
]
[[package]]
name = "md5"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e6bcd6433cff03a4bfc3d9834d504467db1f1cf6d0ea765d37d330249ed629d"
[[package]]
name = "measure_time"
version = "0.9.0"
@@ -8482,7 +8541,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"log",
"wasi",
"wasi 0.11.1+wasi-snapshot-preview1",
"windows-sys 0.48.0",
]
@@ -8493,7 +8552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
dependencies = [
"libc",
"wasi",
"wasi 0.11.1+wasi-snapshot-preview1",
"windows-sys 0.61.2",
]
@@ -10632,6 +10691,19 @@ dependencies = [
"nibble_vec",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc",
]
[[package]]
name = "rand"
version = "0.8.5"
@@ -10654,6 +10726,16 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
@@ -10674,6 +10756,15 @@ dependencies = [
"rand_core 0.9.5",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
name = "rand_core"
version = "0.6.4"
@@ -10712,6 +10803,15 @@ dependencies = [
"rand 0.9.0",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
name = "range-alloc"
version = "0.1.4"
@@ -13786,8 +13886,7 @@ dependencies = [
[[package]]
name = "tiberius"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1446cb4198848d1562301a3340424b4f425ef79f35ef9ee034769a9dd92c10d"
source = "git+https://github.com/prisma/tiberius?rev=59db57960a14b422fb3a1309aa4aa47880896ff8#59db57960a14b422fb3a1309aa4aa47880896ff8"
dependencies = [
"async-trait",
"asynchronous-codec",
@@ -13798,6 +13897,7 @@ dependencies = [
"encoding_rs",
"enumflags2",
"futures-util",
"libgssapi",
"num-traits",
"once_cell",
"pin-project-lite",
@@ -13810,6 +13910,7 @@ dependencies = [
"tokio-util",
"tracing",
"uuid",
"winauth",
]
[[package]]
@@ -15131,6 +15232,12 @@ dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.11.1+wasi-snapshot-preview1"
@@ -15496,6 +15603,19 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "winauth"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f820cd208ce9c6b050812dc2d724ba98c6c1e9db5ce9b3f58d925ae5723a5e6"
dependencies = [
"bitflags 1.3.2",
"byteorder",
"md5",
"rand 0.7.3",
"winapi",
]
[[package]]
name = "windmill"
version = "1.626.0"
+6 -2
View File
@@ -98,15 +98,17 @@ mysql = ["windmill-worker/mysql"]
oracledb = ["windmill-worker/oracledb"]
duckdb = ["windmill-worker/duckdb"]
mssql = ["windmill-worker/mssql"]
mssql-kerberos = ["windmill-worker/mssql-kerberos"] # Linux/Unix integrated auth
mssql-winauth = ["windmill-worker/mssql-winauth"] # Windows integrated auth
bigquery = ["windmill-worker/bigquery"]
php = ["windmill-worker/php"]
csharp = ["windmill-worker/csharp"]
nu = ["windmill-worker/nu"]
java = ["windmill-worker/java"]
ruby = ["windmill-worker/ruby"]
all_languages = ["python", "deno_core", "rust", "mysql", "oracledb", "duckdb", "mssql", "bigquery", "csharp", "nu", "php", "java", "ruby"]
all_languages = ["python", "deno_core", "rust", "mysql", "oracledb", "duckdb", "mssql-kerberos", "bigquery", "csharp", "nu", "php", "java", "ruby"]
# For windows we have another set of languages enabled
all_languages_windows = ["python", "deno_core", "rust", "mysql", "oracledb", "duckdb", "mssql", "bigquery", "csharp", "nu", "php", "java"]
all_languages_windows = ["python", "deno_core", "rust", "mysql", "oracledb", "duckdb", "mssql-winauth", "bigquery", "csharp", "nu", "php", "java"]
all_sqlx_features = ["all_languages", "enterprise", "enterprise_saml", "embedding", "parquet", "prometheus", "flow_testing",
"openidconnect", "cloud", "jemalloc", "tantivy", "sqlx", "kafka", "nats", "otel", "dind", "websocket", "http_trigger",
"postgres_trigger", "mcp", "mqtt_trigger", "sqs_trigger", "gcp_trigger", "smtp", "stripe",
@@ -114,6 +116,8 @@ all_sqlx_features = ["all_languages", "enterprise", "enterprise_saml", "embeddin
[patch.crates-io]
object_store = { git = "https://github.com/apache/arrow-rs-object-store", rev = "36752c975d4f29e20b57c91f81a10872dcd48ae7" }
# Use tiberius main branch for libgssapi 0.8.1 fix (https://github.com/prisma/tiberius/issues/343)
tiberius = { git = "https://github.com/prisma/tiberius", rev = "59db57960a14b422fb3a1309aa4aa47880896ff8" }
[dependencies]
anyhow.workspace = true
+2
View File
@@ -15,6 +15,8 @@ mcp = ["dep:windmill-mcp"]
prometheus = ["dep:prometheus", "windmill-common/prometheus"]
enterprise = ["windmill-queue/enterprise", "windmill-git-sync/enterprise", "windmill-common/enterprise", "dep:pem", "dep:tokio-util"]
mssql = ["dep:tiberius"]
mssql-kerberos = ["mssql", "tiberius/integrated-auth-gssapi"] # Linux/Unix integrated auth
mssql-winauth = ["mssql", "tiberius/winauth"] # Windows integrated auth
bigquery = ["dep:gcp_auth"]
benchmark = ["windmill-queue/benchmark", "windmill-common/benchmark"]
parquet = ["windmill-common/parquet", "dep:object_store"]
+19 -2
View File
@@ -46,6 +46,7 @@ struct MssqlDatabase {
#[serde(default, deserialize_with = "empty_as_none")]
ca_cert: Option<String>,
encrypt: Option<bool>,
integrated_auth: Option<bool>,
}
#[derive(Debug, Deserialize)]
@@ -129,7 +130,23 @@ pub async fn do_mssql(
}
// Handle authentication based on available credentials
if let Some(token_value) = &database.aad_token {
if database.integrated_auth.unwrap_or(false) {
#[cfg(any(feature = "mssql-kerberos", feature = "mssql-winauth"))]
{
config.authentication(AuthMethod::Integrated);
#[cfg(feature = "mssql-kerberos")]
let logs = format!("\nUsing Integrated Authentication (Kerberos/GSSAPI)");
#[cfg(feature = "mssql-winauth")]
let logs = format!("\nUsing Integrated Authentication (Windows SSPI)");
append_logs(&job.id, &job.workspace_id, logs, conn).await;
}
#[cfg(not(any(feature = "mssql-kerberos", feature = "mssql-winauth")))]
{
return Err(Error::BadRequest(
"Integrated authentication is not available in this build. Requires mssql-kerberos (Linux) or mssql-winauth (Windows) feature.".to_string(),
));
}
} else if let Some(token_value) = &database.aad_token {
if let Some(token) = &token_value.token {
config.authentication(AuthMethod::aad_token(token));
} else {
@@ -141,7 +158,7 @@ pub async fn do_mssql(
config.authentication(AuthMethod::sql_server(user.clone(), password.clone()));
} else {
return Err(Error::BadRequest(
"Neither AAD token nor username/password credentials are set".to_string(),
"No authentication method configured. Set integrated_auth, aad_token, or user/password.".to_string(),
));
}
+1 -1
View File
@@ -62,7 +62,7 @@ RUN --mount=type=secret,id=rh_username \
RUN subscription-manager repos --enable codeready-builder-for-rhel-8-$(arch)-rpms
RUN yum update -y && \
yum install -y perl-interpreter perl-IPC-Cmd perl-Time-Piece libxml2-devel xmlsec1-devel xmlsec1-openssl-devel clang llvm-devel cmake libtool-ltdl-devel
yum install -y perl-interpreter perl-IPC-Cmd perl-Time-Piece libxml2-devel xmlsec1-devel xmlsec1-openssl-devel krb5-devel clang llvm-devel cmake libtool-ltdl-devel
# RUN --mount=type=cache,target=/usr/local/cargo/registry \
# CARGO_NET_GIT_FETCH_WITH_CLI=true RUST_BACKTRACE=1 cargo chef cook --release --features "$features" --recipe-path recipe.json
+1 -1
View File
@@ -62,7 +62,7 @@ RUN --mount=type=secret,id=rh_username \
RUN subscription-manager repos --enable codeready-builder-for-rhel-9-$(arch)-rpms
RUN yum update -y && \
yum install -y perl-FindBin perl-IPC-Cmd perl-Time-Piece libxml2-devel xmlsec1-devel xmlsec1-openssl-devel clang llvm-devel cmake libtool-ltdl-devel
yum install -y perl-FindBin perl-IPC-Cmd perl-Time-Piece libxml2-devel xmlsec1-devel xmlsec1-openssl-devel krb5-devel clang llvm-devel cmake libtool-ltdl-devel
# RUN --mount=type=cache,target=/usr/local/cargo/registry \
# CARGO_NET_GIT_FETCH_WITH_CLI=true RUST_BACKTRACE=1 cargo chef cook --release --features "$features" --recipe-path recipe.json