Magnemite
Features

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. A secret identity that a box authenticates every socket and every download with. A factory-fresh box has none, and you are not pasting two hundred by hand.

The enrollment token is one shared secret meaning "a box holding this may 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

Getting one

Settings → Enrollment → New token, shown once, only its sha256 is stored, so a lost token is not recovered, it is replaced. make seed also mints one on a fresh database.

ControlEffect
EnrolsBoxes, or a machine. A box token cannot bring a machine up, and vice versa.
Max usesA batch of 20 boxes gets a token good for exactly 20 enrollments.
Auto-approveOff, boxes sit pending until approved and receive nothing meanwhile.
RevokeStops further enrollments. Boxes already enrolled are unaffected.

Box tokens are for the manual path too, now

Fleet → Add boxes mints one token per box, writes it over adb and nobody ever sees it — so minting a box token here is for flashing a batch from an image, or for a box no network can reach. Those are single use and expire in a week.

Machine tokens are for the manual path only

Machines → Add machine mints its own, writes it into that machine's config over SSH and nobody ever sees it — so Enrols: A machine is needed only when provisioning a machine by hand. Such a token always auto-approves, and the form offers no switch: /internal/authz refuses an unapproved device, so a machine that enrolled pending would get a bare 401 from the edge on its first self-update with nothing anywhere to explain it.

The agent rewrites config.json without the token as the last step of a successful enrollment.

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 the edge checks with the hub through forward_auth before serving a byte.
  • Revoking a device invalidates it: the socket drops and downloads start returning 401.

Moving a box to another hub

A device token is a row in that hub's database. Point an enrolled box at a different hub and the handshake is rejected, and the box does not recover on its own, because Enroll runs only at startup, and only when the token is empty. It retries the same dead token forever, a minute apart.

device token rejected > re-enroll this box

The box reached a hub that has never heard of its token. Either it was re-pointed at a new one, or its device row was deleted. Nothing on the box fixes this by itself, the config has to be replaced by hand.

Read what it points at now:

adb shell su -c 'cat /data/adb/magnemite/config.json'

An enrolled box shows a deviceToken and no enrollmentToken.

The agent deletes the second the moment it has the first. Replace both, along with the URL:

adb push config.json /data/local/tmp/config.json
adb shell su -c 'mv /data/local/tmp/config.json /data/adb/magnemite/config.json'
adb shell su -c 'chmod 600 /data/adb/magnemite/config.json'

The file is the same shape as a factory-fresh one: serverUrl, a fresh enrollmentToken from the new hub, no deviceToken. Then restart the agent (service.sh brings it back within ten seconds and it enrolls against the new hub) or reboot the device, it works too.

adb shell su -c 'killall magnemite-agent'

The restart is not optional

The config is read once, at startup. Rewriting the file under a running agent changes nothing, it keeps the URL and the token it loaded. That is the confusing half: the file on disk is already correct and the box still will not connect.

To drop a box's identity without writing a new config, delete the file instead:

adb shell su -c 'rm -f /data/adb/magnemite/config.json'

The module's customize.sh installs the config bundled in the zip only when none exists, which is why re-flashing over an enrolled box prints "Keeping the existing config" and changes nothing.

Delete first, then re-flash. If you forgot how, check here.

Names

A box names itself when it enrols: manufacturer, model and the last six of its serial, so Magnemite FakeBox ke-00132. Unique enough to tell two boxes apart on a bench, and no use at all once forty of them are on a shelf.

The name is a label, not an identity — the serial is what Magnemite matches a box by across re-enrolments and IP changes. So renaming is free, and nothing downstream breaks when you do it.

Renaming many at once

Pick boxes on Fleet and press Rename N selected, or open a group in Settings → Device groups and press Rename boxes to take all of its approved boxes. Either way you get a preview of every old → new pair before anything is written.

Two ways to fill the names in.

A pattern, when you are naming a site into a scheme:

{group}-{n:02}     lisboa-01, lisboa-02, lisboa-03
tv-{serial:4}      tv-002A, tv-19F3, tv-7C08
TokenIs
{n}the counter. {n:03} pads it to 007, and never truncates a bigger number
{serial}the serial. {serial:4} is the last four — the first characters are a vendor prefix and identical across a fleet
{group}the group's name
{model} / {manufacturer}what the box reported
{name}the name it has now, for prefixing an existing scheme

The counter follows an order you pick — what is on screen, the serial, the current name, or when the box enrolled — and you can set where it starts and how much it steps, for continuing a series at 41 or leaving gaps of ten.

From the boxes, when Magnemite is arriving at a fleet that is already running. It reads each box's MITM config and takes the name already in it, so you adopt the scheme instead of retyping it. The field it reads is wherever that group's template puts {{device.name}}, so the two cannot disagree. Boxes that are offline, or whose group has no config, are skipped and named later.

Two boxes may share a name

Nothing stops you, because sometimes two sites really do both have a spare. The preview marks them so the accidental case — a pattern with no {n} — is obvious before you press the button. You just will not tell them apart in the table or in an alert.

The config on the box keeps the old name

A rename changes the name in Magnemite. The config file already written to a box still holds the name it was written with, and goes out with that box's next MITM deploy — there is no separate push. Until then the scanner reports its old name to Rotom.

On this page