Skip to main content

Certificate‑based (mTLS)

mTLS is configured per interface (listener) in NetworkManager.yaml.
Keystores, trust stores, and revocation settings live on the interface because certificate issuance/rotation/CRLs are managed outside MAPS. MAPS provides the TLS plumbing (via SslContext) and, optionally, a JAAS realm to surface client‑cert identity.


Scope​

  • Where: on listeners (e.g., MQTT/AMQP/REST) that use ssl:// or https:// URLs.
  • What: server keypair, client trust anchors, CRL polling, client‑cert requirement.
  • Not in: AuthManager.yaml (global).

Per‑interface TLS configuration (NetworkManager.yaml)​

- name: "MQTT over TLS (mTLS)"
url: "ssl://0.0.0.0:8883/"
protocol: mqtt
auth: ssl # optional JAAS realm if you map client certs to identities
tls:
protocol: "TLSv1.3"
requireClientAuth: true

# Server keypair (keystore)
keyStore:
alias: "server-cert"
type: "JKS"
path: "/opt/maps/.security/server.jks"
store_passphrase: "CHANGE_ME"
passphrase: "CHANGE_ME" # key password if different from store
managerFactory: "SunX509"

# Client trust anchors (trust store)
trustStore:
alias: "root-ca" # optional default alias
type: "JKS"
path: "/opt/maps/.security/truststore.jks"
store_passphrase: "CHANGE_ME"
managerFactory: "SunX509"

# Certificate revocation
crlUrl: "http://crl.example.com/root-ca.crl"
crlInterval: "360000" # ms between CRL refreshes

Same pattern applies to other listeners (e.g., AMQP or REST/HTTP).

- name: "REST API over HTTPS (mTLS)"
url: "https://0.0.0.0:8443/"
protocol: rest
auth: ssl
tls:
protocol: "TLSv1.3"
requireClientAuth: true
keyStore: { ... }
trustStore: { ... }
crlUrl: "http://crls.pki.goog/gts1c3/zdATt0Ex_Fk.crl"
crlInterval: "360000"

The keys mirror what SslHelper.createContext("TLSv1.3", properties, ...) expects in tests: keyStore, trustStore, crlUrl, crlInterval, managerFactory, etc.


Optional: map client certificates to identities (JAAS)​

If you want MAPS to expose the TLS client identity to auth/ACLs, add a JAAS realm and reference it with auth: ssl:

SSLAuthConfig {
io.mapsmessaging.security.jaas.SSLCertificateLoginModule Required
debug=true;
};
SecurityManager:
- ssl: SSLAuthConfig

This enables per‑interface auth decisions using fields from the client certificate (e.g., subject DN, SANs).


Field reference (TLS block)​

KeyWhereDescription
tls.protocolinterfaceTLS protocol version (e.g., TLSv1.3).
tls.requireClientAuthinterfacetrue to require client certificates (mTLS).
tls.keyStore.*interfaceServer keystore: type, path, store_passphrase, passphrase (private key), alias, managerFactory.
tls.trustStore.*interfaceTrust store for client certs (CAs): type, path, store_passphrase, alias (optional), managerFactory.
tls.crlUrlinterfaceHTTP(S) URL for a CRL to check revocation.
tls.crlIntervalinterfaceCRL refresh interval in ms.

Notes & best practices​

  • Manage certificates, CAs, and CRLs outside MAPS; mount keystores as read‑only volumes where possible.
  • Prefer TLSv1.3 and modern CAs. Keep trust stores minimal (least privilege).
  • If using multiple client CAs, consolidate into a dedicated truststore for the interface.
  • Rotate server keys by replacing the keystore file and restarting the listener.
  • For high‑frequency revocation needs, consider shorter crlInterval or OCSP (if/when available in your PKI).

Troubleshooting​

  • Handshake fails: confirm keystore/truststore paths and passphrases; check that client cert chains to a trusted CA.
  • Client rejected: ensure requireClientAuth: true and the client presents a certificate with a valid chain and non‑revoked status.
  • Wrong server cert: check alias in keyStore and that it refers to a key entry (not a CA cert).
  • Revocation errors: verify crlUrl availability and increase crlInterval if your CRL server rate‑limits.

DTLS (for UDP protocols: CoAP, MQTT‑SN)​

MAPS also supports DTLS on UDP‑based listeners using the same keystore/truststore/CRL model.

CoAP over DTLS​

- name: "CoAP over DTLS"
url: "coaps://0.0.0.0:5684/" # CoAP Secure (UDP/DTLS)
protocol: coap
auth: ssl
tls:
protocol: "DTLSv1.2" # DTLS protocol version
requireClientAuth: true
keyStore:
alias: "server-cert"
type: "JKS"
path: "/opt/maps/.security/server.jks"
store_passphrase: "CHANGE_ME"
passphrase: "CHANGE_ME"
managerFactory: "SunX509"
trustStore:
type: "JKS"
path: "/opt/maps/.security/truststore.jks"
store_passphrase: "CHANGE_ME"
managerFactory: "SunX509"
crlUrl: "http://crl.example.com/root-ca.crl"
crlInterval: "360000"

MQTT‑SN over DTLS​

- name: "MQTT‑SN over DTLS"
url: "dtls://0.0.0.0:1885/" # Generic DTLS UDP listener
protocol: mqtt-sn
auth: ssl
tls:
protocol: "DTLSv1.2"
requireClientAuth: true
keyStore: { ... }
trustStore: { ... }
crlUrl: "http://crl.example.com/root-ca.crl"
crlInterval: "360000"

Notes

  • DTLS uses UDP; ensure the corresponding ports (e.g., 5684 for CoAP Secure) are open for UDP.
  • The keystore/truststore/CRL settings are identical to the TLS examples above; only the protocol changes to DTLSv1.2 (or later if supported).
  • Client certificate mapping via the ssl realm works the same way for DTLS listeners.