Files
apps-registry/docs/devsecops/cosign.md
T
devopsandClaude Sonnet 5 ac095ff981
Build and Push Medusa / Escaneo de Secretos (Gitleaks) (push) Successful in 58s
Build and Push Frontend / Escaneo de Secretos (Gitleaks) (push) Successful in 32s
Build and Push Docs Portal / Escaneo de Secretos (Gitleaks) (push) Successful in 35s
Build and Push Medusa / Construir y publicar Medusa (push) Successful in 18m58s
Build and Push Frontend / Construir y Subir Imagen (push) Successful in 12m0s
Build and Push Docs Portal / Construir y publicar Docs Portal (push) Successful in 5m43s
fix(devsecops): firmar y verificar imagenes por digest, no por tag
Los 3 pipelines (frontend, commerce-backend, docs-portal) ahora capturan
el digest real del docker push y lo usan como referencia para cosign
sign/verify, en vez del tag mutable :VERSION. Documenta ademas la
decision de mantener Rekor deshabilitado (registry privado, evita
dependencia de red saliente hacia rekor.sigstore.dev via el tunel).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011FqYP3Wf1W63Qmh7qgXAAT
2026-08-16 14:46:01 -05:00

2.4 KiB

Firma de imágenes con Cosign

Los 3 pipelines que construyen y publican imágenes hacia gitea.cruzcloud.net (frontend en .gitea/workflows/build.yaml, commerce-backend en build-medusa.yaml, docs-portal en deploy-docs.yaml) firman la imagen con Cosign (par de llaves propio, sin CA externa) inmediatamente después del docker push y antes de que cualquier manifiesto pueda referenciarla.

Firma por digest, no por tag

Desde 2026-08-16 los tres workflows firman y verifican por digest (${IMAGE_NAME}@sha256:...), no por tag (${IMAGE_NAME}:${VERSION}).

Motivo: :VERSION y :latest son punteros mutables — nada impide que en el futuro un tag se vuelva a mover a otro contenido. El digest identifica el contenido exacto de la imagen que Trivy ya escaneó unos pasos antes en el mismo job, así que la firma queda atada a ese contenido específico, no al nombre que apunta a él en un momento dado.

El digest se captura parseando la salida de docker push (sha256:[a-f0-9]{64}) inmediatamente después de subir la imagen, y se pasa como steps.push.outputs.digest a los pasos de firma y verificación (smoke test) que corren a continuación en el mismo job.

Rekor / transparency log: deshabilitado (decisión, no pendiente)

cosign sign corre con --use-signing-config=false --tlog-upload=false en los tres workflows — evaluado y confirmado el 2026-08-16, se mantiene así.

Razones:

  • El registry (gitea.cruzcloud.net) es privado, de un lab. No hay valor de auditoría en anunciar públicamente en Rekor qué se firmó y cuándo.
  • Subir al transparency log público requiere una llamada de red saliente por build hacia rekor.sigstore.dev, atravesando el túnel de Cloudflare. Este túnel ya tuvo un incidente de SNI/orden con Cosign (ver memoria de infraestructura), así que sumar otra dependencia de red saliente por cada build agrega superficie de fallo sin beneficio real en este contexto.
  • Impacto en tiempo de pipeline: evitado por completo al no hacer la llamada.

Si el registry deja de ser privado, o aparece un requisito de compliance externo que exija prueba pública de firma, revisar esta decisión.

Llaves públicas

Cada app commitea su llave pública junto al resto de sus manifiestos (workloads/<app>/cosign.pub), para que la verificación (paso de smoke test dentro del mismo workflow) sea local y no dependa de un servicio externo.