Provisioning por key claim
El key claim es el flujo para el autoaprovisionamiento a escala. En lugar de registrar
cada dispositivo a mano, tú (o tu fabricante por contrato) grabas una provisioning key
compartida en un lote de dispositivos. En el primer arranque, cada dispositivo llama a
POST /api/v1/provision con esa key, y la plataforma crea el dispositivo y devuelve sus
credenciales. No hay ningún operador en el bucle en el momento del claim.
Este es el flujo adecuado cuando los dispositivos salen de una línea y deben conectarse por su cuenta. Para dispositivos puntuales, registro manual es más sencillo.
Paso 1 — Crear una plantilla / key de provisioning
Sección titulada «Paso 1 — Crear una plantilla / key de provisioning»Un admin del tenant crea una plantilla de provisioning (y la key que emite) con antelación. La plantilla acota lo que la key puede hacer:
| Campo | Propósito |
|---|---|
| Referencia de profile | El device profile que heredan los nuevos dispositivos (tags, configuración, política de anchoring, esquema de telemetry, …) |
Patrón de hardware_id permitido | Restringe qué hardware IDs pueden reclamar con esta key |
| Caducidad | Instante UTC tras el cual se rechaza la key (sin caducidad si no se establece) |
| Flag de un solo uso | Si se establece, la key se marca como usada tras un claim exitoso |
| Tipo de credencial | Qué credencial reciben los nuevos dispositivos (API key, PSK o cert) |
| Grupos por defecto | Grupos a los que se une cada dispositivo reclamado con esta key |
La key está vinculada a un tenant. El tenant del dispositivo provisionado siempre se deriva de la key — nunca de nada que el dispositivo envíe.
Paso 2 — El dispositivo reclama su identidad
Sección titulada «Paso 2 — El dispositivo reclama su identidad»En el primer arranque el dispositivo envía su provisioning key en bruto, un nombre legible
y su hardware_id estable a POST /api/v1/provision.
POST /api/v1/provision HTTP/1.1Host: api.kronoxdata.comContent-Type: application/json{ "provision_key": "pk_factory_7Qx2mZr8K...redacted...", "device_name": "Cold Store Sensor 014", "hardware_id": "AA:BB:CC:00:11:22"}La misma llamada por curl:
curl -sS -X POST https://api.kronoxdata.com/api/v1/provision \ -H "Content-Type: application/json" \ -d '{ "provision_key": "pk_factory_7Qx2mZr8K...redacted...", "device_name": "Cold Store Sensor 014", "hardware_id": "AA:BB:CC:00:11:22" }'Primer claim exitoso
Sección titulada «Primer claim exitoso»Un dispositivo totalmente nuevo recibe de vuelta su device_id de la plataforma y una
api_key recién acuñada:
{ "device_id": "8f1c0b7e-3d2a-4f56-9a10-2c4e6f8b1d33", "api_key": "sk_live_Zr8K2mQx...redacted..."}El dispositivo ahora descarta la provisioning key y autentica todas las peticiones futuras
con sk_live_…. Ver credenciales para las
cabeceras de autenticación.
Reclamo idempotente
Sección titulada «Reclamo idempotente»Si ya existe en el tenant un dispositivo con el mismo hardware_id, la llamada es
idempotente: devuelve el device_id existente y una api_key vacía.
{ "device_id": "8f1c0b7e-3d2a-4f56-9a10-2c4e6f8b1d33", "api_key": ""}Una api_key vacía no es un error — es la plataforma diciendo “ya conozco este
dispositivo; sigue usando la key que se te emitió antes”. No se crea ningún dispositivo
duplicado, no se acuña una segunda key y no se emite ningún evento device.provisioned.
Por tanto, los dispositivos deben almacenar de forma duradera su primera API key
emitida y no depender de obtener una nueva al reiniciar.
El flujo de claim completo
Sección titulada «El flujo de claim completo»sequenceDiagram
autonumber
participant Dev as Dispositivo
participant GW as Gateway / device-link
participant Reg as Device registry
participant Auth as Servicio de autenticación
Dev->>GW: POST /api/v1/provision<br/>{provision_key, device_name, hardware_id}
GW->>GW: SHA-256(provision_key)
GW->>GW: Buscar key por hash,<br/>comparación de tiempo constante,<br/>comprobar estado + caducidad
Note over GW: Inválida / deshabilitada / caducada →<br/>PermissionDenied (uniforme)
GW->>Reg: CreateDevice(tenant_from_key, name, hardware_id)
alt Nuevo hardware_id
Reg-->>GW: device_id (creado)
GW->>Auth: MintAPIKey(tenant, device_id)
Auth-->>GW: sk_live_… (raw, una vez)
GW-->>Dev: {device_id, api_key}
GW--)Reg: publicar evento device.provisioned
else hardware_id existente (idempotente)
Reg-->>GW: device_id (existente)
GW-->>Dev: {device_id, api_key: ""}
end