Security modes¶
Every firmware artifact has a security_mode field that describes the
level of trust assurance applied during OTA delivery. Set it in the
manifest sidecar at upload time.
Modes¶
basic (default)¶
Transport security via HTTPS plus a SHA-256 checksum on the artifact.
The OTA check response includes "checksum": "<sha256>" and
"size": <bytes>. The device should verify both after download and abort
the update if either mismatches; do not flash an artifact whose checksum
does not match.
Suitable for: prototyping, hobby projects, and internal fleets where code-signing infrastructure is not yet in place.
token¶
Per-device token authentication at check-in time.
When security_mode: "token" is set on an artifact, the OTA engine
enforces that the device must authenticate with a
per-device token. A device presenting only
a project token receives {"update_available": false, "status": "token_required"}
and no firmware URL.
No change to the firmware binary is required; the security upgrade is
entirely at the protocol level (the Authorization header).
Suitable for: production fleets that require per-device authentication and auditability.
signed¶
Firmware signed with a project-scoped Ed25519 private key that only you hold. Two independent verifications protect the fleet:
- At upload: the server verifies the signature in
signing_metadataagainst one of the project's registered public keys before the artifact is accepted. Uploads with a missing, invalid, or revoked-key signature are rejected outright; no build number is consumed. - On device (essential): the OTA check response includes
signing_key_id,signature_algorithm, andsignature(base64). The device must verify the signature over the exact downloaded bytes against its pinned public key before writing to flash. A tampered image is rejected before any flash operation begins.
The signature covers the raw binary bytes exactly as delivered from the pre-signed URL. Register keys in project settings (Advanced mode) or via the developer API; SimpleOTA stores only the public key.
On Arduino, SimpleOTAClient v0.4.0+
performs the device-side verification automatically once you pin the
public key with setSigningPublicKey(). ESP-IDF and custom integrations
verify manually; see the guide below.
See the full signed firmware guide for key generation, CI signing commands, and device-side verification code.
Suitable for: commercial fleets where devices must never flash a binary that was not approved by the key holder, even if an account or upload credential is compromised.
How modes are matched¶
security_mode is a compatibility dimension in the OTA decision engine:
an artifact is only offered to a device when the two values are exactly
equal, or either side is blank. A device that never reports a mode
matches every artifact. The rule is symmetric, which has consequences in
both directions:
| Device reports | basic artifact |
token artifact |
signed artifact |
|---|---|---|---|
| (nothing) | offered | offered | offered |
basic |
offered | not offered | not offered |
token |
not offered | offered | not offered |
signed |
not offered | not offered | offered |
What this means in practice:
- A
basicdevice can never receive asignedartifact. Upgrading a fleet to signed therefore goes through one lastbasicupload whose firmware pins the key and switches the reported mode; see the migration recipe. - A
signeddevice can never receive abasicartifact. Once your fleet reportssigned, every subsequent upload must be signed; there is no quiet fallback to unsigned releases (that is the point). - A blocked device does not error. It receives a normal
no_compatible_buildresponse and simply stays on its current build. After changing modes, watch the project device list for devices stuck on old builds; they are the ones still reporting the previous mode.
Choosing a mode¶
| Deployment | Recommended mode |
|---|---|
| Prototyping / hobby project | basic |
| Production fleet, no code-signing infrastructure | token |
| Production fleet with key management | signed |
Setting the mode¶
In your manifest sidecar:
{
"framework": "arduino",
"version_label": "1.4.2",
"chip_family": "esp32",
"security_mode": "token"
}
Valid values are basic, token, and signed. Omitting the field
defaults to basic.
Related¶
- Device tokens: required for
tokenmode - Manifest schema: full sidecar reference
- Authentication: token acceptance matrix