Part 7by Muhammad

PSK vs Certificate-based auth in MQTT: When to Use Each

PSK vs Certificate-based auth in MQTT

PSK vs Certificate-based auth in MQTT comes up any time you need to secure device connections while keeping manufacturing, onboarding and operations manageable. This comparison is for intermediate IoT and embedded engineers who already use MQTT (Message Queuing Telemetry Transport) and Transport Layer Security (TLS) but need to choose an authentication model that will scale across fleets.

Table of Contents

What you are actually choosing

In MQTT deployments, “authentication” usually means you authenticate the client to the broker at connection time, then optionally authorize what the client can publish or subscribe to (topics, wildcards, retained messages and so on). With TLS, you typically have three related choices:

  • Server authentication: the client validates the broker certificate (standard TLS). You almost always want this.
  • Client authentication: the broker authenticates the device, either with a pre-shared key (PSK) or a client X.509 certificate (mutual TLS or mTLS).
  • Application-level authentication: MQTT username/password, tokens (JWT), SAS tokens, custom auth, often still inside a TLS tunnel.

This post compares PSK-based TLS against certificate-based TLS client auth (mTLS) as the primary device identity mechanism. You can still combine either approach with MQTT authorization policies and per-topic access control lists (ACLs).

PSK vs Certificate-based auth in MQTT: the core comparison

Both approaches can provide strong security when implemented correctly, but they optimize for different constraints: manufacturing workflow, identity lifecycle, revocation semantics and platform interoperability.

DimensionPSK (TLS-PSK)Client certificates (mTLS with X.509)
Identity modelIdentity is usually an ID + shared secret. The secret must be provisioned to device and broker (or auth backend).Identity is a private key + certificate. Broker trusts a CA (Certificate Authority) and validates the certificate chain.
ProvisioningSimple: inject PSK per device, per batch or per product line.More moving parts: keypair generation, CSR (Certificate Signing Request) or manufacturing CA signing.
RotationHarder at fleet scale: you must update secrets on device and broker/backend.Natural: issue short-lived certs, rotate automatically, keep CA stable.
RevocationOften “revocation by database delete” works, but only if broker checks an auth backend each connect.Revocation via CRL (Certificate Revocation List) or OCSP is possible but often not used on constrained brokers. Many fleets instead use short cert lifetimes.
Broker supportInconsistent in MQTT brokers, especially managed cloud offerings. Some TLS stacks support PSK but brokers may not expose it.Widely supported across Mosquitto, EMQX, HiveMQ and many cloud IoT platforms.
Security blast radiusIf you reuse PSKs per batch or product line, compromise can affect many devices. Per-device PSKs reduce this but require stronger provisioning controls.Per-device unique private keys are standard. Compromise tends to be isolated to a single device identity.
Hardware secure element fitSupported by many secure elements as a symmetric secret, but you must handle PSK identity and retrieval carefully.Excellent fit: secure elements store private keys and perform signing without exposing keys.
FootprintLower handshake overhead and smaller credential storage.More handshake bytes and CPU for public-key operations, usually acceptable on modern MCUs with TLS acceleration or session resumption.
Compliance and auditCan be harder to audit lifecycle and prove identity provenance.PKI (Public Key Infrastructure) aligns with standard enterprise practices and audit trails.

Security properties that matter in MQTT deployments

Threat model recap

For IoT MQTT, the practical threats tend to be:

  • Credential extraction from device flash, debug ports or memory (especially in the field).
  • Broker impersonation via DNS spoofing or rogue Wi-Fi. Client must validate broker identity.
  • Device impersonation (cloned devices) using leaked credentials.
  • Fleet-wide compromise from shared secrets, weak manufacturing controls or poor rotation.
  • Authorization bypass: device authenticates correctly but is allowed to publish/subscribe too broadly.

PSK security properties

TLS-PSK can be strong, but only if you meet these conditions:

  • Unique PSK per device (or at least per small cohort). Shared PSKs across many devices increase blast radius.
  • Secure provisioning: the PSK must never leak from manufacturing logs, test fixtures or over debug ports.
  • Strong PSK entropy: generate 16 to 32 bytes from a cryptographically secure RNG, do not derive from serial numbers.
  • Server authentication still required: PSK alone does not automatically prevent broker impersonation unless you authenticate the server too (some PSK modes do not provide server identity in the same way as certificates). You need a robust approach to validate you are talking to the right broker.

