Skip to content

Security & Authentication

LoomCache provides two independent security mechanisms: TLS (or mutual TLS, mTLS) at the transport layer, and authorization based on roles or certificate common names (CNs) at the message-handler layer. Both are off by default outside production; production startup requires TLS/mTLS and auth. TLS is configured through TlsConfig or the Spring Boot loomcache.tls.* properties. Authorization is configured through AuthConfig. The Spring Boot loomcache.auth.* binding covers gateway trust, role maps, certificate credential selection, and certificate CN permission maps, while token and JAAS/LDAP/Kerberos server auth backends require direct AuthConfig or direct properties/YAML configuration.

mTLS Internal Network

mTLS Handshake + RBAC + Audit Logging

Java Client
Presents client cert
CN=orders-api
TLS Listener
Negotiated mTLS
Execution
RBAC + AuditLog
[Client] Opening binary connection with client certificate CN=orders-api.eu-west.prod.lan

Configure TLS through the TlsConfig builder:

TlsConfig tls = TlsConfig.builder()
.enabled(true)
.keyStorePath(Paths.get("/etc/loomcache/tls/keystore.p12"))
.keyStorePassword(System.getenv("KEYSTORE_PASSWORD"))
.keyStoreType("PKCS12")
.trustStorePath(Paths.get("/etc/loomcache/tls/truststore.p12"))
.trustStorePassword(System.getenv("TRUSTSTORE_PASSWORD"))
.trustStoreType("PKCS12")
.requireClientAuth(true) // mTLS
.protocols(List.of("TLSv1.3", "TLSv1.2"))
.provider(TlsProvider.JDK) // JSSE; required for FIPS-capable deployments
.revocationCheckingEnabled(true) // required in production
.revocationSoftFail(false) // fail closed on CRL/OCSP errors
.certExpirationWarningDays(30)
.certExpirationCriticalDays(7)
.build();

For deployments that need different TLS material per traffic role, EndpointTlsConfig carries member-to-member, member-to-client, and WAN endpoint configurations:

EndpointTlsConfig endpointTls = EndpointTlsConfig.builder()
.defaults(tls)
.memberTlsConfig(memberTls)
.clientTlsConfig(clientTls)
.wanTlsConfig(wanTls)
.build();

Spring Boot exposes the same split as loomcache.tls.member.*, loomcache.tls.client.*, and loomcache.tls.wan.*. Each endpoint inherits the global loomcache.tls.* settings and overrides only the fields it sets. The current binary listener remains a single socket and uses the member endpoint config at runtime. Direct production startup rejects distinct client/WAN endpoint TLS settings until dedicated inbound listeners exist; use identical endpoint settings for a single-process node, or terminate/split listeners outside the process.

Under the production profile, direct properties/YAML loaders and Spring Boot binding still require loomcache.tls.enabled=true explicitly. Once TLS is enabled, omitted mTLS/revocation booleans resolve to production-safe values: mTLS required, revocation checking enabled, and revocation soft-fail disabled. Startup still rejects missing key/trust material and explicit insecure values.

The current binary listener initializes its SSLContext at startup, so rotate production certificates with a rolling restart.

LoomCache is not a FIPS-validated cryptographic module. The shipped blocking client/server socket transports delegate TLS, keystore handling, random generation, signatures, and cipher operations to the configured Java security provider. That means a FIPS-controlled deployment depends on the runtime cryptographic module and its CMVP certificate, not on a LoomCache product certificate.

FIPS 140-3 superseded FIPS 140-2, and CMVP no longer accepts new FIPS 140-2 validation submissions. Active FIPS 140-2 modules remain usable for new systems until September 21, 2026; after that, the certificates move to the Historical list and are for existing systems only.

