feat(devsecops): firmar la imagen del frontend con Cosign
Firma la imagen (solo el tag versionado, no :latest) después del push exitoso, usando la llave privada desde secrets de Gitea Actions (COSIGN_PRIVATE_KEY/COSIGN_PASSWORD, nunca en el repo ni en disco). Verifica la firma como smoke test en el mismo pipeline contra workloads/ecommerce/cosign.pub (pública, commiteada a propósito). Firma solo con el par de llaves propio, sin publicar en el transparency log público de Sigstore (--use-signing-config=false --tlog-upload=false / --insecure-ignore-tlog=true) — registry privado, no tiene sentido esa fuga de metadata. Par de llaves generado y validado end-to-end (firma + verificación, incluyendo que verificar con la llave incorrecta falla como se espera) contra un registry local descartable antes de tocar nada real. Docs en docs/devsecops/cosign.md, incluyendo qué falta para que un admission controller verifique esto en el cluster (no implementado todavía).
This commit is contained in:
@@ -392,6 +392,51 @@ for r in results:
|
||||
docker push "${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
|
||||
docker push "${IMAGE_NAME}:latest"
|
||||
|
||||
- name: Instalar Cosign
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
COSIGN_VERSION="3.1.3"
|
||||
curl -sSfL \
|
||||
"https://github.com/sigstore/cosign/releases/download/v${COSIGN_VERSION}/cosign-linux-amd64" \
|
||||
-o /tmp/cosign
|
||||
chmod +x /tmp/cosign
|
||||
/tmp/cosign version
|
||||
|
||||
# Firma solo la versión (no :latest, que es un tag mutable y firmarlo
|
||||
# pierde sentido en cuanto se vuelve a mover). --use-signing-config=false
|
||||
# --tlog-upload=false: firma solo con el par de llaves propio, sin
|
||||
# publicar metadata en el transparency log público de Sigstore — este
|
||||
# registry es privado, no tiene sentido anunciar públicamente qué se
|
||||
# firmó y cuándo.
|
||||
- name: Firmar Imagen (Cosign)
|
||||
shell: bash
|
||||
env:
|
||||
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
|
||||
COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
/tmp/cosign sign \
|
||||
--key env://COSIGN_PRIVATE_KEY \
|
||||
--use-signing-config=false \
|
||||
--tlog-upload=false \
|
||||
--yes \
|
||||
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
|
||||
|
||||
# Smoke test: confirma en el propio pipeline que la firma que se
|
||||
# acaba de crear valida contra la llave pública commiteada en el
|
||||
# repo (workloads/ecommerce/cosign.pub). Es la misma verificación
|
||||
# que, más adelante, podría correr un admission controller en el
|
||||
# cluster antes de dejar desplegar la imagen (ver docs/devsecops/cosign.md).
|
||||
- name: Verificar Firma (smoke test)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
/tmp/cosign verify \
|
||||
--key "${APP_DIR}/cosign.pub" \
|
||||
--insecure-ignore-tlog=true \
|
||||
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
|
||||
|
||||
# Evita que una ejecución antigua actualice frontend.yaml después de que
|
||||
# ya exista un commit más reciente en main.
|
||||
- name: Verificar promoción segura
|
||||
|
||||
Reference in New Issue
Block a user