Ir al contenido

Autenticación y scopes

La API pública de NORA se autentica con API keys enviadas en la cabecera X-API-Key. Cada key pertenece a un workspace (tenant), lleva un conjunto de scopes que limitan a qué endpoints puede acceder y, opcionalmente, una lista de IPs permitidas, un conjunto de entornos y una fecha de expiración.

  • URL base de producción: https://nora.valisoftconsulting.com
  • Prefijo de la API: /api/v1
  • Cabecera de autenticación: X-API-Key: nora_ak_...

Puedes crear una key desde la interfaz (Settings → API Keys) o directamente con la API de configuración. Crear, listar, rotar y revocar keys requiere rol admin del workspace.

El endpoint de creación es:

POST /api/v1/settings/api-keys

Este endpoint usa autenticación de usuario (sesión / token de acceso), no X-API-Key. El cuerpo acepta los siguientes campos:

CampoTipoRequeridoDescripción
namestringNombre descriptivo (mínimo 2 caracteres).
scopesstring[]Al menos un scope válido (ver tabla).
expires_atdatetime | nullNoFecha de expiración. null = sin expiración.
allowed_ipsstring[] | nullNoLista de IPs permitidas. null = sin restricción.
environmentsstring[] | nullNoRestringe la lectura de assets a estos entornos. null = todos. Valores válidos: dev, staging, production.

Ejemplo de creación:

Ventana de terminal
curl -X POST https://nora-api.valisoftconsulting.com/api/v1/settings/api-keys \
-H "Authorization: Bearer <token-de-acceso>" \
-H "Content-Type: application/json" \
-d '{
"name": "Integración CI/CD",
"scopes": ["jobs:read", "jobs:write"],
"environments": ["staging"]
}'

La respuesta va envuelta en {"success": true, "data": {...}} e incluye el campo key con el valor completo de la API key:

{
"success": true,
"data": {
"id": "0d4c…",
"name": "Integración CI/CD",
"prefix": "nora_ak_AbC",
"is_active": true,
"last_used_at": null,
"expires_at": null,
"allowed_ips": null,
"scopes": ["jobs:read", "jobs:write"],
"environments": ["staging"],
"created_at": "2026-06-19T12:00:00Z",
"key": "nora_ak_..."
}
}

Las keys tienen el prefijo fijo nora_ak_ seguido de material aleatorio. El campo prefix (los primeros 12 caracteres) sirve para identificar la key en la interfaz sin exponer el valor completo.

Envía la key en la cabecera X-API-Key en cada petición a la API pública:

Ventana de terminal
curl https://nora-api.valisoftconsulting.com/api/v1/machines \
-H "X-API-Key: nora_ak_..."

En cada uso, NORA actualiza el campo last_used_at de la key. Si la key está inactiva (revocada), expirada o el scope no coincide, la petición se rechaza.

Los scopes de API key usan la notación recurso:accion (con dos puntos), un espacio de nombres distinto al de los permisos RBAC internos de los usuarios (que usan recurso.accion con punto). Cada scope habilita un conjunto concreto de endpoints de la API pública.

ScopeSignificadoGrupo
assets:readLeer assets (credenciales/valores)Credenciales
queues:readLeer items de colasColas
queues:writeAgregar items a colasColas
jobs:readVer estado de ejecucionesEjecuciones
jobs:writeDisparar ejecucionesEjecuciones
jobs:stopDetener ejecucionesEjecuciones
processes:readLeer procesosProcesos
machines:readLeer máquinasMáquinas

Puedes consultar dinámicamente el catálogo de scopes aceptados (solo admin):

GET /api/v1/settings/api-keys/available-scopes

La validación de scopes es fail-closed: una key solo puede usar un endpoint si su lista de scopes contiene explícitamente el scope requerido. Una key sin scopes (lista vacía o nula) no tiene ningún permiso y se rechaza con un error de autorización.

flowchart TD
    A[Petición con X-API-Key] --> B{Key activa y no expirada}
    B -- No --> X[401 No autorizado]
    B -- Sí --> C{IP en allowed_ips?}
    C -- No --> Y[403 IP no autorizada]
    C -- Sí --> D{Scope requerido presente}
    D -- No --> Z[403 Scope faltante]
    D -- Sí --> E[Petición permitida]

Al crearse vía API, toda key debe llevar al menos un scope (scopes exige min_length=1), por lo que no es posible crear keys sin restricción desde la superficie pública.

Si la key define allowed_ips, NORA compara la IP de origen de la petición contra esa lista; si no coincide, devuelve 403 IP no autorizada. Si es null, no hay restricción de IP.

environments limita desde qué entornos puede leer assets la key. Por ejemplo, una key de CI/CD restringida a ["dev"] o ["staging"] no podrá leer secretos de production, conteniendo el impacto de una key filtrada. Si es null, la key puede leer assets de todos los entornos. Los valores válidos son dev, staging y production.

Si expires_at está definido y ya pasó, la key se rechaza con 401 API key expirada. Define una expiración para keys temporales o de terceros.

Rotar una key genera un nuevo valor secreto manteniendo el mismo registro (nombre, scopes, IPs). El valor antiguo deja de funcionar y la respuesta devuelve el nuevo key (de nuevo, solo esta vez):

POST /api/v1/settings/api-keys/{key_id}/rotate

Revocar desactiva la key de forma permanente; cualquier petición posterior con ese valor se rechaza:

DELETE /api/v1/settings/api-keys/{key_id}

Tanto la creación, como la rotación y la revocación quedan registradas en el registro de auditoría del workspace.

  • Mínimo privilegio: asigna solo los scopes que la integración necesita (p. ej. una integración de monitoreo solo necesita jobs:read).
  • Una key por integración: facilita revocar una sola sin afectar al resto.
  • Restringe entornos: scope las keys de CI/CD a dev/staging para que una filtración no exponga secretos de producción.
  • Usa allowed_ips cuando la integración tenga IPs de salida estables.
  • Define expiración en keys temporales y rota periódicamente las permanentes.
  • Nunca publiques la key en el frontend, repositorios o logs: trátala como una contraseña y guárdala en un gestor de secretos.
  • Revoca de inmediato cualquier key potencialmente comprometida.