Resolución de problemas¶
Cada entrada tiene el síntoma, la causa y la solución. Todo error de /v1 lleva un
request_id (también en la cabecera X-Request-Id): cítalo si escribes a soporte.
API¶
| Síntoma | Causa | Solución |
|---|---|---|
401 unauthorized |
Clave desconocida, mal formada, revocada o caducada: la respuesta es la misma para las cuatro | Comprueba que envías Authorization: Bearer <credencial> completa; si la clave se revocó o caducó, crea una nueva (o rota la existente) en la consola. Ver Autenticación |
403 forbidden, con details.missing |
A la credencial le falta un ámbito | Crea una clave con el ámbito que indica details.missing. Ningún ámbito implica otro, y el cumplimiento es por marco |
403 con details.code: "LICENCE_INACTIVE" |
Tu inquilino no tiene una licencia en vigor (ninguna, suspendida, revocada o caducada; details.licence dice cuál) |
Un token nuevo no lo arregla: un administrador del inquilino debe renovar o reactivar la licencia en la consola |
400 con details.code: "TENANT_REQUIRED" |
Usas una clave de cartera (MSSP) sin la cabecera X-HS-Tenant |
Envía X-HS-Tenant: <id del inquilino> (un UUID, nunca un slug). GET /v1/portfolio/tenants lista los que puedes seleccionar |
400 con details.code: "TENANT_SELECTOR_NOT_SUPPORTED" |
Una clave de inquilino o un token OAuth envió X-HS-Tenant con un id que no es el de su propio inquilino |
Quita la cabecera o envía el id de tu propio inquilino |
400 con details.code: "TENANT_HEADER_INVALID" |
X-HS-Tenant no es un UUID válido |
Usa el id (UUID) del inquilino |
404 con details.code: "TENANT_NOT_FOUND" |
El inquilino no está en la cartera de la clave, o no existe: la respuesta es la misma | Revisa el id con GET /v1/portfolio/tenants |
405 method_not_allowed |
/v1 es de sólo lectura: cualquier método distinto de GET se rechaza |
Usa GET; la cabecera Allow lo indica |
409 con details.code: "REPORT_NOT_READY" |
El informe aún se genera o falló (details.status) |
Si details.status es generating, reintenta más tarde |
409 con details.code: "FORMAT_UNSUPPORTED" |
No hay renderizador para el formato pedido | Elige uno de los de details.formats |
429 rate_limited |
Superaste un límite de uso (details.scope dice cuál) |
Espera lo que diga Retry-After y reintenta con backoff. Ver Límites de uso |
El vocabulario completo está en Errores.
Webhooks¶
La verificación de la firma falla. Causas habituales, por orden de frecuencia:
- Calculas el HMAC sobre un cuerpo distinto del enviado. La firma cubre el cuerpo tal como llega; si tu framework lo parsea y lo vuelve a serializar antes de verificar, los bytes cambian. Verifica sobre el cuerpo en bruto.
- Cadena firmada incorrecta. Es
"{timestamp}.{cuerpo}"(marca de tiempo, un punto, el cuerpo), con el valor deX-HodeiShield-Timestampdel mismo intento: cada reintento se vuelve a firmar con una marca de tiempo nueva. - Comparas sin el prefijo
sha256=: el valor deX-HodeiShield-Signature-256lo incluye. - Verificas la cabecera heredada
X-HodeiShield-Signaturecon el esquema nuevo (o al revés). Son dos esquemas distintos; usaX-HodeiShield-Signature-256. - Secreto equivocado o rotado. El secreto (
whsec_…) se muestra una sola vez; si lo perdiste o lo rotaste, usa el nuevo. - Marca de tiempo fuera de tolerancia. Recomendamos rechazar las de más de 5 minutos de diferencia con tu reloj; si tu servidor tiene el reloj desfasado, sincronízalo.
No llegan las cabeceras de firma. Las cabeceras de firma se envían sólo cuando el webhook tiene un secreto configurado.
Recibes la misma entrega dos veces. Es esperado en un reintento (entrega al menos una
vez). Deduplica por X-HodeiShield-Delivery, idéntica en todos los reintentos.
Una entrega figura como fallida. Tras seis intentos sin una respuesta 2xx (a los 5
minutos, 30 minutos, 2 horas, 6 horas y 24 horas) queda fallida; corrige tu endpoint y
reencólala desde la consola. Ver Webhooks.
CLI¶
La CLI informa del resultado con su código de salida (tabla completa en CLI).
| Síntoma | Causa | Solución |
|---|---|---|
Salida 3 en un servidor, contenedor o CI; login se detiene antes de abrir el navegador |
No hay llavero del sistema (o no es accesible en esa sesión) | Usa una clave de API de inquilino en HODEISHIELD_API_KEY; es la opción recomendada para servidores, contenedores y CI |
| Salida 3 con la clave definida | La API rechazó la credencial: clave revocada, caducada o incorrecta | Crea o rota la clave. Si usas una clave de cartera con una restricción de IP, la petición desde otra dirección se rechaza como una clave desconocida |
| Salida 4 | La credencial no tiene el ámbito que necesita el comando | Crea una clave con ese ámbito |
| Salida 6 | Límite de uso agotado (la CLI ya reintentó esperas cortas) | Espera y repite; ver Límites de uso |
| Salida 8 | La licencia del inquilino no está en vigor | Un administrador debe renovarla o reactivarla |
login y logout salen con 1 en una máquina sin llavero |
La CLI no cae a un fichero por su cuenta | Usa HODEISHIELD_API_KEY. Guardar la sesión en un fichero de texto plano es una activación expresa con riesgos que explica la página de la CLI |