For FIPS-controlled environments:

  1. Use a JDK or JSSE security provider backed by a CMVP Active FIPS 140-3 module, or by an accepted FIPS 140-2 module before its September 21, 2026 transition date.
  2. Set TlsConfig.provider(TlsProvider.JDK) or loomcache.tls.provider=JDK.
  3. Do not use OPENSSL or OPENSSL_REFCNT unless you are using an explicit Netty TLS integration and your exact Netty/native TLS distribution is independently covered by the certificate and security policy you intend to cite.
  4. Pin direct TlsConfig.cipherSuites to the exact set of suites approved by the module’s security policy. LoomCache filters unsafe suite families by default, but it does not enforce a positive FIPS-approved allowlist automatically — the operator must supply an explicit cipherSuites list rather than relying on the default set. Spring Boot property binding does not currently expose a loomcache.tls.cipher-suites property, so Spring deployments that require an explicit allowlist need direct TlsConfig customization or provider-level disabled algorithms.
  5. Configure provider order, FIPS mode, DRBG/random source, keystore type, disabled algorithms, protocols, and cipher suites according to the chosen module’s security policy.
  6. Keep the CMVP certificate number, module version, JVM build, operating system, provider files, JVM flags, and LoomCache TLS configuration in the deployment evidence package.

Primary references: NIST FIPS 140-3 transition and NIST CMVP.

The following example creates a private CA and issues a node certificate with DNS/IP subject alternative names and both serverAuth and clientAuth extended key usage:

Terminal window
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 3650 -key ca-key.pem -out ca-cert.pem \
-subj "/O=LoomCache/CN=loomcache-ca"
openssl genrsa -out node-1-key.pem 4096
openssl req -new -key node-1-key.pem -out node-1.csr \
-subj "/O=LoomCache/CN=node-1.eu-west.prod.lan"
cat > node-1.ext <<'EOF'
subjectAltName = DNS:node-1.eu-west.prod.lan,DNS:loomcache-health.eu-west.prod.lan,IP:192.0.2.10
extendedKeyUsage = serverAuth,clientAuth
keyUsage = digitalSignature,keyEncipherment
EOF
openssl x509 -req -in node-1.csr -CA ca-cert.pem -CAkey ca-key.pem \
-CAcreateserial -out node-1-cert.pem -days 365 -sha256 \
-extfile node-1.ext
umask 077
printf '%s' "$KEYSTORE_PASSWORD" > keystore.pass
printf '%s' "$TRUSTSTORE_PASSWORD" > truststore.pass
openssl pkcs12 -export -in node-1-cert.pem -inkey node-1-key.pem \
-out node-1.p12 -name node-1 -passout file:keystore.pass
keytool -import -file ca-cert.pem -alias ca \
-keystore truststore.p12 -storetype PKCS12 \
-storepass:file truststore.pass -noprompt
rm -f keystore.pass truststore.pass

Choose an enforcement style via AuthConfig:

When gatewayTrust=true is configured, LoomCache accepts gateway authentication messages from connections originating in the trustedGatewayAddresses set without requiring full mTLS client credentials. The role CSV carried inside the AUTH message is parsed by AuthConfig.parseRolesHeader using the configured roleSeparator, and the resulting role names are resolved against the server’s roles map. A trusted source IP is the gating mechanism — the cluster verifies the source address, not an HTTP header.

The gateway-trust mode is non-production only. Production preflight rejects gatewayTrust=true; use certificate-CN permissions through Spring binding, or direct token/JAAS configuration (including LDAP and Kerberos JAAS login modules), for production clusters.

The following example maps gateway-forwarded roles to permissions:

AuthConfig auth = AuthConfig.builder()
.enabled(true)
.gatewayTrust(true)
.trustedGatewayAddresses(Set.of("10.0.0.0/8"))
.rolePrefix("ROLE_")
.addRole("reader", Set.of())
.addRolePermissionConfig("reader", new AuthConfig.PermissionConfig("map", "*", Set.of("read")))
.addRole("writer", Set.of())
.addRolePermissionConfig("writer", new AuthConfig.PermissionConfig("map", "*", Set.of("read", "write", "remove")))
.addRole("admin", Set.of("*"))
.build();

When mTLS is enabled, authConfig.certPermissions maps exact certificate CNs or non-empty terminal-* CN prefixes to a CertPermissionMapper.PermissionLevel. The server validates each client certificate for extendedKeyUsage = clientAuth (OID 1.3.6.1.5.5.7.3.2) and keyUsage covering at least one of digitalSignature or keyEncipherment; certificates that fail either check are rejected.

There are three public client-facing permission levels:

RoleAllowed operations
READ_ONLYReads across maps, queues, sets, and topics; cluster info queries.
READ_WRITEAll READ_ONLY operations plus writes, deletes, and batches.
ADMINAdministrative auth tier; production safety guards still block partition/migration control and REST operator mutations unless the path is explicitly release-validated.

