Proving device identity: token, host, and mutual authentication
Device authentication answers the core question: is this device genuine? The CyberRock token computes a hardware HMAC response to a challenge; the cloud, holding the matching secret in its HSM, verifies it independently. Because the secret never leaves either side, a passing check proves the physical token is present.
Three ways to run it
| Flow | Who issues the challenge | Use when |
|---|---|---|
Token authentication (token_auth.py) |
The cloud (CW → RW) | Your backend decides when devices must prove themselves: fleet check-ins, on-connect verification. |
Host authentication (host_auth.py, host_auth_priority.py) |
The device (HCW → HRW) | The device decides when to prove itself: before sending data, after boot, on schedule. |
Mutual authentication (mutual_auth.py, mutual_auth_host.py) |
Both directions | The device must also confirm it is talking to the real CyberRock Cloud, not an impersonator. The cloud returns an HRW2 the device can reproduce locally. |
Recommended starting point
examples/02-prove-device-identity/host_auth_priority.py is the shortest complete round-trip and the pattern most integrations start from. The _priority suffix means synchronous: one call, immediate answer, no polling.
What happens, step by step (host auth, priority)
- The host script creates a challenge (HCW) locally.
- It reads the token's TID over SPI/USB.
- It sends the HCW to the token, which computes the hardware response (HRW).
- The host logs in to the CyberRock Cloud and submits TID + HCW + HRW to the
priorityHostAuthendpoint. - The cloud recomputes the expected response in its HSM and returns
AUTH_OKimmediately.
Token authentication (cloud-initiated) differs in one way
- The host requests a challenge word (CW) from the cloud, which returns CW plus a transaction ID.
- The token computes the response (RW), the host submits it, then polls
checkAuthStatusuntil the cloud reportsAUTH_OK.
Async vs. priority
Flows without _priority submit the response, then poll the cloud for a verdict. Priority variants make a single synchronous call. Priority is simpler and less exposed to the package's unbounded polling behaviour (see Known issues and production checklist); use the async form only if your workflow needs the transaction-based model.
Results you may see
| Result | Meaning | Action |
|---|---|---|
AUTH_OK |
The device is genuine and bound to your tenant. | None; proceed. |
CLAIM_TOKEN |
The token is genuine but not yet bound to your tenant. | Run examples/01-getting-started/token_claim.py once, then retry. |
| Failure / rejection | The response did not verify: wrong token, tampering, or a corrupted exchange. | Re-run; if persistent, check wiring and contact support@sandgrain.eu. |
Related variants in this folder
host_auth_hrwrequest.py: host auth combined with an HRW request (the cloud derives the expected tag for data you supply).mutual_auth_host.py: the host-initiated form of mutual authentication; the recommended starting point when the device must verify the cloud.
If you also need a shared session key out of the authentication, use the _ek forms of these flows instead; see Deriving a session key (Ephemeral Keys).
Source code: SandGrain CyberRock - Core Functions on GitHub