Ir al contenido

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:

CampoPropósito
Referencia de profileEl device profile que heredan los nuevos dispositivos (tags, configuración, política de anchoring, esquema de telemetry, …)
Patrón de hardware_id permitidoRestringe qué hardware IDs pueden reclamar con esta key
CaducidadInstante UTC tras el cual se rechaza la key (sin caducidad si no se establece)
Flag de un solo usoSi se establece, la key se marca como usada tras un claim exitoso
Tipo de credencialQué credencial reciben los nuevos dispositivos (API key, PSK o cert)
Grupos por defectoGrupos 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.1
Host: api.kronoxdata.com
Content-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:

Ventana de terminal
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"
}'

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.

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.

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