Trust boundaries
Key storage by client
Read Client patterns for the matching flows.
Tickets
- The raw ticket is returned once by
POST /flash/downloads. - Firmngin stores only the SHA-256 hash.
- A ticket is bound to the workspace, firmware, and flash session.
- A ticket expires after five minutes or on first use, whichever comes first.
- A redeemed ticket returns
410on a second request.
Artifact code binding
The API key can be limited to specific artifact codes:- Empty binding: all signed firmware in the workspace.
- Filled binding: only the selected artifact codes.
Verify before you flash
- Download the binary with the ticket.
- Compute SHA-256 and compare it with the manifest and
X-Firmware-Sha256. - Verify
X-Firmware-Signaturewith the public key pinned in the app. - Compare the manifest target board and model with the connected device.
- Compare the version and security version with the device.
- Show the version, target, and SHA-256 to the user and ask for confirmation.
- Flash.
Temp files
If the app writes the binary to a temp folder:- Use a private folder with owner-only permissions (
0700on Linux and macOS). - Create the file with owner-only permissions (
0600) and a random name. - Open with
O_NOFOLLOWon platforms that support it. - Hash while writing, then verify the final size and digest.
- Keep the verified bytes in memory, or keep the same file descriptor open and verify again immediately before flashing.
- Delete the file after the flash.
Advisory reports
POST /flash/sessions/{id}/report records what the app observed:
successorboot_failed- reported version
- the session nonce
boot_failed and rolled_back; a device-origin success event is not implemented yet, so treat an app success report as unverified. If the device is offline, the dashboard shows the session as reported by the app, not as device-confirmed.
Limits and abuse controls
- Ticket creation and download are rate-limited.
- Successful downloads are metered through
ota_downloads. - API keys can be revoked at any time; revoked keys stop working on the next request.
- A ticket cannot be reused after it is redeemed.
Security checklist
- API key scope is
ota:read, not a broader scope. - Artifact-code binding is set when the app should only flash one product family.
- Firmware public key is pinned in the app.
- The app rejects unsigned artifacts.
- The app verifies SHA-256 and signature before flashing.
- Temp files use private permissions and random names.
- The device verifies the signature at boot.
- The app treats reports as advisory, not as device truth.