PSK shines when you control both ends of the connection, you run your own broker and you want a simple device credential format. It gets tricky when you need to interoperate with cloud brokers that do not support TLS-PSK or you need robust identity lifecycle tooling.

Certificate-based (mTLS) security properties

With certificates, you typically:

  • Provision a unique private key on each device.
  • Issue a client certificate that identifies the device and is signed by a CA you control (or your platform controls).
  • Configure the broker to trust that CA and require client certificates.

This gives you well-understood properties:

  • Unique device identity is the default. Even if two devices share the same firmware, their keys differ.
  • Harder-to-clone if you use secure elements because the private key never leaves hardware.
  • Better interoperability with managed IoT offerings and enterprise security tooling.

The main risks are operational: managing PKI, certificate renewal, clock validity (notBefore/notAfter) and ensuring your broker enforces authorization beyond mere authentication.

Operational considerations (fleet scale, rotation and revocation)

Provisioning workflows

In practice, your choice often comes down to what your factory and onboarding pipeline can reliably do.

  • PSK provisioning: you inject a random secret and an identifier (psk_identity). You store the mapping in a backend database used by the broker or an authentication plugin.
  • Certificate provisioning: you create a keypair per device, then either sign it at manufacturing or have the device enroll on first boot using a bootstrap credential.

A common hybrid is: bootstrap with a factory PSK or claim code, then enroll for a device certificate using an enrollment service. That gives you simple manufacturing and strong long-term identity.

Rotation at scale

Rotation is where PSK often loses to certificates:

  • Rotate PSKs: you must change the secret on the device and in the broker auth database. If you rotate too aggressively, you risk bricking devices that miss the update window.
  • Rotate certs: you can issue a new certificate while keeping the private key stable or rotate both. Short-lived certs (days to months) reduce reliance on revocation lists.

For large fleets, certificate renewal can be automated using scheduled reconnects, device management jobs and enrollment endpoints.

Revocation realities

Revocation sounds straightforward, but each model has practical gotchas:

  • PSK: if the broker validates PSKs against a live database on each connect, “revocation” is immediate, delete the PSK record or mark it disabled. If you embed PSKs in broker config files and reload on a timer, revocation becomes operationally slower.
  • Certificates: CRLs or OCSP require distribution and checking. Many MQTT brokers can do CRL checking, but you must manage the CRL size and update cadence. Short-lived certs are often the simpler answer.

Authorization is still separate

Regardless of which side you pick in PSK vs Certificate-based auth in MQTT, you still need authorization policies:

  • Map identity (psk_identity or certificate subject/SAN) to allowed topic patterns.
  • Prevent wildcard subscriptions where not needed.
  • Constrain retained messages and shared subscriptions if your broker supports them.

Performance and footprint on embedded devices

Handshake cost

TLS-PSK avoids public-key operations during the handshake, so it can be faster and smaller on very constrained microcontrollers. Certificate-based mTLS uses ECDSA or RSA signatures and certificate chain parsing, which costs CPU and RAM.

That said, modern TLS stacks and cipher suites reduce the gap:

  • ECDSA + ECDHE is common and much lighter than legacy RSA handshakes.
  • Session resumption (tickets or session IDs) can make reconnects cheap for both PSK and certificates.
  • Hardware accelerators in secure elements or MCUs can offload ECDSA operations.

Credential storage

  • PSK: store 16 to 32 bytes plus identity, typically under 64 bytes.
  • Certificates: store private key (32 bytes for P-256) plus certificate(s). A DER-encoded device cert can be 500 to 1500 bytes, plus CA cert(s). In PEM, it is larger.

If your device has tight flash constraints, consider DER storage and keep CA chains short. Many devices only need the CA certificate used to sign the broker certificate (or a pinned broker public key), plus their own client cert and key.

Interoperability and platform support

