Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1,018 changes: 1,018 additions & 0 deletions doc/developer/design/20260821_mutual_tls_client_authentication.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions misc/python/materialize/mzcompose/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,9 @@ def get_default_system_parameters(
"oidc_group_role_sync_enabled",
"oidc_group_claim",
"oidc_group_role_sync_strict",
"mtls_client_ca",
"mtls_mode",
"mtls_identity_binding",
"console_oidc_client_id",
"console_oidc_scopes",
"enable_public_metrics_endpoint",
Expand Down
5 changes: 5 additions & 0 deletions misc/python/materialize/parallel_workload/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -3326,6 +3326,11 @@ def __init__(
"oidc_group_role_sync_enabled",
"oidc_group_claim",
"oidc_group_role_sync_strict",
# Flipping an admission policy would sever parallel-workload's own
# connections, which present no client certificate.
"mtls_client_ca",
"mtls_mode",
"mtls_identity_binding",
"console_oidc_client_id",
"console_oidc_scopes",
"cluster_controller_tick_interval",
Expand Down
35 changes: 35 additions & 0 deletions src/adapter-types/src/dyncfgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,38 @@ pub const OIDC_GROUP_ROLE_SYNC_STRICT: Config<bool> = Config::new(
"When true, reject login if OIDC group-to-role sync fails (fail-closed).",
);

/// Trust anchors for mutual TLS client authentication: a PEM bundle of
/// certificate authorities whose leaves are accepted.
///
/// A bundle rather than a single certificate so that an operator can trust
/// several authorities at once, and can stage a CA rotation by trusting the old
/// and the new authority simultaneously.
pub const MTLS_CLIENT_CA: Config<Option<&'static str>> = Config::new(
"mtls_client_ca",
None,
"PEM bundle of certificate authorities trusted to issue client certificates for mutual TLS.",
);

/// How strictly to enforce mutual TLS on external logins: `disable`, `allow`,
/// or `require`. See `mz_authenticator::client_cert::MtlsMode`.
pub const MTLS_MODE: Config<&'static str> = Config::new(
"mtls_mode",
"disable",
"How strictly to enforce mutual TLS client authentication for external logins: \
'disable' ignores client certificates, 'allow' accepts a trusted certificate but does \
not require one, 'require' rejects logins without one.",
);

/// Which certificate field, if any, must agree with the connecting username.
/// See `mz_authenticator::client_cert::IdentityBinding`.
pub const MTLS_IDENTITY_BINDING: Config<&'static str> = Config::new(
"mtls_identity_binding",
"none",
"Which client certificate field must match the connecting username: 'none' to treat the \
certificate purely as an admission gate, or 'common-name' to require the leaf's Subject \
Common Name to equal the username.",
);

pub const PERSIST_FAST_PATH_ORDER: Config<bool> = Config::new(
"persist_fast_path_order",
false,
Expand Down Expand Up @@ -452,6 +484,9 @@ pub fn all_dyncfgs(configs: ConfigSet) -> ConfigSet {
.add(&OIDC_GROUP_ROLE_SYNC_ENABLED)
.add(&OIDC_GROUP_CLAIM)
.add(&OIDC_GROUP_ROLE_SYNC_STRICT)
.add(&MTLS_CLIENT_CA)
.add(&MTLS_MODE)
.add(&MTLS_IDENTITY_BINDING)
.add(&PERSIST_FAST_PATH_ORDER)
.add(&ENABLE_S3_TABLES_REGION_CHECK)
.add(&ENABLE_MCP_AGENT)
Expand Down
3 changes: 3 additions & 0 deletions src/authenticator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ publish = false

[dependencies]
jsonwebtoken.workspace = true
anyhow.workspace = true
mz-adapter = { path = "../adapter", default-features = false }
mz-adapter-types = { path = "../adapter-types", default-features = false }
mz-auth = { path = "../auth", default-features = false }
mz-dyncfg = { path = "../dyncfg" }
mz-frontegg-auth = { path = "../frontegg-auth", default-features = false }
mz-ore = { path = "../ore", features = ["assert"] }
mz-pgwire-common = { path = "../pgwire-common", default-features = false }
openssl.workspace = true
reqwest.workspace = true
tokio-postgres.workspace = true
serde.workspace = true
Expand Down
Loading
Loading