Supply Chain Security: Firma con Sigstore y SBOM Real en CI/CD
Como Basilisk implementa cosign, SLSA y CycloneDX en pipelines reales para mitigar ataques tipo SolarWinds, XZ Utils y dependency confusion.
Cuando la puerta trasera de XZ Utils (CVE-2024-3094) estuvo a punto de entrar en distribuciones Linux estables en marzo de 2024, quedo claro que firmar un tag en GitHub ya no alcanza. La cadena de suministro de software se volvio objetivo prioritario porque un solo maintainer comprometido propaga codigo malicioso a millones de hosts en horas. En Basilisk OffSec trabajamos ambos lados: simulamos ataques contra pipelines de clientes y ayudamos a equipos a cerrar las puertas que encontramos. Este post consolida lo que aplicamos en CI/CD real usando Sigstore cosign, SLSA nivel 3 y SBOMs CycloneDX, con enfoque pragmatico y no teatro de cumplimiento.
El primer paso es abandonar la idea de clave privada de larga duracion guardada en un secret manager. Cosign keyless usa OIDC de GitHub Actions, GitLab CI o Buildkite para emitir un certificado efimero via Fulcio, valido 10 minutos, y registra la firma en Rekor, un log transparente append-only. Eso elimina toda una categoria de fugas de clave de firma, que fue el pivote del incidente de CodeCov en 2021. Un workflow tipico tiene tres jobs: build reproducible, sign con cosign sign --yes y attest con predicado SLSA Provenance v1.0. En proyectos de cliente vimos 90% menos tiempo de rotacion de credenciales al migrar de claves PGP a keyless, y eso conecta directamente con lo que discutimos en AppSec Shift-Left: SAST, SCA y Escaneo de Secretos sin Frenar al Equipo.
Un SBOM no es un XML que nadie lee. Generamos CycloneDX 1.6 con Syft en el momento del build, incluyendo hashes SHA-256 de cada componente, licencia SPDX y proveedor. El archivo viaja junto a la imagen OCI como artefacto referenciado, no perdido en un S3. Para validar corremos Grype en el pull request y tambien en background contra el registry, porque las CVE nuevas aparecen despues del merge. Combinamos esto con policy-as-code via Kyverno o Conftest, bloqueando despliegues si el SBOM tiene una dependencia con CVSS superior a 7.0 sin excepcion documentada. Este mismo modelo de policy aparece cuando discutimos Hardening de Linux Server: CIS Benchmark Aplicado sin Romper Produccion en servidores de produccion.
SLSA (Supply-chain Levels for Software Artifacts) se volvio el marco de referencia despues de que Google y OpenSSF estandarizaron la v1.0 en 2023. Nivel 1 es solo tener build script versionado. Nivel 2 exige builder hospedado con procedencia firmada. Nivel 3, donde queremos llegar en proyectos sensibles, exige aislamiento del build, procedencia no falsificable y hermetic builds. En la practica usamos GitHub Actions con el reusable workflow slsa-framework/slsa-github-generator, que produce attestation in-toto firmada por el propio runner via OIDC. Un atacante que comprometa a un maintainer todavia tiene que romper el builder de GitHub, lo que eleva el costo del ataque en ordenes de magnitud. Para equipos que tambien atienden Dependency Confusion y Typosquatting: Defensa Practica para Equipos Dev, SLSA cierra el lado del publisher.
Verificar en el consumidor es tan importante como firmar en el productor. En clusters Kubernetes usamos el admission controller policy-controller de Sigstore con ClusterImagePolicy exigiendo que toda imagen en namespace produccion tenga firma cosign valida, identidad OIDC del dominio basilisk.example y attestation SLSA del builder esperado. Configuramos soft-fail en staging para no romper deploys de emergencia, y hard-fail en prod. Tambien corremos cosign verify-blob en los binarios CLI bajados a estaciones de analista, integrado al flujo descrito en OPSEC para Investigadores de Seguridad: Modelo de Amenaza Personal, porque el equipo de OffSec descarga muchas herramientas de origen incierto y eso se vuelve vector obvio.
Donde se rompe en la practica: builds no reproducibles, timestamps incrustados en binarios Go, dependencias transitivas que cambian entre git pull y CI, y maintainers que rechazan adoptar 2FA. El XZ pre-2.0 ya tenia senales de takeover social del proyecto que ninguna firma captura. Por eso recomendamos combinar cosign+SLSA+SBOM con revision periodica de maintainers criticos, scorecard de OpenSSF corriendo semanalmente sobre las top 50 dependencias, y ejercicios de red team que simulen compromiso de maintainer, similar a lo que hacemos en engagements descritos en Adversary Emulation con Caldera y MITRE ATT&CK en Laboratorio Corporativo y Purple Team en la Practica: Construyendo Ciclo de Feedback Red vs Blue. Tecnologia sin proceso de mantenimiento se vuelve teatro caro.
Takeaway practico: empieza pequeno y medible. Esta semana, agrega cosign sign keyless en un pipeline unico, genera SBOM CycloneDX con Syft y publicalo como artefacto OCI junto a la imagen. La proxima sprint, activa cosign verify obligatorio en un namespace de staging. En 30 dias tienes base para exigir SLSA L2 a proveedores y responder con evidencia cuando ocurra el proximo XZ, porque va a ocurrir. El costo de implementacion en un pipeline existente ronda 2 a 4 horas de ingeniero; el costo de no implementar es preguntar a tus clientes en una call de domingo si firmaste ese contenedor que esta minando Monero en produccion.