-
Notifications
You must be signed in to change notification settings - Fork 0
mTLS Configuration
A small, dependency-free package (crypto/tls, crypto/x509 only) that
builds conservative TLS configurations for services you package with this
project's builder. It is not wired into the builder or into any consumer
automatically — the security.tls.minimum/security.mtls OCI labels
mentioned in CLI Reference are pure documentation
metadata; if you want real mTLS enforcement, your service imports and
calls this package itself.
type Options struct {
CAPEM []byte // PEM-encoded CA bundle
Certificates []tls.Certificate // from tls.LoadX509KeyPair or tls.X509KeyPair
ServerName string // client-side: expected server name
MutualTLS bool // server-side: require + verify client certs
}
func ClientConfig(options Options) (*tls.Config, error)
func ServerConfig(options Options) (*tls.Config, error)Returns a *tls.Config with:
-
MinVersion: tls.VersionTLS12- TLS 1.2 is the floor. -
No
MaxVersionset - deliberately left at Go's default (unset), which means TLS 1.3 is automatically enabled whenever both sides support it. This is a common mistake to get backwards: pinningMaxVersionto 1.2 "to be safe" actually prevents the connection from ever using the newer, stronger protocol version. -
RootCAsbuilt fromOptions.CAPEM(seecertificatePoolbelow). -
Certificatescopied (not aliased) fromOptions.Certificates, for client-certificate authentication if the server requires it. -
ServerNamepassed through for SNI / hostname verification.
-
Requires at least one certificate - returns an error immediately if
Options.Certificatesis empty. A TLS server with no certificate can't serve anything, so this fails fast instead of producing a config that would only break at the first handshake. - Same
MinVersion: tls.VersionTLS12, noMaxVersioncap, same reasoning asClientConfig. - If
Options.MutualTLSistrue:-
requires a non-empty CA bundle - returns an error if
CAPEMis empty, since mutual TLS with no way to verify client certificates would be a false sense of security. - sets
ClientAuth: tls.RequireAndVerifyClientCertandClientCAsto the parsed pool - every connecting client must present a certificate the server can verify against that bundle. There is no "request but don't require" mode exposed here; this package only offers the strict form.
-
requires a non-empty CA bundle - returns an error if
- An empty/nil
CAPEMreturns(nil, nil)- not an error. This letsClientConfigbe called with no custom CA bundle (falling back to the Go runtime's system trust store) while still surfacing a real error if a non-emptyCAPEMcontains no valid PEM certificates (pool.AppendCertsFromPEMreturningfalse).
caPEM, err := os.ReadFile("ca.pem")
if err != nil {
log.Fatal(err)
}
cfg, err := mtls.ClientConfig(mtls.Options{
CAPEM: caPEM,
ServerName: "internal-service.example",
})
if err != nil {
log.Fatal(err)
}
client := &http.Client{Transport: &http.Transport{TLSClientConfig: cfg}}cert, err := tls.LoadX509KeyPair("server.pem", "server-key.pem")
if err != nil {
log.Fatal(err)
}
caPEM, err := os.ReadFile("client-ca.pem")
if err != nil {
log.Fatal(err)
}
cfg, err := mtls.ServerConfig(mtls.Options{
Certificates: []tls.Certificate{cert},
CAPEM: caPEM,
MutualTLS: true,
})
if err != nil {
log.Fatal(err)
}
srv := &http.Server{TLSConfig: cfg, Addr: ":8443"}internal/mtls/config_test.go covers: minimum-version enforcement,
missing-certificate rejection in ServerConfig, missing-CA rejection when
MutualTLS is requested, and invalid-PEM rejection in the CA pool
builder. Run just this package's tests with:
go test ./internal/mtls -count=1(This exact invocation is also one of the explicit regression checks in
ci-quality.yml - see Testing and CI/CD.)
© 2026 CYPT71
platform-factory
Core
- Architecture and OCI Layout
- Next-generation Architecture
- Architecture Decision Records
- Security Model
- Threat Model and Residual Risks
- Independent Security Review Process
- CLI Reference
- Project Configuration and Dependency Freezing
- mTLS Configuration
- Meine Graal
CI/CD
Running an image
- Production Adoption Guide
- Dockerfile Consumer
- Local Dev (Podman/macOS)
- MicroVM Support
- MicroVM Administration
- Large-image streaming
Operating