1. Today's topic
The identity lifecycle:
device produced
→ unique device_id
→ key pair
→ CSR
→ client certificate
→ mTLS
→ certificate rotation
→ revocation
→ decommissionThe main idea: every device must have its own cryptographic identity. A production station must not write one shared password or private key across the entire fleet.
2. Why this matters
The username=device/password=common scheme is dangerous:
a leak from one device -> compromise of all devices.The correct approach:
TC-0001842 -> unique private key -> unique client certificate -> mTLSIf a device is compromised, one certificate is revoked. Device identity must link:
device_id;
ESP32 MAC;
EC25 IMEI;
hardware revision;
client certificate fingerprint;
firmware release;
HIL result.3. Theory
A serial number is not a cryptographic identity
device_id, MAC, IMEI and STM32 UID are inventory attributes. A private key proves possession of an identity.
Key pair
private key: secret, never leaves the device;
public key: included in the certificate; the server verifies the signature.ECC P-256 is often convenient for embedded systems.
CSR
The device generates a key pair, creates a CSR and sends the public key plus proof to the CA. The CA issues a certificate and does not receive the private key.
Provisioning models
Poor approach:
one shared key/cert for the entire fleet.Better approach:
the station generates a unique key and writes it to the device.Even better:
a key pair is generated on the device or secure element;
the station receives only a CSR.A/B credential slots
Rotation must not overwrite active credentials:
identity_a ACTIVE
identity_b PENDINGThe new identity is activated only after proof-of-possession/a TLS probe.
Where to store an ESP32 private key
Options:
embedded in firmware: for laboratory use only;
NVS Encryption + Flash Encryption: better;
secure element ATECC608A: stronger;
new ESP32 SoC hardware with hardware-backed crypto: depends on the target.For the classic ESP32-WROOM-32U, an external secure element is a good option if the private key must not be extractable by software.
STM32
On STM32, a private key can be stored in protected internal Flash/TrustZone/Secure Storage or in STSAFE. STSAFE-A110 supports on-chip key generation and ECDSA operations without exposing the private key to the MCU.
4. Common mistakes
- One certificate for every device.
- Treating MAC/IMEI as proof of identity.
- Generating private keys in a shared CI job.
- Storing a private key in Git.
- Sending a private key to the backend instead of a CSR.
- Overwriting the active certificate without A/B slots.
- Deleting the old certificate before checking the new one.
- Disabling server verification because a client certificate is present.
- Storing a key in plaintext NVS.
- Writing a PEM key to a debug log.
- Not monitoring certificate expiry.
- Using one bootstrap token for an entire batch.
- Having no recovery path after credentials are lost.
5. A practical task for 30–60 minutes
Create DEVICE_IDENTITY_POLICY.md:
# Device identity policy
1. Every production device has a unique key pair.
2. A private key is never shared by multiple devices.
3. The backend receives CSR, never a device private key.
4. MAC, UID and IMEI are inventory attributes, not credentials.
5. Server certificate verification is always enabled.
6. Operational credentials are stored in A/B slots.
7. New credentials are tested before activation.
8. Old credentials are retained during a grace period.
9. Every credential has a generation and fingerprint.
10. Production private keys are never stored in Git or CI artifacts.
11. Lost credentials do not fall back to a common password.
12. Provisioning produces an auditable device record.Create a development CA and device certificate using OpenSSL:
# Editorial addition: development CA only; not a production provisioning workflow.
cat > device.ext <<'EOF'
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
extendedKeyUsage=clientAuth
subjectAltName=URI:urn:traffic-controller:device:TC-DEV-0001
EOF
openssl x509 -req -in TC-DEV-0001.csr -CA dev-ca.crt -CAkey dev-ca.key \
-CAcreateserial -out TC-DEV-0001.crt -days 365 -sha256 -extfile device.ext
openssl verify -purpose sslclient -CAfile dev-ca.crt TC-DEV-0001.crtOpenSSL x509: CSR signing and certificate extensions
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out dev-ca.key
openssl req -x509 -new -key dev-ca.key -sha256 -days 3650 \
-subj "/CN=Embedded Development CA" -out dev-ca.crt
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out TC-DEV-0001.key
openssl req -new -key TC-DEV-0001.key -subj "/CN=TC-DEV-0001" -out TC-DEV-0001.csrAdd a SAN:
subjectAltName=URI:urn:traffic-controller:device:TC-DEV-0001
keyUsage=critical,digitalSignature
extendedKeyUsage=clientAuthCheck:
openssl verify -CAfile dev-ca.crt TC-DEV-0001.crtAdd a CLI identity info command that displays fingerprint, issuer, SAN, generation and backend, but not the private key.
6. What to read or try next
- ESP-TLS client certificates, NVS Encryption and ATECC608A integration.
- STSAFE-A110 / X-CUBE-STSE01.
- Device provisioning audit records and CSR enrollment.
Criteria: Keep the private-key boundary explicit.
Exercise
Describe safe A/B credential rotation when identity_a is ACTIVE and identity_b is PENDING. State when the new identity becomes active and what must not be deleted prematurely.
Self-check criteria: Separate writing, testing and activation; retain distinct generations/fingerprints and do not expose a private key in diagnostics.
Show the supplied answer
Write the new credentials to the inactive/PENDING slot, validate proof-of-possession and a TLS probe, then activate the new identity. Do not overwrite the current active credentials or remove the old certificate before the new identity is checked; preserve the planned grace/recovery path.