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.