Autenticación y convenciones

Convenciones de la API de administración: autenticación con bearer, roles y capacidades, mutaciones idempotentes, paginación y el sobre de error.

  • Disponibilidad: Planificado
  • Evidencia: Leído del código fuente
  • Referencia

Autenticación

Cada solicitud lleva el token bearer de la autoridad compartida de Beyond, la misma identidad que usa Workspace:

HTTP
GET /v1/session HTTP/1.1
Authorization: Bearer <token>

El CDN no guarda cuentas ni membresías. Una organización es un equipo de Workspace, y el CDN almacena solo identificadores opacos de organización y de usuario. Esta API nunca acepta tokens de invitado de aplicaciones privadas.

Operación Solicitud Capacidad Reintento
session.read GET /v1/session Cualquier usuario con sesión iniciada
organization.read GET /v1/organizations/{organization} application.read

session.read responde el usuario que inició sesión, sus organizaciones, roles, capacidades de CDN y un resumen del plan. organization.read responde el contexto de una organización de quien llama. Cuando no se puede contactar a la autoridad, la respuesta es 502 UPSTREAM_UNAVAILABLE, nunca un rechazo ni una aprobación.

Roles y capacidades

Los roles vienen de la autoridad: owner, admin, developer, viewer y none. El CDN es dueño de una tabla de capacidades sobre esos roles, y cada operación indica la capacidad que exige.

Capacidad Permite owner admin developer viewer
application.read Leer aplicaciones, targets, registros, grafos, inventarios, trabajos, releases, entornos, dominios y cierres de backend Sí Sí Sí Sí
application.manage Crear, cambiar y eliminar aplicaciones y sus targets, y vincular una aplicación a un proyecto de Beyond o desvincularla Sí Sí Sí
release.prepare Registrar selecciones, preparar candidatos, cancelar trabajos y vincular el entorno testing Sí Sí Sí
release.promote Vincular production: promover, revertir y retirar releases Sí Sí
access.manage Cambiar la visibilidad y administrar permisos de invitado Sí Sí
domain.manage Reservar el subdominio de pruebas y administrar dominios propios Sí Sí
providers.manage Leer el resumen sin credenciales de los proveedores de registro de la organización, y establecer o quitar sus ajustes y sus credenciales de solo escritura Sí Sí
usage.read Leer consumo, cuotas, plan, habilitaciones, crédito y libro de crédito Sí Sí Sí
plan.request Entrar en la lista de espera de premium o salir de ella Sí Sí
events.subscribe Obtener permisos de tiempo real, reproducir eventos y leer instantáneas Sí Sí Sí Sí

El rol none no tiene ninguna capacidad y oculta los recursos de la organización.

Dos operaciones exigen una capacidad que depende del entorno sobre el que actúan: la promoción y la reversión necesitan release.prepare para testing y release.promote para production. El contrato lo expresa de forma legible por máquina, x-beyond-capability-by, junto a x-beyond-capability.

Las negativas siguen una regla. Un recurso que quien llama no puede ver responde 404 NOT_FOUND, para no revelar su existencia. Un recurso visible sobre el que el rol no puede actuar responde 403 FORBIDDEN.

Las operaciones bajo /v1/platform pertenecen al backoffice de la plataforma. Exigen una capacidad de operador de plataforma que ningún rol de organización implica, y responden NOT_FOUND a todos los demás. No se documentan aquí.

Proveedores de registro

Una organización puede resolver paquetes desde registros distintos del público, por ejemplo un registro privado para un ámbito de npm. Los ajustes pertenecen a la organización y los usan los registros que se ejecuten después. Los grafos fijados y los releases existentes nunca cambian.

La versión 1 lee registros compatibles con npm accesibles por Internet. Un registro accesible solo a través de una red privada o una VPN queda fuera de la versión 1: los workers llegan solo a direcciones públicas de Internet, y una dirección de registro que no puede serlo se rechaza al guardarla.

