doc: design for mutual TLS client authentication - #38419
Draft
jubrad wants to merge 1 commit into
Draft
Conversation
jubrad
force-pushed
the
mtls-design-doc
branch
from
August 23, 2026 04:00
57564f8 to
ecb781f
Compare
Proposes mutual TLS as an admission gate for external SQL connections, as an alternative to IP-based network policies. Egress IPs are unstable behind NAT gateways and cloud NAT pools, an IP is not an identity, and an allowlist has no rotation or revocation story. The obstacle specific to Materialize is balancerd, which terminates TLS and opens a separate pgwire connection to environmentd, so the process that sees the client certificate has no tenant configuration and the process with the configuration never sees the certificate. The design separates proof of possession from trust evaluation. The handshake proves the client holds the leaf's private key and only the terminating proxy can obtain that proof, but judging the issuer is a pure function of a chain and a set of trust anchors. balancerd therefore forwards the chain and environmentd judges it, so balancerd never learns any tenant's certificate authority and stays stateless. environmentd honours a forwarded chain only from a peer that authenticates against a configured proxy authority. Also records a three phase roadmap: system parameters with environmentd enforcing, then edge filtering at balancerd over a cacheable API, then CREATE CERTIFICATE AUTHORITY for per-authority scoping. Alternatives cover the catalog object syntax, edge filtering, TLS passthrough, and folding certificates into network policies. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
jubrad
force-pushed
the
mtls-design-doc
branch
from
August 24, 2026 20:00
ecb781f to
e12bb7f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Design doc only. The prototype is in a follow-up PR, which includes this commit.
The problem
The only way to restrict who may open a connection to an environment today is
a network policy: CIDR blocks matched against the client's IP. That fits poorly
with how customers run. Egress IPs are unstable behind NAT gateways, corporate
VPNs, and cloud NAT pools; an IP is not an identity, so anyone sharing an
allowlisted egress path inherits the admission decision; and an allowlist has no
expiry, rotation, or revocation.
The obstacle specific to us is
balancerd. Every cloud connection lands there,and it terminates TLS and opens a separate pgwire connection to
environmentd. So the client certificate is consumed by a process with nocatalog and no tenant configuration, while the process that has the
configuration never sees the certificate.
The proposal
Proof of possession and trust evaluation are separable. The handshake's
CertificateVerifyproves the client holds the leaf's private key, and onlywhoever terminated TLS can obtain that proof. Deciding whether the issuer is
acceptable is a pure function of a chain and a set of trust anchors, so it can
happen elsewhere.
balancerdtherefore obtains the proof and forwards the chain;environmentdjudges it against anchors from the catalog.
balancerdnever learns anytenant's certificate authority and stays stateless. A forwarded chain is
honoured only from a peer that authenticates as a trusted proxy, so an attacker
who can reach
environmentddirectly cannot forge one.Configuration is three system parameters, following the OIDC precedent.
Enforcement runs before the authenticator dispatches, so a rejected client is
never offered a password prompt, a SASL challenge, or a token exchange, which is
the property that makes this a real substitute for a network-level gate.
Roadmap
The doc records three phases:
environmentdenforces. Untrusted connections reach thedataplane and are rejected there.
balancerdover a cacheableenvironmentdAPI, sountrusted connections never reach the dataplane.
environmentdstaysauthoritative, making the edge a filter whose staleness degrades filtering
rather than correctness.
CREATE CERTIFICATE AUTHORITY, forFOR ROLESscoping, per-authorityidentity binding, named rotation, and audit.
Alternatives cover the catalog object's full syntax, edge filtering and its two
candidate distribution mechanisms, TLS passthrough, folding certificates into
network policies, and certificate-as-authenticator.
Notes for reviewers
Three things are worth disagreeing with:
CREATE CERTIFICATE AUTHORITY.requirecosts anoperator their webhook sources until the surfaces can be separated.
Release notes
No user-visible change; documentation only.