skip to content

What are Spring Boot SSL bundles (spring.ssl.bundle) and why use them for the embedded server?

level: seniorimportance: should knowfreq 30%

answer

  1. spring.ssl.bundle.jks / .pem named material
  2. server.ssl.bundle=<name> ties connector to it
  3. PEM = cert/key files directly, no keystore
  4. SslBundles bean -> getBundle -> SSLContext
  5. reuse inbound + outbound, enables hot reload

basics

~10 s

SSL bundles (Spring Boot 3.1+) are named, reusable sets of TLS material and options defined under spring.ssl.bundle.jks.* or .pem.*. The connector references one via server.ssl.bundle=<name>, so the same config is shared and centrally managed.

solid answer

~40 s

Before 3.1, TLS config was scattered across server.ssl.* and duplicated for each client (RestTemplate, WebClient, datastores). SSL bundles centralize it: you define a named bundle under spring.ssl.bundle.jks.<name> (keystore/truststore files) or spring.ssl.bundle.pem.<name> (PEM cert/key files directly, no keystore needed), including options like enabled-protocols and ciphers and a protocol. The embedded connector then just says server.ssl.bundle=<name>. The same bundle can be injected as an SslBundle via the SslBundles bean and applied to outbound clients, giving one source of truth. PEM bundles are especially handy because Kubernetes/cert-manager and Let's Encrypt emit PEM files, so you skip converting to a keystore. Bundles are also the gateway to hot-reloadable certificates (reload-on-update), which the legacy server.ssl.key-store path cannot do.

code

yaml · 16 lines
yaml
spring:
  ssl:
    bundle:
      pem:
        web:
          keystore:
            certificate: "file:/etc/tls/tls.crt"
            private-key: "file:/etc/tls/tls.key"
          truststore:
            certificate: "file:/etc/tls/ca.crt"   # for peer/mTLS trust
          options:
            enabled-protocols: [TLSv1.3, TLSv1.2]
          reload-on-update: true
server:
  ssl:
    bundle: web    # embedded connector uses the 'web' bundle

go deeper

for a junior

Know a bundle is a named, reusable TLS config referenced by server.ssl.bundle.

for a middle

Distinguish JKS vs PEM bundles and know PEM avoids keystore conversion.

for a senior

Explain the SslBundles bean and reuse across inbound + outbound clients.

for a principal

Standardize bundles as the org's single TLS-material source and the enabler for zero-downtime rotation.

## The problem bundles solve Historically TLS material was configured independently everywhere it was needed: `server.ssl.*` for the inbound connector, plus separate keystore/truststore wiring for `RestTemplate`, `WebClient`, mail, Redis, Kafka, etc. Duplication meant rotation and hardening had to be repeated per consumer. **SSL bundles** (introduced in Spring Boot 3.1) make TLS material a *named, first-class, reusable unit*. ## Two bundle flavors - **JKS/PKCS12 bundles** — `spring.ssl.bundle.jks.<name>`: reference keystore and/or truststore files (the classic container format). - **PEM bundles** — `spring.ssl.bundle.pem.<name>`: reference **PEM-encoded certificate and private-key files directly**, no keystore file required. This matches how cert-manager, Let's Encrypt, and cloud secret mounts deliver certs, eliminating a `keytool` conversion step. Each bundle has: - `keystore` (with `certificate`, `private-key`, `private-key-password`, or for JKS `location`/`password`/`type`), - `truststore` (peer-verification material, for mTLS or outbound trust), - `options.enabled-protocols` and `options.ciphers`, - `protocol` (default TLS), - `reload-on-update` (enables certificate hot-reload — see the reload topic). ## Wiring to the embedded connector ```yaml server: ssl: bundle: web # <-- reference the named bundle instead of key-store spring: ssl: bundle: pem: web: keystore: certificate: "file:/etc/tls/tls.crt" private-key: "file:/etc/tls/tls.key" options: enabled-protocols: [TLSv1.3, TLSv1.2] ``` When `server.ssl.bundle` is set, Spring Boot resolves the bundle and applies it to whichever embedded server is active. You do **not** also set `server.ssl.key-store` — the bundle supplies the material. ## Programmatic access Spring Boot registers an **`SslBundles`** bean and a `DefaultSslBundleRegistry`. Inject it and call `sslBundles.getBundle("web")` to get an `SslBundle`, from which `createSslContext()` / `getManagers()` produce a `javax.net.ssl.SSLContext`, `KeyManager[]`, `TrustManager[]`. Many client builders accept an `SslBundle` directly (e.g. `RestClient.Builder`/`ClientHttpRequestFactorySettings`, `WebClient` via connector config), so the same named material secures both inbound and outbound TLS. ## Gotchas - Setting **both** `server.ssl.bundle` and `server.ssl.key-store` is contradictory — use the bundle form exclusively for that connector. - PEM `private-key` must be an unencrypted key or you must supply `private-key-password`; formats are PKCS#8/PKCS#1 PEM. - A bundle name is global; referencing an undefined bundle fails fast at startup. - Bundles unlock **hot reload** (`reload-on-update`), which the legacy `server.ssl.key-store` cannot do — a key reason to migrate. ## When to use Use bundles for any non-trivial deployment: containerized apps with mounted PEM certs, services needing the same trust material inbound and outbound, mTLS, or anywhere zero-downtime cert rotation matters. For a throwaway demo the legacy `server.ssl.key-store` is still fine.

  • How do you use the same TLS material a bundle defines for an outbound WebClient/RestClient call?
    Inject the SslBundles bean, call getBundle("web") to get an SslBundle, and pass it to the client builder (or derive an SSLContext via createSslContext()). This shares one source of truth for inbound and outbound TLS.
  • Why are PEM bundles convenient in Kubernetes?
    cert-manager and TLS secrets mount PEM cert and key files directly. PEM bundles consume those files as-is, so you skip converting them into a JKS/PKCS12 keystore with keytool.

saying these in an interview costs you the question

  • Thinking bundles require a keystore file — PEM bundles use cert/key files directly.
  • Setting both server.ssl.bundle and server.ssl.key-store on one connector.
  • Believing bundles are only for inbound TLS (they also secure outbound clients).
  • Claiming SSL bundles existed before Spring Boot 3.1.

context