Operación Solicitud Capacidad Reintento
providers.list GET /v1/organizations/{organization}/providers providers.manage
providers.set PUT /v1/organizations/{organization}/providers/{provider} providers.manage natural
providers.remove DELETE /v1/organizations/{organization}/providers/{provider} providers.manage natural

{provider} es default, para todo paquete sin un ajuste de ámbito, o un ámbito de npm como @acme.

JSON
{ "registry": "https://<registry host>", "token": "<registry token>" }
Miembro Obligatorio Regla
registry Sí La dirección base, http o https, sin información de usuario, consulta ni fragmento. Puede llevar un prefijo de ruta. Una dirección de un rango de loopback, privado, de enlace local u otro reservado, o un nombre que solo responde un resolvedor local (localhost, *.internal, una sola etiqueta), es 400 VALIDATION_FAILED con el mensaje must be a public Internet address. Una dirección que esta versión no puede usar como registro compatible con npm responde 422 UNSUPPORTED_INPUT.
token No El token bearer del registro. Bearer es el único modo de autenticación de esta versión. Una solicitud sin token deja el registro sin credencial.

Quitar un proveedor hace que los paquetes de ese ámbito vuelvan a resolverse desde el registro predeterminado. Quitar un proveedor que no existe responde lo mismo.

La visibilidad pertenece al paquete

Si un paquete es público se decide para cada paquete, no por la credencial con la que se leyó:

  • Un paquete leído sin credencial es público.
  • Un paquete leído con credencial es público solo cuando el mismo registro, consultado de forma anónima, responde la misma versión con la misma integridad y el mismo archivo comprimido, y el archivo comprimido en sí responde de forma anónima. Cualquier duda lo mantiene privado: un registro responde igual "no encontrado" y "no permitido" a un cliente anónimo.
  • Un repositorio Git o una URL de archivo comprimido leídos con credencial son privados.

Un paquete público produce salidas públicas, aunque se haya usado tu token para leerlo, y se descarga sin el token. Un paquete privado se queda en tu organización, y también toda salida que lo lee, incluido el módulo de un paquete público que lo importa. Una aplicación privada no vuelve privadas sus dependencias públicas. Quitar un token no vuelve públicos los bytes que ya se retuvieron. Consulta Preparación e inventario.

Reintentos y cambios concurrentes

Cada mutación indica cómo tolera un reintento:

Tipo Cómo funciona Lo usan
key El encabezado Idempotency-Key es obligatorio. Un reintento con la misma clave y la misma solicitud responde el resultado original sin repetir el trabajo. La misma clave con una solicitud distinta es 409 IDEMPOTENCY_MISMATCH; una clave ausente es 400 IDEMPOTENCY_REQUIRED. La creación de aplicaciones, registros, preparaciones, dominios propios y permisos de invitado
version La solicitud lleva expected_version. Si no es la versión actual del recurso, no cambia nada y la respuesta es 409 CONFLICT_VERSION con details.current. El cambio de una aplicación, la promoción y la reversión
natural Repetir la solicitud deja el mismo estado Definir y quitar targets, eliminar, cancelar, retirar, reservar el subdominio de pruebas, verificar un dominio, revocar un permiso, establecer y quitar un proveedor, pedir un ticket de miembro

Un Idempotency-Key cumple ^[A-Za-z0-9_.:-]{8,128}$, lo elige el cliente, es único por cada mutación que se quiere hacer y su ámbito es la organización de quien llama. Si una solicitud agota su tiempo de espera, envíala de nuevo con la misma clave: nunca generes una clave nueva para un reintento.

Paginación

Las operaciones de listado aceptan limit (de 1 a 200, 50 de forma predeterminada) y after. Una página responde items y, cuando hay más, next. Envía next de vuelta como after. Los cursores son opacos.

Identificadores

Tipo Forma
Recursos del CDN (aplicaciones, releases, trabajos, …) <kind>_<random>, que cumple ^[a-z][a-z0-9]*_[A-Za-z0-9]{6,40}$, por ejemplo job_Prep0001x
Organizaciones y usuarios Valores opacos que pertenecen a la autoridad. El CDN nunca los interpreta.
Fechas y horas Fecha y hora según RFC 3339
Digests sha256- seguido de 64 caracteres hexadecimales

