B2B Tier 2 — OTP
Pre-provisioned onboarding with a manufacturer-issued one-time password and server-generated certificates via EST.
In this flow, devices are pre-provisioned during manufacturing. The manufacturer registers each device with the Glaze registry, receives a unique OTP, and flashes it onto the device. When the device first connects to the network at the deployment site, it self-onboards using the OTP. No customer app is involved.
Use this flow for B2B/industrial devices where:
- Devices are provisioned during manufacturing and deployed without a customer app
- The manufacturer can register devices with the Glaze registry and distribute OTPs
- The device can store keys securely after enrollment
- Examples: industrial sensors, connected chargers, commercial HVAC units
Prerequisites
Manufacturer:
- Register devices with the platform via
POST /api/devices/register(attestation_type=otp) — onboarding mints a one-shototp_tokenper device - Flash each device with:
device_id,otp_token, onboarding base URL, Glaze Root CA certificate - Call
POST /api/provisioningfor each device during manufacturing — drives the orchestrator chain (onboarding → core-management → mqttprovider) and returns ack-only{deviceId, created}
The device does NOT need EST URLs, broker URLs, or MQTT configuration at manufacturing time — these are discovered at runtime via GET /get_settings.
Platform:
- Beacon Tower EST server deployed and configured
- Glaze CA operational
- Device Registry accessible from EST server
Device hardware:
- Network connectivity (Ethernet, cellular, or pre-configured WiFi)
- TLS client capable of HTTP Basic Auth
- Secure persistent storage for certificates and private keys
Sequence Diagram
Flow Walkthrough
Manufacturing + Pre-Provisioning
The manufacturer handles both device registration and tenant provisioning on the production line:
# 1. Register device with Glaze registry
curl -X POST https://<onboarding-host>/api/devices/register \
-H "Authorization: Bearer $MFG_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"device_id": "sensor-ind-0042",
"hw_rev": "3.0",
"batch": "2026-Q1-batch-15"
}'
# Response: {"device_id": "sensor-ind-0042", "otp_token": "otp_9a2b..."}
# 2. Provision device to enrollment group
curl -X POST https://<onboarding-host>/api/provisioning \
-H "Authorization: Bearer $MFG_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"device_id": "sensor-ind-0042",
"enrollment_group_id": "<enrollment-group-uuid>"
}'
The device is flashed with the OTP, onboarding base URL, Glaze Root CA, and network configuration. In bulk manufacturing, these calls are automated as part of the production pipeline.
Step 1: Bootstrap Discovery
When the device powers on at the deployment site, it connects to the network using pre-configured settings (Ethernet, cellular APN, or WiFi credentials), then calls the onboarding service to learn where everything is:
curl -X GET https://<onboarding-host>/get_settings \
-H "Authorization: Basic <base64(device_id:otp_token)>"
Response contains the broker URL, EST enrollment URL, and EST renewal URL. The device now knows where to enroll and where to connect.
Step 2: EST Enrollment
- Fetch CA chain —
GET /.well-known/est/cacertsreturns the Glaze CA chain. - Enroll —
POST /.well-known/est/serverkeygenwith HTTP Basic Auth (device_id:otp_token). EST generates the keypair server-side and returns the signed certificate (PKCS#7) and private key (PKCS#8). - OTP preserved — The OTP is validated but NOT invalidated. It remains as the device's permanent credential for future
get_settingscalls and re-enrollment.
Step 3: Connect to Broker
The device connects to Mosquitto (URL from Step 1) using mTLS with the Glaze-issued certificate.
Step 4: Certificate Renewal
Before the 90-day certificate expires, the device calls POST /.well-known/est/serverkeygen using its current operational certificate for mTLS authentication. No OTP is needed — the valid certificate proves identity.
Step 5: Re-enrollment (Certificate Expired)
If the certificate expires before renewal (e.g., device was offline too long), the device falls back to OTP authentication: calls get_settings to refresh URLs, then re-enrolls via serverkeygen with Basic Auth. The OTP is permanent, so this always works.
Lifecycle Operations
The five steps above cover the device-driven happy path. The following operations cover the rest of the lifecycle — admin-driven (revoke, disable, approval gating) and device-driven recovery from states the happy path cannot fix on its own (session loss, shard rotation).
Session-loss recovery / shard rotation — POST /reenroll
Used when the device still holds a valid operational certificate but its MQTT session is broken — broker refused CONNECT, MQTT 5 reason 0x82 (session-taken-over) / 0x9C (use-another-server), or the device woke up after a fleet rebalance and its provider shard moved.
Distinct from Step 5 above: Step 5 is "my cert is gone, give me a new one." /reenroll is "my cert is fine, tell me where to connect (and rotate credentials if the routing changed)."
POST /reenroll
Authorization: Basic <base64(device_id:otp_token)> # OTP path
OR
(mTLS with current operational cert) # cert path
| Status | Meaning |
|---|---|
200 | Existing routing is healthy — idempotent fast path. Device reconnects with current credentials. |
201 | Routing was refreshed (shard rotation). Response carries fresh credentials. |
202 | Admin approval required — retry after the indicated interval (see below). |
403 | The enrollment group's re-enrollment policy denied the request. |
409 | Re-enroll not supported for the routing target type. |
503 | Provider unavailable — retry with backoff. |
Rate-limited per device.
Admin-gated approval
An enrollment group can be configured to require an admin decision on every re-enrollment. When that gate is active, the device's /reenroll or /.well-known/est/serverkeygen call returns 202 Accepted with a Retry-After header instead of issuing credentials. The device keeps retrying on that cadence until an admin makes a decision:
- Admin reads the parked request:
GET /api/devices/{deviceRecordId}/pending-reenrollment. - Admin approves or rejects:
POST /api/devices/{deviceRecordId}/pending-reenrollment/approve— next device retry mints the cert.POST /api/devices/{deviceRecordId}/pending-reenrollment/reject— next device retry returns403until the parked request expires (group-configured TTL).
Use this for fleets where every re-enrollment must trace back to a human decision.
Revoke a device
Two operations, both admin-only (JWT). Run them together for a full revoke:
| Endpoint | Effect |
|---|---|
DELETE /api/devices/{deviceId} | Soft-deletes the onboarding device record. Subsequent get_settings / serverkeygen / reenroll fail with 401 invalid_bootstrap_key or 404. |
POST /api/devices/{deviceId}/delete-provider-client | Tells the provider (mqttprovider) to evict the MQTT user + ACL rows. Returns 202 Accepted once queued. |
Order matters only for which call returns last; both are idempotent. After a revoke the OTP is still on file (soft delete is reversible) but the device cannot reach any device-facing endpoint.
Disable / re-enable
Soft-delete is the disable mechanism. Restore brings the device back:
| Endpoint | Effect |
|---|---|
DELETE /api/devices/{deviceId} | Soft-delete (same as revoke). Device cannot enrol, renew, or re-enrol. |
POST /api/devices/{deviceId}/restore | Undoes the soft-delete. Cert (if still valid) works again; OTP still works for get_settings and re-enrollment. |
POST /api/devices/bulk-delete / bulk-restore | Batch variants (NDJSON body). |
If you re-enable a device whose cert has expired, the device falls back to the Step 5 OTP path on its own.
Security Considerations
- Pre-provisioned — Devices are bound to a tenant at the factory. No opportunity for unauthorized claiming.
- Permanent OTP — The OTP is permanent — used for
get_settingsand re-enrollment after certificate expiry. Each device has a unique OTP; if compromised, only one device is affected (per-device credential). - No app dependency — Fully autonomous onboarding. No mobile app or human interaction at the deployment site.
- Server-generated keys — Private key generated by EST, transported once over TLS. After initial enrollment, renewals also generate new keys server-side.
- Bulk automation — Registration and provisioning integrate into manufacturing pipelines. Scales to thousands of devices.
Next Steps
- B2B Tier 1 — Shared Key — Simpler flow without OTP registration
- B2B Tier 3 — Birth Certificate — Highest security with manufacturer PKI
- Consumer Tier 2 — OTP — Same attestation tier with a customer app
- Certificate Onboarding Overview — Decision matrix and key concepts
- Shared-Secret Onboarding — Simpler username/password alternative