Skip to content

Register an NFC scanner device

When a new iPhone or laptop joins your scanner fleet, you pair it with the admin console so it can authenticate scans against Polaris Express. The handshake mints a (deviceToken, deviceSecret) pair that the iOS app holds in Keychain and presents on every subsequent request. Use this runbook when you unbox a new scanner, replace a lost device, or re-pair a device whose token you previously revoked.

  • You are signed in to the admin console with the admin role. Non-admins receive a 403 on the registration endpoint.
  • You have physical access to the device you want to register, and the Polaris Express iOS app is installed on it.
  • The device is on a network that can reach docs.polaris.express (and the API origin behind it).
  • You know the owner of the device — registration binds the device to your admin user account as ownerUserId.
  1. Open the Devices section

    In the admin console, navigate to Devices in the sidebar, then click Register device in the page header.

  2. Generate a one-time code

    The registration dialog mints a single-use code valid for 60 seconds. The code is bound to a PKCE verifier that only your browser session holds — the iOS app must present the matching proof to redeem it.

  3. Enter the code on the device

    On the iPhone or laptop, open the Polaris Express app and tap Pair with admin. Enter the one-time code shown in the browser.

    The app collects these fields and submits them to POST /api/devices/register :

    • Label — a human-readable name for the device (max 120 chars). Use something operators will recognise in the fleet list, e.g. “Front-desk iPhone 14” or “Service van laptop”.
    • Platformios, macos, or ipados.
    • Model, OS version, App version — collected by the app.
    • APNs environmentsandbox for TestFlight builds, production for App Store builds.
    • Requested capabilities — at least one of the supported capabilities (e.g. managed).
  4. Confirm pairing on the device

    The app submits the code along with its PKCE proof. On success the server responds with the device’s deviceToken, deviceSecret, and the token’s expiresAtIso. The app writes both values to Keychain immediately — they are never shown on screen and never returned again.

After the device confirms pairing:

  1. Return to Devices in the admin console. The new device appears in the fleet list with its label, platform, and owner email.

  2. Open the device’s detail page (/admin/devices/<deviceId>). Confirm:

    • Registered timestamp matches when you just paired.
    • Token count is 1 and the active token’s expiry is in the future.
    • Push token shows the last 8 characters if the app uploaded an APNs token during registration.
    • The device shows as online if the app has heartbeated within the last 90 seconds.
  3. Check the audit log for two entries authored by your admin user:

    • device.registered
    • device.token.issued

    Both carry the new deviceId in their metadata.

Every registration writes two audit-log entries: device.registered (captures deviceId, kind, platform, model, appVersion, and the granted capabilities) and device.token.issued (captures deviceId, tokenId, and the first 8 chars of the token hash). Both are attributed to the admin user who minted the one-time code.

To reverse a registration, open the device detail page and use the Deregister action in the header menu. Deregistration is soft-delete: the device row is marked deletedAt, its tokens are revoked, and the device can no longer authenticate. The audit trail is preserved. To pair the same physical device again afterwards, run this runbook from the top — you’ll get a new deviceId.