Errores

Los fallos usan un solo sobre, con la misma forma que el del contrato de entrega. details reemplaza a diagnostics:

JSON
{ "error": { "code": "CONFLICT_VERSION", "message": "…", "details": { "current": 7 } } }
Estado Código Significado
400 VALIDATION_FAILED La solicitud no sigue el esquema; details.fields enumera los problemas
400 IDEMPOTENCY_REQUIRED La mutación exige un encabezado Idempotency-Key
401 UNAUTHENTICATED Ninguna sesión válida acompaña la solicitud
402 CREDIT_INSUFFICIENT El crédito disponible de la organización no cubre la reserva
403 FORBIDDEN El recurso es visible y el rol no tiene la capacidad
403 ACCESS_REVOKED La sesión, la membresía, el permiso de invitado o el permiso de tiempo real fue revocado o venció
403 ADMISSION_REQUIRED El solicitante es un miembro cuyo rol permite la operación, pero no fue admitido a la gestión y la preparación de CDN, o su admisión fue revocada; details.policy nombra la política de admisión. Ver Admisión interna de personas
403 ENTITLEMENT_REQUIRED El plan de la organización no incluye la capacidad; details.entitlement la nombra
404 NOT_FOUND El recurso no existe, o quien llama no debe saber que existe
409 CONFLICT_VERSION expected_version está desactualizado; details.current trae el actual
409 IDEMPOTENCY_MISMATCH La clave ya se usó con una solicitud distinta
409 STATE_INVALID El recurso no está en un estado que permita la operación
409 NAME_CONFLICT El nombre ya está en uso dentro de la organización
409 DOMAIN_CONFLICT, DOMAIN_UNVERIFIED Consulta Dominios
409 QUOTA_EXCEEDED Se superaría una cuota; details.quota la nombra
409 PROJECT_CONFLICT La aplicación ya está vinculada a otro proyecto de Beyond; details.current lo nombra. Consulta El proyecto de una aplicación
409 PROJECT_INACTIVE El proyecto de Beyond está archivado o eliminado; details.state lleva su estado
410 CURSOR_EXPIRED Un cursor de reproducción es anterior a los eventos retenidos
413 PAYLOAD_TOO_LARGE El cuerpo de la solicitud supera el tamaño aceptado
422 UNSUPPORTED_INPUT Una entrada bien formada que esta versión no puede procesar: proveedor, forma de publicación, formato o forma de dependencia
422 LIMIT_EXCEEDED La solicitud supera un límite configurado y no se reintenta automáticamente
422 PROJECT_UNKNOWN El proyecto de Beyond no existe o no pertenece a la organización de la aplicación; nunca se distingue entre las dos
501 NOT_IMPLEMENTED La operación existe en el contrato y esta instancia del servicio no monta su área, o la integración que necesita no está configurada; details.operation la nombra
429 RATE_LIMITED Demasiadas solicitudes; respeta Retry-After
500 INTERNAL Fallo inesperado. El mensaje nunca contiene secretos.
502 UPSTREAM_UNAVAILABLE Un registro, la autoridad, Beyond Projects u otro servicio externo no respondió. Nunca es un rechazo ni una aprobación
503 BUDGET_EXHAUSTED El presupuesto global de admisión no acepta trabajo nuevo en este momento
503 UNAVAILABLE El servicio no puede atender la solicitud en este momento

Los códigos son estables y nunca se traducen. Los motivos por los que un trabajo puede fallar son un vocabulario aparte que viaja dentro de documentos y eventos; consulta Trabajos.

Ningún GET inicia trabajo

Ningún GET de esta API, ni ningún GET de la entrega publicada, inicia, reanuda o programa trabajo. Solo las operaciones POST explícitas crean trabajos. Leer un trabajo, un release o un inventario tantas veces como quieras es seguro.