Magnemite
Features help

Enrollment tokens

One shared secret that lets a factory-fresh box register itself and trade up for its own.

A device token is per-box and secret: it is what a box authenticates every socket and every download with. But a factory-fresh box has no token yet, and you are not going to paste hundred and ninety-nine by hand.

The enrollment token solves that. It is one shared secret that says "a box holding this is allowed to register itself". Flash the same one onto a whole batch; each box trades it for a device token of its own on first boot.

box boots ─► POST /api/enroll { enrollmentToken, serial, model, … }


          hub creates the Device row


box receives ◄─ its own deviceToken   ─► and deletes the enrollment
                                          token from its config

Where you get one

  • pnpm db:seed mints one on a fresh database and prints it once.
  • Afterwards: Settings → Enrollment tokens → New token, also shown once.

Only the sha256 is stored, so a token cannot be recovered, mint another instead.

Lost yours? Nothing breaks and there is nothing to recover.

What you can do with one

ControlEffect
Max usesA batch of 20 boxes can get a token good for exactly 20 enrollments.
Auto-approveEnrolled boxes sit as pending until you approve them, and receive no updates in the meantime.
RevokeStops further enrollments immediately. Boxes enrolled are unaffected, they have own tokens now.

Why the box deletes it

Once the box has its own device token, the enrollment token is dead weight with real blast radius, anyone holding it can register more devices. The agent rewrites config.json without it as the last step of a successful enrollment, so a stolen box gives up only itself.

Device tokens

  • Generated by the hub, handed back once, stored on the box.
  • Only the sha256 is kept server-side.
  • Sent as a bearer token on the WebSocket handshake and on every /files/* request, which Caddy checks with the hub through forward_auth before serving a byte.
  • Revoking a device (in the admin) invalidates it; the box's socket drops and its downloads start returning 401.

On this page