Patterns support exact matches and non-empty terminal-* prefixes such as svc-*; bare *, embedded wildcards, and regex patterns are rejected. Exact matches win first; otherwise the longest matching prefix wins.

During connection setup, the server binds authentication to a fresh per-connection nonce before evaluating credentials. In the production profile, authentication that is missing this binding or carries a mismatched nonce is rejected with REPLAY_DETECTED and the attempt is audited. In development, legacy unbound authentication is accepted with a warning to support controlled compatibility testing.

LoomCache defaults to modern TLS 1.3 suites and TLS 1.2 ECDHE-authenticated AEAD suites. Operator-supplied cipher lists are filtered to remove known-unsafe families such as legacy DES/3DES, CBC-only, RC4, export, null, anonymous, MD5, and static-RSA suites. The loomcache.tls.allowUnsafeCipherSuites system property bypasses this filter only outside the production profile and should be limited to controlled testing; production ignores the override and keeps unsafe suites disabled.

  • Executor task allowlist — in the production profile the distributed executor-service task handler (loomcache.executor.allowlist) defaults to empty, which denies all tasks. Set -Dloomcache.executor.allowlist.deny=true to force deny-all explicitly in non-production configurations. Entry processors are governed by the separate loomcache.entryprocessor.allowlist (also empty/deny-all by default in production). Operator-named fully qualified class names (FQCNs) are required to run tasks in production.
  • Auth brute-force lockout — authentication failures are tracked per user+mechanism key and per source address. These tuning keys are JVM system properties, not Spring Boot or loomcache.properties bindings. After -Dloomcache.auth.failure_lockout_threshold (default 5) failures within a -Dloomcache.auth.failure_lockout_window_ms (default 60 000 ms) window, further attempts from that key are rejected. After -Dloomcache.auth.connection_denial_close_threshold (default 3) consecutive denials on a single connection, the connection is force-closed.
  • Plaintext write-escalation denial — outside production, READ_WRITE and ADMIN roles over non-TLS connections receive FORBIDDEN; only READ_ONLY scoped access is permitted over plaintext. Production direct startup requires TLS and rejects plaintext application connections.
  • Client endpoint identification — outbound TLS connections (client and WAN) enforce HTTPS-style endpoint identification, so hostname validation is performed on every outbound socket.
  • Session timeout — idle authenticated sessions expire after JVM system property -Dloom.auth.sessionTimeoutMs (default 3 600 000 ms = 1 hour).
  • Kryo registration digest — the serializer computes a SHA-256 digest over its type-registration table; this digest is exchanged during the version handshake and verified on both sides before a connection is used for replication or client traffic.
  • Command-queue backpressure rejects overloaded requests with a server-busy response.
  • Spring Boot REST rate limiting can cap request rates when the Spring HTTP surface is enabled.
  • Server accept loops reject inbound connections that exceed the global or per-client-IP connection limit with a typed connection-limit error.
  • REST inputs are validated before controller execution.
  1. Generate a private CA; issue one keystore per node, one shared truststore.
  2. Enable TLS with requireClientAuth = true, revocationCheckingEnabled = true, and revocationSoftFail = false for production — Raft traffic is critical.
  3. Use CN-based certificate permissions, or direct token/JAAS/LDAP/Kerberos server auth configuration, for production authorization; keep gateway-forwarded roles out of production.
  4. Store keystore passwords in a secret manager — never in git.
  5. Rotate certificates with a rolling restart — the binary listener initializes its SSLContext at startup.
  6. Track certificate notAfter lifetimes externally and rotate before the certExpirationCriticalDays window (defaults: certExpirationWarningDays = 30, certExpirationCriticalDays = 7 on TlsConfig). These thresholds are configuration only — LoomCache does not currently emit a cert-expiration Prometheus gauge.

LoomCache is an independent open-source project. It is not affiliated with, endorsed by, or sponsored by Hazelcast, Inc. or by any other company whose products are named in this documentation. “Hazelcast” is a trademark of Hazelcast, Inc.; references to it are nominative and describe only migration and comparison. All other product and company names are trademarks of their respective owners and are used for identification purposes only.