name: "Cosign — firmar y verificar por digest" description: >- Firma la imagen por digest (no por tag) y verifica esa firma como smoke test, en el mismo job. --tlog-upload=false: sin publicar en el transparency log público de Sigstore (registry privado, no tiene sentido anunciar públicamente qué se firmó — ver docs/devsecops/cosign.md en apps-registry para el razonamiento completo de esta decisión). IMPORTANTE: un composite action no puede leer `secrets` directamente — el workflow que lo llama tiene que pasarlos como `with:` (ver ejemplo en el README de este snippet). inputs: image_name: description: "Nombre de la imagen sin tag/digest (ej. gitea.cruzcloud.net/devops/mi-app)." required: true digest: description: "Digest sha256:... a firmar (el output del paso que hace docker push)." required: true public_key_path: description: "Ruta al cosign.pub commiteado en el repo (para el smoke test de verificación)." required: true cosign_private_key: description: "Contenido de la llave privada de Cosign (pasar como \\${{ secrets.COSIGN_PRIVATE_KEY }} desde el caller)." required: true cosign_password: description: "Password de la llave privada (pasar como \\${{ secrets.COSIGN_PASSWORD }} desde el caller)." required: true cosign_version: description: "Versión de Cosign a instalar." required: false default: "3.1.3" runs: using: composite steps: - name: Instalar Cosign shell: bash run: | set -euo pipefail curl -sSfL \ "https://github.com/sigstore/cosign/releases/download/v${{ inputs.cosign_version }}/cosign-linux-amd64" \ -o /tmp/cosign chmod +x /tmp/cosign /tmp/cosign version - name: Firmar imagen (Cosign) — por digest shell: bash env: COSIGN_PRIVATE_KEY: ${{ inputs.cosign_private_key }} COSIGN_PASSWORD: ${{ inputs.cosign_password }} run: | set -euo pipefail /tmp/cosign sign \ --key env://COSIGN_PRIVATE_KEY \ --use-signing-config=false \ --tlog-upload=false \ --yes \ "${{ inputs.image_name }}@${{ inputs.digest }}" - name: Verificar firma (smoke test) shell: bash run: | set -euo pipefail /tmp/cosign verify \ --key "${{ inputs.public_key_path }}" \ --insecure-ignore-tlog=true \ "${{ inputs.image_name }}@${{ inputs.digest }}"