Interoperability is often the deciding factor:

  • Self-hosted brokers: Mosquitto, EMQX and HiveMQ generally support mTLS well. PSK support depends on TLS library integration and configuration. Even when TLS supports PSK, the broker may not expose a clean way to map PSK identities to ACLs.
  • Managed IoT platforms: many require X.509 certificates (for example, AWS IoT Core style flows) or token-based auth over TLS. TLS-PSK support is uncommon.
  • Enterprise tooling: certificate issuance, auditing and device identity are often already solved by PKI products, making mTLS an easier sell to security teams.

If you expect to migrate brokers, use multiple environments or integrate with customer networks, certificate-based auth is usually safer from a compatibility standpoint.

Working code examples

The examples below use Mosquitto because it is common in labs and production. They illustrate how PSK and certificates look end-to-end: broker config plus a client connection.

Example 1: Mosquitto with TLS-PSK and a Paho client

Prerequisites: Mosquitto 2.x installed, OpenSSL installed, a Linux machine or Raspberry Pi. You will configure Mosquitto to accept PSK on a dedicated listener and connect with Python using Paho MQTT.

Step 1: Create a PSK file for Mosquitto

Generate a strong random PSK and store it in Mosquitto format (identity:hexkey).

# Generates a random 32-byte PSK and writes a Mosquitto PSK file entry (identity:hexkey)
PSK_IDENTITY="device-001"
PSK_HEX=$(openssl rand -hex 32)
echo "${PSK_IDENTITY}:${PSK_HEX}" | sudo tee /etc/mosquitto/pskfile
sudo chmod 600 /etc/mosquitto/pskfile
sudo cat /etc/mosquitto/pskfile

Step 2: Configure Mosquitto to listen with PSK

Create a minimal config that enables a PSK listener. Keep this separate from any certificate-based listeners so you can test cleanly.

# Mosquitto config: enable TLS-PSK listener on port 8884
# Save as /etc/mosquitto/conf.d/psk.conf
listener 8884
protocol mqtt

# Require TLS and use PSK file for client authentication
psk_file /etc/mosquitto/pskfile

# Optional: limit ciphers to PSK suites supported by your OpenSSL
# tls_version tlsv1.2
# ciphers PSK-AES128-CBC-SHA256

Restart Mosquitto:

# Restarts mosquitto so the PSK listener becomes active
sudo systemctl restart mosquitto
sudo ss -lntp | grep 8884

Step 3: Connect with Python (Paho MQTT) using PSK

Paho uses OpenSSL underneath. On some platforms, PSK support may be limited depending on the Python ssl module build. If your environment does not support PSK via Python, you can still validate the broker side with mosquitto_pub/mosquitto_sub if built with PSK support.

# Connects to a Mosquitto TLS-PSK listener and publishes a test message
import binascii
import paho.mqtt.client as mqtt

BROKER_HOST = "127.0.0.1"
BROKER_PORT = 8884
PSK_IDENTITY = "device-001"
PSK_HEX = ""  # Paste the hex key from /etc/mosquitto/pskfile
TOPIC = "lab/psk/test"

if not PSK_HEX:
    raise SystemExit("Set PSK_HEX to the hex key from your mosquitto pskfile")

psk_bytes = binascii.unhexlify(PSK_HEX)

client = mqtt.Client(client_id="psk-client-001", protocol=mqtt.MQTTv311)

# Configure TLS-PSK. This requires Paho + Python ssl with PSK enabled.
# If this fails, use mosquitto_pub/mosquitto_sub compiled with PSK support.
client.tls_set_context(None)
client.tls_set_psk(psk_bytes, PSK_IDENTITY)

client.connect(BROKER_HOST, BROKER_PORT, keepalive=60)
client.loop_start()

info = client.publish(TOPIC, payload="hello over TLS-PSK", qos=1)
info.wait_for_publish()

client.loop_stop()
client.disconnect()
print("Published to", TOPIC)

Operational note: with PSK you still need an authorization mapping. In Mosquitto, that typically means writing ACL rules keyed on psk_identity (which Mosquitto exposes as the username in some auth plugin setups) or using a custom plugin. Without good ACLs, all authenticated devices might share broad publish rights.

