# 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//cosign.pub`), para que la verificación (paso de smoke test dentro del mismo workflow) sea local y no dependa de un servicio externo.