Seguridad de la cadena de suministro
SBOM con Syft, firma y verificación de imágenes con cosign/Sigstore y AWS Signer, niveles SLSA de integridad del build y gestión de dependencias con Dependabot.
Casi ninguna línea del código que corre en producción la has escrito tú. Debajo de la API de Citas hay cientos de dependencias npm, una imagen base de contenedor, acciones de GitHub de terceros y las herramientas del propio pipeline. Cada una es una puerta por la que un atacante puede entrar sin tocar tu código: basta comprometer una librería popular, o sustituir una imagen legítima en el registro. La seguridad de la cadena de suministro responde a dos preguntas: ¿qué llevo dentro? y ¿puedo confiar en que esto es lo que construí?
El problema: confianza transitiva#
Cuando despliegas una imagen, confías implícitamente en todo lo que la compone y en todo el proceso que la produjo. Los ataques de cadena de suministro explotan precisamente esa confianza transitiva:
- Dependencia comprometida: un paquete que usas (o uno de sus sub-dependencias) recibe una versión maliciosa. Pasó con
event-streamy conxz/liblzmaen 2024. - Vulnerabilidad transitiva: una librería que ni sabías que usabas resulta vulnerable, como Log4Shell en 2021.
- Sustitución del artefacto: alguien reemplaza tu imagen en el registro, o en tránsito, por una versión manipulada.
Las defensas forman una cadena: saber qué hay dentro (SBOM), firmar lo que construyes y verificar la firma antes de desplegar, medir la integridad del proceso (SLSA) y mantener al día las dependencias.
Paso 1 de 6Build + SBOM
La CI construye el artefacto y genera su SBOM con Syft: el inventario completo de dependencias que lleva dentro.
SBOM: saber qué llevas dentro#
Un SBOMSBOMInventario legible por máquina de todos los componentes y dependencias de un artefacto de software, usado para auditar y responder a vulnerabilidades. (Software Bill of Materials) es el inventario completo de componentes de un artefacto: librerías, versiones, licencias y dependencias transitivas, en un formato estándar como SPDX o CycloneDX. Se genera en el build, de forma automática.
# Generar un SBOM de la imagen de Citas en formato CycloneDXsyft citas-api:1.4.2 -o cyclonedx-json > sbom.json
# Cruzar ese SBOM con la base de vulnerabilidadesgrype sbom:sbom.json --fail-on highEl valor del SBOM se cobra el día que aparece una vulnerabilidad nueva. Sin SBOM, la pregunta «¿qué imágenes usan la versión afectada?» se responde con arqueología y suerte. Con SBOM, es una consulta de minutos. Por eso cada vez más contratos y normativas lo exigen.
Firmar y verificar: cortar la sustitución#
Saber qué hay dentro no impide que alguien sustituya el artefacto entero. Para eso está la firmaFirma de imagenFirmar criptográficamente una imagen o artefacto para verificar en el despliegue su origen e integridad y rechazar lo no firmado o manipulado.: adjuntar a la imagen una prueba criptográfica de quién la construyó, y verificarla en el despliegue rechazando todo lo que no esté firmado por un firmante de confianza. Es una aplicación directa de la firma digital: la clave privada firma, la pública (o un certificado) verifica.
La herramienta de referencia es cosign, del proyecto Sigstore. Su modo más interesante es la firma keyless: en lugar de custodiar una clave privada de larga vida, una identidad OIDC (por ejemplo el propio workflow de GitHub Actions) obtiene un certificado efímero de la autoridad Fulcio, firma con él, y la firma se registra en el log de transparencia Rekor. No hay clave que guardar ni que filtrar.
# Firmar sin clave: usa la identidad OIDC del entorno (keyless)COSIGN_EXPERIMENTAL=1 cosign sign citas-api@sha256:abcd...
# Verificar en el despliegue: exige identidad y emisor concretoscosign verify citas-api@sha256:abcd... \ --certificate-identity "https://github.com/clinicas/citas/.github/workflows/deploy.yml@refs/heads/main" \ --certificate-oidc-issuer "https://token.actions.githubusercontent.com"Fíjate en la verificación: no basta con que la imagen esté firmada; --certificate-identity y --certificate-oidc-issuer exigen que la firmara tu workflow, no cualquiera. En AWS, AWS Signer ofrece un flujo gestionado equivalente para imágenes de contenedor y para código Lambda, integrado con ECR y con la verificación en el despliegue.
SLSA: medir la integridad del build#
Firmar demuestra quién construyó el artefacto. SLSASLSAMarco con niveles (Build L1–L3) para asegurar la integridad de la cadena de build mediante provenance firmada y plataformas de build endurecidas. (Supply-chain Levels for Software Artifacts) va un paso más allá y mide la integridad del proceso de build con niveles crecientes del Build track:
| Nivel | Qué exige | Contra qué protege |
|---|---|---|
| Build L1 | Existe provenance: cómo, con qué entradas y con qué proceso se construyó | Errores y falta de trazabilidad |
| Build L2 | Plataforma de build gestionada que firma la provenance | Manipulación después del build |
| Build L3 | Builds aislados y endurecidos; la clave de firma, fuera del alcance de los pasos del usuario | Manipulación durante el build |
La provenance es una atestación firmada que dice «este artefacto salió de este repositorio, con este commit, en este pipeline». Al verificarla en el despliegue, compruebas que la imagen vino de verdad de tu CI y no de la máquina de un atacante. SLSA no sustituye al SBOM ni a la firma: los complementa, poniendo el foco en la confianza del proceso.
Dependencias al día: Dependabot#
La mayoría de los compromisos entran por dependencias desactualizadas con vulnerabilidades conocidas. Dependabot (GitHub) abre pull requests automáticos cuando una dependencia tiene una versión con parche de seguridad, y vigila tanto librerías como acciones de GitHub e imágenes base.
version: 2updates: - package-ecosystem: npm directory: / schedule: interval: weekly - package-ecosystem: docker # imagen base del contenedor directory: / schedule: interval: weekly - package-ecosystem: github-actions # acciones de terceros directory: / schedule: interval: weeklyTu turno
Firma y verifica una imagen de tu pipeline
Sobre una imagen de contenedor de tu trabajo o tu lab:
- Genera su SBOM con
syfty crúzalo congrype. ¿Cuántas vulnerabilidades altas o críticas salen? - Firma la imagen con
cosign(keyless si usas GitHub Actions) y verifícala concosign verifyexigiendo--certificate-identityy--certificate-oidc-issuer. - Haz la prueba negativa: intenta verificar una imagen sin firmar o firmada por otra identidad. Debe fallar.
- Añade
dependabot.ymlcubriendo tus dependencias, la imagen base y las acciones de GitHub. - (Opcional) Genera provenance SLSA con el generador oficial y verifícala en el deploy.
| Campo | Tu respuesta |
|---|---|
| Imagen | |
| Vulnerabilidades (altas / críticas) | |
¿cosign verify pasa con tu identidad? |
|
| ¿Falla con imagen sin firmar? | |
| Nivel SLSA objetivo |
Reto
Firmas todas tus imágenes con cosign, pero el despliegue acepta cualquiera. ¿Qué has conseguido?
▸Mostrar solución
Poco. Firmar sin verificar en el despliegue no impide que entre una imagen manipulada: el atacante simplemente despliega una sin tu firma, y como nadie la comprueba, pasa. El control nace en la admisión: una política que exige firma válida de la identidad esperada y rechaza el resto. Firma y verificación son las dos mitades; con una sola no hay control.
Reto
Tienes SBOM y firmas, ¿para qué quieres además SLSA?
▸Mostrar solución
Porque responden a preguntas distintas. El SBOM dice qué hay dentro; la firma dice quién construyó el artefacto; SLSA dice si el proceso de build es confiable y no manipulable. Un atacante con acceso a un build poco endurecido podría producir una imagen maliciosa y firmarla legítimamente con la identidad del pipeline. SLSA (builds aislados, clave de firma fuera del alcance de los pasos del usuario) cierra justo ese hueco.
En resumen#
- La cadena de suministro es confianza transitiva: el riesgo entra por dependencias, imágenes base y herramientas, sin tocar tu código.
- SBOM (Syft) responde «¿qué llevo dentro?» y hace que responder a una vulnerabilidad nueva sea cuestión de minutos.
- Firmar (cosign/Sigstore, AWS Signer) y verificar en el despliegue corta la sustitución de artefactos; la verificación debe exigir la identidad del firmante.
- SLSA mide la integridad del proceso de build (L1 provenance → L2 firmada → L3 aislada) y complementa SBOM y firma.
- Dependabot mantiene las dependencias al día; fija las acciones de terceros por SHA y revisa lo sensible.