Example 2: Mosquitto with mutual TLS (client certificates) and a Paho client

This is the most portable pattern across MQTT brokers and aligns well with managed IoT platforms.

Step 1: Create a local CA, broker cert and client cert

This creates a minimal lab PKI. In production, you would use an internal CA, an IoT platform CA or an HSM-backed CA.

# Creates a local CA, signs a broker certificate and a client certificate for mTLS testing
set -euo pipefail
mkdir -p ~/mqtt-mtls-demo && cd ~/mqtt-mtls-demo

# 1) CA key and cert
openssl ecparam -name prime256v1 -genkey -noout -out ca.key
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \
  -subj "/CN=IoTSnacks Demo CA" -out ca.crt

# 2) Broker key and CSR
openssl ecparam -name prime256v1 -genkey -noout -out broker.key
openssl req -new -key broker.key -subj "/CN=localhost" -out broker.csr

# 3) Broker cert with SAN=localhost,127.0.0.1
cat > broker.ext << 'EOF'
subjectAltName=DNS:localhost,IP:127.0.0.1
extendedKeyUsage=serverAuth
keyUsage=digitalSignature,keyEncipherment
EOF

openssl x509 -req -in broker.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out broker.crt -days 825 -sha256 -extfile broker.ext

# 4) Client key and CSR
openssl ecparam -name prime256v1 -genkey -noout -out client.key
openssl req -new -key client.key -subj "/CN=device-001" -out client.csr

# 5) Client cert
cat > client.ext << 'EOF'
extendedKeyUsage=clientAuth
keyUsage=digitalSignature
EOF

openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out client.crt -days 825 -sha256 -extfile client.ext

echo "Generated: ca.crt, broker.crt/key, client.crt/key"

Step 2: Configure Mosquitto for mTLS

# Mosquitto config: TLS listener with required client certificates (mTLS)
# Save as /etc/mosquitto/conf.d/mtls.conf
listener 8883
protocol mqtt

cafile /home/youruser/mqtt-mtls-demo/ca.crt
certfile /home/youruser/mqtt-mtls-demo/broker.crt
keyfile /home/youruser/mqtt-mtls-demo/broker.key

# Require client certificates
require_certificate true
use_identity_as_username true

# Optional hardening
# tls_version tlsv1.2
# ciphers ECDHE-ECDSA-AES128-GCM-SHA256

Restart Mosquitto:

# Restarts mosquitto so the mTLS listener becomes active
sudo systemctl restart mosquitto
sudo ss -lntp | grep 8883

Step 3: Connect with Python (Paho MQTT) using client certificates

# Connects to a Mosquitto mTLS listener using a CA cert and a client certificate
import ssl
import paho.mqtt.client as mqtt

BROKER_HOST = "localhost"
BROKER_PORT = 8883
CA_CERT = "/home/youruser/mqtt-mtls-demo/ca.crt"
CLIENT_CERT = "/home/youruser/mqtt-mtls-demo/client.crt"
CLIENT_KEY = "/home/youruser/mqtt-mtls-demo/client.key"
TOPIC = "lab/mtls/test"

client = mqtt.Client(client_id="mtls-client-001", protocol=mqtt.MQTTv311)

client.tls_set(
    ca_certs=CA_CERT,
    certfile=CLIENT_CERT,
    keyfile=CLIENT_KEY,
    tls_version=ssl.PROTOCOL_TLS_CLIENT
)

# Verify broker certificate hostname (important when you use real DNS names)
client.tls_insecure_set(False)

client.connect(BROKER_HOST, BROKER_PORT, keepalive=60)
client.loop_start()

info = client.publish(TOPIC, payload="hello over mTLS", qos=1)
info.wait_for_publish()

client.loop_stop()
client.disconnect()
print("Published to", TOPIC)

Step 4: Tie identity to authorization

With use_identity_as_username true, Mosquitto uses the certificate subject CN as the username. You can then apply ACLs by username. Example ACL file:

# Mosquitto ACL: allow device-001 to only publish/subscribe under its own prefix
user device-001
topic readwrite devices/device-001/#

