Re-arm a demo box
A Roost box watches a sensing mesh around its signing boards. When the mesh is cut, a feedthrough is disturbed or the lid is opened, the box erases the keys that unlock its signing keys. Production boxes stay erased and are reinstalled at the factory.
A demo box can be brought back into service on site. The owner of the organization confirms the re-arm with a passkey seal, and Axowl returns a re-arm ticket that only that box, for that one attempt, accepts.
Re-arm flow
- Replace the mesh cartridge on the box.
- On the box controller run
rearm_client.py nonce. The box prints its box ID and a one-time number (nonce), plus a link to/dashboard/{slug}/roost-rearm?box=…&nonce=…. - The organization Owner opens that page and seals. The seal is bound to the organization, the box ID and the nonce.
- Axowl returns the ticket. Enter it on the box with
rearm_client.py apply --ticket <ticket>within 10 minutes. - The box checks the ticket signature, its own box ID and the nonce, then creates new keys. Each signing board enrolls again and the new signers are registered.
Endpoints
| Method · Route | Purpose |
|---|---|
POST /api/org/{slug}/roost/rearm-ticket | Issue a re-arm ticket. Body { box, nonce, stepUpAssertion }. Owner only. |
GET /api/roost/rearm-public-key | Public key the demo box pins: { alg: "ES256", publicKeyPem, fingerprint }. Anonymous. |
GET /api/roost/spec-sheet | Roost specification sheet, application/pdf (attachment Axowl-Roost-Specification.pdf). Any signed-in user; 401 otherwise. |
POST /api/org/{slug}/roost/rearm-ticket
box— 4 to 40 characters ofA–Z,0–9and-, exactly as the box prints it.nonce— 32 lowercase hex characters, exactly as the box prints it.stepUpAssertion— a passkey step-up with purposeroost.rearmand subjectStepUpPurpose.RoostRearmSubject(slug, box, nonce). Request the challenge fromPOST /api/passkey/stepup/optionswith that purpose and subject. A seal made for another box or another nonce is rejected.
Response 200:
{
"ticket": "eyJ2IjoxLCJ0eXAiOi....Qc2NMSUK...",
"box": "ROOST-0001",
"nonce": "404142434445464748494a4b4c4d4e4f",
"expiresAt": "2026-10-18T09:10:00Z",
"keyFingerprint": "SHA256:…"
}
| Status | error | When |
|---|---|---|
| 400 | INVALID_REARM_REQUEST | box or nonce is malformed |
| 401 | STEPUP_REQUIRED · STEPUP_FAILED | No seal, a seal from another user, or a seal bound to another box or nonce |
| 403 | OWNER_REQUIRED | The caller is a member but not the Owner |
| 404 | ROOST_DEVICE_NOT_FOUND | No box with that serial is bound to this organization |
| 503 | ROOST_REARM_DISABLED | The server has no re-arm signing key |
Every issued ticket is recorded as the audit event roost.rearm.ticket_issued with the box ID, nonce, expiry, key fingerprint and the seal proof (see the Axowl audit reference).