This pattern maps cleanly to “one device, one namespace” topic designs.

Decision matrix and recommendations

Use this matrix to decide quickly, then validate against your constraints.

Your constraintPrefer PSKPrefer certificates (mTLS)
Very constrained MCU, tight RAM/flash, no crypto accelerationYes, especially if you also control the broker environmentMaybe, but test handshake memory and parsing overhead
Need compatibility with managed IoT servicesNoYes
Large fleet with frequent credential rotation requirementsSometimes, but tends to be operationally painfulYes, automate cert renewal
Manufacturing pipeline cannot handle PKI todayYes as a bootstrap or interim solutionConsider enrollment later using a bootstrap credential
High risk of device extraction and cloningOnly with per-device PSK in a secure element and strong controlsYes, especially with secure element private keys
Need clean audit trails and enterprise security alignmentNoYes

Practical recommendations

  • If you can use mTLS, do it: for most production MQTT fleets, certificate-based device identity gives better interoperability and lifecycle tooling.
  • Use PSK when you own the full stack and need simplicity: PSK can be secure and fast for closed systems, especially for prototypes, gateways in controlled networks or short-lived deployments.
  • Consider PSK for bootstrap, certificates for steady state: bootstrap enrollment reduces manufacturing complexity while keeping long-term security properties strong.

Common pitfalls and hard-won lessons

Pitfall 1: Treating authentication as authorization

Whether you choose PSK or certificates, the broker must enforce topic-level permissions. Many incidents happen because every authenticated device can publish to devices/+/cmd or subscribe to #. Start with least privilege and only widen as needed.

Pitfall 2: Reusing PSKs across devices

Shared PSKs are tempting because they simplify database lookups and manufacturing, but they make device cloning trivial after one extraction. If you pick PSK, use per-device PSKs and protect them with secure storage.

Pitfall 3: Ignoring time and certificate validity

Certificates expire. Devices without reliable time can fail validation if you enforce strict notBefore/notAfter checks. Fix this by:

  • Using a time source (NTP over a trusted path, cellular network time, GPS or a gateway).
  • Using longer-lived certs on devices that cannot keep time, then relying on backend controls and rotation plans.
  • Designing an enrollment flow that can recover when time is wrong.

Pitfall 4: Not pinning or validating the broker identity

TLS only helps if the client verifies the broker certificate. For lab setups, developers often disable verification, then forget to re-enable it. In production, validate the broker chain or pin the broker public key depending on your operational model.

Pitfall 5: Overlooking broker side scaling

With PSK, a broker might perform a lookup in an external auth backend for each connect. With certificates, the broker validates signatures and chains. Test your peak reconnect storm scenario (power outage, cellular flap) and use connection rate limiting, session resumption and backoff on devices.

FAQ

Is MQTT username/password enough if I already use TLS?

It can be, but it depends on how you store and rotate credentials. MQTT username/password over TLS is common, but you still need robust per-device secrets, rotation and server-side authorization. Many teams prefer mTLS because it integrates better with hardware key storage and PKI tooling.

Does mTLS automatically encrypt payloads end-to-end?

No. TLS encrypts the transport between device and broker. If you need broker-to-cloud or broker-to-consumer end-to-end confidentiality, you must add application-level encryption.

Can I mix PSK devices and certificate devices on the same broker?

Yes, typically by using separate listeners (ports) with different TLS settings. Keep ACL logic consistent across both and avoid “temporary” broad permissions.

What should I choose for a gateway that talks to many sensors?

If the gateway is capable, use mTLS to the cloud broker. For the sensor-to-gateway link, PSK may be fine if the link is short-range and you tightly control onboarding, but still treat PSK reuse and rotation as first-class concerns.

When you evaluate PSK vs Certificate-based auth in MQTT, focus on identity lifecycle and interoperability as much as cryptography. PSK can be fast and simple in closed systems, but certificates usually win for large fleets, managed platforms and long-term maintainability. If you choose PSK, make it per-device and plan rotation early. If you choose certificates, automate enrollment and renewal and enforce topic-level authorization from day one.