{"id":617,"date":"2026-02-03T11:37:47","date_gmt":"2026-02-03T10:37:47","guid":{"rendered":"https:\/\/secure-pipelines.com\/?p=617"},"modified":"2026-03-24T17:17:26","modified_gmt":"2026-03-24T16:17:26","slug":"signing-verifying-container-images-sigstore-cosign","status":"publish","type":"post","link":"https:\/\/secure-pipelines.com\/es\/ci-cd-security\/signing-verifying-container-images-sigstore-cosign\/","title":{"rendered":"Firma y Verificaci\u00f3n de Im\u00e1genes Container con Sigstore y Cosign"},"content":{"rendered":"<h2>Introducci\u00f3n: Por qu\u00e9 la Firma de Artefactos es Importante en CI\/CD<\/h2>\n<p>Los pipelines modernos de entrega de software son extraordinariamente buenos para compilar y desplegar c\u00f3digo r\u00e1pidamente. Pero la velocidad sin confianza es un riesgo. Entre el momento en que el c\u00f3digo fuente se hace commit y el momento en que una imagen container se ejecuta en producci\u00f3n, existe una brecha \u2014 una brecha donde la manipulaci\u00f3n, la sustituci\u00f3n o la corrupci\u00f3n silenciosa pueden ocurrir sin que nadie lo note.<\/p>\n<p>Esto no es una preocupaci\u00f3n te\u00f3rica. El ataque a <strong>SolarWinds<\/strong> en 2020 demostr\u00f3 c\u00f3mo los adversarios pod\u00edan inyectar c\u00f3digo malicioso en un proceso de compilaci\u00f3n, produciendo artefactos firmados pero comprometidos que se propagaron a miles de organizaciones. La brecha de <strong>Codecov<\/strong> en 2021 mostr\u00f3 c\u00f3mo un script de CI manipulado pod\u00eda exfiltrar secretos de cada repositorio que lo utilizaba. En ambos casos, la cadena de suministro \u2014 la infraestructura entre el c\u00f3digo y el despliegue \u2014 fue la superficie de ataque.<\/p>\n<p>La firma de artefactos aborda una pieza cr\u00edtica de este rompecabezas: <strong>autenticidad e integridad<\/strong>. Al firmar criptogr\u00e1ficamente una imagen container, se crea un v\u00ednculo verificable entre la imagen y la identidad (persona, equipo o sistema CI) que la produjo. Los consumidores de esa imagen pueden entonces verificar la firma antes de ejecutarla, asegur\u00e1ndose de que no ha sido modificada desde que fue compilada.<\/p>\n<p>Durante a\u00f1os, la firma fue impracticable en la mayor\u00eda de las organizaciones. La gesti\u00f3n de claves GPG era engorrosa, la distribuci\u00f3n de claves era fr\u00e1gil y las herramientas requer\u00edan una profunda experiencia criptogr\u00e1fica. <strong>Sigstore<\/strong> cambi\u00f3 eso. Introdujo un conjunto de herramientas de c\u00f3digo abierto que hacen que la firma y la verificaci\u00f3n sean accesibles, automatizadas y \u2014 de manera cr\u00edtica \u2014 sin claves (keyless).<\/p>\n<p>Esta gu\u00eda recorre el ecosistema Sigstore, muestra c\u00f3mo firmar y verificar im\u00e1genes container con <strong>Cosign<\/strong>, integrar la firma en pipelines CI\/CD y adjuntar attestations y SBOMs. Al final, tendr\u00e1 una comprensi\u00f3n pr\u00e1ctica de c\u00f3mo hacer de la firma de artefactos una parte est\u00e1ndar de su proceso de entrega.<\/p>\n<h2>\u00bfQu\u00e9 es Sigstore?<\/h2>\n<p>Sigstore es un proyecto de c\u00f3digo abierto bajo la Linux Foundation que proporciona herramientas gratuitas, transparentes y f\u00e1ciles de usar para firmar, verificar y proteger artefactos de software. Fue creado para resolver un problema espec\u00edfico: hacer que la firma criptogr\u00e1fica sea pr\u00e1ctica para el ecosistema de c\u00f3digo abierto y m\u00e1s all\u00e1.<\/p>\n<p>El ecosistema Sigstore consta de tres componentes principales:<\/p>\n<h3>Cosign<\/h3>\n<p><strong>Cosign<\/strong> es la herramienta del lado del cliente para firmar y verificar im\u00e1genes container y otros artefactos OCI. Es con lo que los desarrolladores y los pipelines CI\/CD interact\u00faan directamente. Cosign soporta tanto la firma tradicional con par de claves como el flujo m\u00e1s reciente de firma keyless.<\/p>\n<h3>Fulcio<\/h3>\n<p><strong>Fulcio<\/strong> es una autoridad certificadora (CA) gratuita que emite certificados de corta duraci\u00f3n basados en una identidad OpenID Connect (OIDC). Cuando se utiliza la firma keyless, Fulcio verifica su identidad a trav\u00e9s de un proveedor OIDC (como Google, GitHub o Microsoft) y emite un certificado que vincula su identidad a una clave de firma. El certificado es v\u00e1lido solo por unos minutos \u2014 el tiempo suficiente para firmar un artefacto, pero lo suficientemente corto para que el compromiso de la clave no sea un riesgo persistente.<\/p>\n<h3>Rekor<\/h3>\n<p><strong>Rekor<\/strong> es un log de transparencia \u2014 un registro inmutable, de solo adici\u00f3n, que registra eventos de firma. Cada vez que se firma un artefacto, se a\u00f1ade un registro a Rekor. Esto proporciona un rastro p\u00fablico y auditable de qui\u00e9n firm\u00f3 qu\u00e9 y cu\u00e1ndo. Es conceptualmente similar a los logs de Certificate Transparency utilizados en el ecosistema TLS.<\/p>\n<h3>C\u00f3mo la Firma Keyless Difiere de GPG<\/h3>\n<p>La firma tradicional basada en GPG requiere generar un par de claves de larga duraci\u00f3n, proteger la clave privada, distribuir la clave p\u00fablica y gestionar la rotaci\u00f3n y revocaci\u00f3n de claves. Esto es operativamente pesado y propenso a errores, raz\u00f3n por la cual la mayor\u00eda de los proyectos nunca adoptaron la firma.<\/p>\n<p>La firma keyless de Sigstore elimina esta carga:<\/p>\n<ul>\n<li><strong>Sin claves de larga duraci\u00f3n<\/strong> \u2014 Las claves de firma son ef\u00edmeras. Existen solo durante la operaci\u00f3n de firma.<\/li>\n<li><strong>Confianza basada en identidad<\/strong> \u2014 En lugar de confiar en una clave, se conf\u00eda en una identidad (por ejemplo, un workflow de GitHub Actions, una direcci\u00f3n de correo electr\u00f3nico espec\u00edfica). Fulcio vincula la identidad a la clave ef\u00edmera mediante un certificado de corta duraci\u00f3n.<\/li>\n<li><strong>Transparencia por defecto<\/strong> \u2014 Cada evento de firma se registra en Rekor, creando un registro auditable sin necesidad de ejecutar su propia infraestructura.<\/li>\n<li><strong>Sin problema de distribuci\u00f3n de claves<\/strong> \u2014 Los verificadores no necesitan obtener una clave p\u00fablica fuera de banda. Verifican contra la identidad y el log de transparencia.<\/li>\n<\/ul>\n<h2>Firma de Im\u00e1genes Container con Cosign<\/h2>\n<h3>Instalaci\u00f3n de Cosign<\/h3>\n<p>Cosign se distribuye como un binario \u00fanico. Puede instalarlo en la mayor\u00eda de las plataformas:<\/p>\n<pre><code># macOS (Homebrew)\nbrew install cosign\n\n# Linux (Go install)\ngo install github.com\/sigstore\/cosign\/v2\/cmd\/cosign@latest\n\n# Linux (binary release)\ncurl -LO https:\/\/github.com\/sigstore\/cosign\/releases\/latest\/download\/cosign-linux-amd64\nchmod +x cosign-linux-amd64\nsudo mv cosign-linux-amd64 \/usr\/local\/bin\/cosign\n\n# Verify installation\ncosign version<\/code><\/pre>\n<h3>Firma con un Par de Claves<\/h3>\n<p>El enfoque m\u00e1s simple es generar un par de claves y usarlo para firmar im\u00e1genes. Esto es \u00fatil cuando se desea un control total sobre la gesti\u00f3n de claves o cuando la firma keyless no est\u00e1 disponible en su entorno.<\/p>\n<p><strong>Paso 1: Generar un par de claves<\/strong><\/p>\n<pre><code>cosign generate-key-pair<\/code><\/pre>\n<p>Esto crea dos archivos: <code>cosign.key<\/code> (clave privada, protegida por contrase\u00f1a) y <code>cosign.pub<\/code> (clave p\u00fablica). Almacene la clave privada de forma segura \u2014 en un gestor de secretos, HSM o b\u00f3veda cifrada.<\/p>\n<p><strong>Paso 2: Firmar una imagen container<\/strong><\/p>\n<pre><code># Sign an image by its digest (always prefer digest over tag)\ncosign sign --key cosign.key ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Cosign solicitar\u00e1 la contrase\u00f1a de la clave privada, generar\u00e1 una firma y la enviar\u00e1 al mismo registro OCI junto a la imagen. La firma se almacena como un artefacto OCI separado, etiquetado con una convenci\u00f3n que lo vincula al digest de la imagen.<\/p>\n<p><strong>Importante:<\/strong> Siempre firme por digest, no por tag. Los tags son mutables \u2014 alguien podr\u00eda mover un tag para apuntar a una imagen diferente despu\u00e9s de la firma. Los digests est\u00e1n direccionados por contenido y son inmutables.<\/p>\n<h3>Firma Keyless con Identidad OIDC<\/h3>\n<p>La firma keyless es el enfoque recomendado para pipelines CI\/CD. Elimina la necesidad de gestionar claves de firma por completo.<\/p>\n<pre><code># Keyless signing (interactive \u2014 opens browser for OIDC login)\ncosign sign ghcr.io\/myorg\/myapp@sha256:abc123...\n\n# Keyless signing (non-interactive, for CI\/CD)\n# The --yes flag skips the confirmation prompt\ncosign sign --yes ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>En un entorno CI\/CD como GitHub Actions, Cosign detecta autom\u00e1ticamente el token OIDC ambiental proporcionado por la plataforma. No se necesita interacci\u00f3n con el navegador.<\/p>\n<h3>Qu\u00e9 Ocurre Detr\u00e1s de Escena<\/h3>\n<p>Cuando ejecuta <code>cosign sign --yes<\/code> en modo keyless, ocurre la siguiente secuencia:<\/p>\n<ol>\n<li><strong>Generaci\u00f3n de clave ef\u00edmera<\/strong> \u2014 Cosign genera un par de claves temporal en memoria.<\/li>\n<li><strong>Autenticaci\u00f3n OIDC<\/strong> \u2014 Cosign obtiene un token de identidad OIDC del entorno (por ejemplo, el proveedor OIDC de GitHub Actions) o le solicita autenticarse a trav\u00e9s de un navegador.<\/li>\n<li><strong>Emisi\u00f3n de certificado<\/strong> \u2014 Cosign env\u00eda la clave p\u00fablica y el token OIDC a <strong>Fulcio<\/strong>. Fulcio verifica el token, extrae la identidad (correo electr\u00f3nico, URI del workflow, etc.) y emite un certificado X.509 de corta duraci\u00f3n que vincula la identidad a la clave p\u00fablica.<\/li>\n<li><strong>Firma<\/strong> \u2014 Cosign firma el digest de la imagen usando la clave privada ef\u00edmera.<\/li>\n<li><strong>Registro de transparencia<\/strong> \u2014 La firma, el certificado y el digest de la imagen se registran en <strong>Rekor<\/strong>. Esta entrada tiene marca de tiempo y es inmutable.<\/li>\n<li><strong>Carga de firma<\/strong> \u2014 La firma se env\u00eda al registro OCI como un artefacto complementario.<\/li>\n<li><strong>Destrucci\u00f3n de clave<\/strong> \u2014 La clave privada ef\u00edmera se descarta. Nunca se almacena en ning\u00fan lugar.<\/li>\n<\/ol>\n<p>El resultado es una imagen firmada con una cadena verificable: el log de Rekor prueba que la firma fue creada en un momento espec\u00edfico por una identidad espec\u00edfica, y el certificado de Fulcio prueba que la identidad fue autenticada en el momento de la firma.<\/p>\n<h2>Verificaci\u00f3n de Firmas<\/h2>\n<p>La firma solo es \u00fatil si los consumidores verifican. Cosign proporciona comandos de verificaci\u00f3n sencillos tanto para escenarios basados en claves como para keyless.<\/p>\n<h3>Verificaci\u00f3n con una Clave P\u00fablica<\/h3>\n<p>Si la imagen fue firmada con un par de claves, verifique usando la clave p\u00fablica:<\/p>\n<pre><code>cosign verify --key cosign.pub ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Cosign obtiene la firma del registro OCI, la verifica contra la clave p\u00fablica y muestra el resultado. Si la firma es v\u00e1lida, imprime el payload de la firma. Si no, sale con un error.<\/p>\n<h3>Verificaci\u00f3n Keyless<\/h3>\n<p>Para im\u00e1genes firmadas con keyless, la verificaci\u00f3n se basa en la identidad en lugar de una clave. Se especifica <em>qui\u00e9n<\/em> se espera que haya firmado la imagen:<\/p>\n<pre><code># Verify that a specific GitHub Actions workflow signed the image\ncosign verify \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Este comando verifica que:<\/p>\n<ul>\n<li>La imagen tiene una firma v\u00e1lida.<\/li>\n<li>El certificado de firma fue emitido por Fulcio.<\/li>\n<li>La identidad en el certificado coincide con el <code>--certificate-identity<\/code> especificado.<\/li>\n<li>El emisor OIDC coincide con <code>--certificate-oidc-issuer<\/code>.<\/li>\n<li>El evento de firma est\u00e1 registrado en el log de transparencia de Rekor.<\/li>\n<\/ul>\n<p>Tambi\u00e9n puede utilizar coincidencia con expresiones regulares para pol\u00edticas m\u00e1s flexibles:<\/p>\n<pre><code>cosign verify \\\n  --certificate-identity-regexp \"https:\/\/github.com\/myorg\/.*\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<h3>Aplicaci\u00f3n de Verificaci\u00f3n en Admission Controllers<\/h3>\n<p>La verificaci\u00f3n manual es \u00fatil para depuraci\u00f3n, pero los entornos de producci\u00f3n necesitan aplicaci\u00f3n automatizada. Los admission controllers de Kubernetes pueden rechazar cualquier imagen que no tenga una firma v\u00e1lida.<\/p>\n<p><strong>Kyverno<\/strong> es un motor de pol\u00edticas popular con soporte integrado de verificaci\u00f3n de Cosign:<\/p>\n<pre><code>apiVersion: kyverno.io\/v1\nkind: ClusterPolicy\nmetadata:\n  name: verify-image-signatures\nspec:\n  validationFailureAction: Enforce\n  background: false\n  rules:\n    - name: verify-cosign-signature\n      match:\n        any:\n          - resources:\n              kinds:\n                - Pod\n      verifyImages:\n        - imageReferences:\n            - \"ghcr.io\/myorg\/*\"\n          attestors:\n            - entries:\n                - keyless:\n                    subject: \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\"\n                    issuer: \"https:\/\/token.actions.githubusercontent.com\"\n                    rekor:\n                      url: https:\/\/rekor.sigstore.dev<\/code><\/pre>\n<p>El <strong>Sigstore Policy Controller<\/strong> (anteriormente Cosign Policy Webhook) proporciona funcionalidad similar con un enfoque nativo de Sigstore:<\/p>\n<pre><code>apiVersion: policy.sigstore.dev\/v1beta1\nkind: ClusterImagePolicy\nmetadata:\n  name: require-signed-images\nspec:\n  images:\n    - glob: \"ghcr.io\/myorg\/**\"\n  authorities:\n    - keyless:\n        identities:\n          - issuer: \"https:\/\/token.actions.githubusercontent.com\"\n            subject: \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\"\n        ctlog:\n          url: https:\/\/rekor.sigstore.dev<\/code><\/pre>\n<p>Con cualquiera de los enfoques, cualquier pod que haga referencia a una imagen sin firmar (o firmada incorrectamente) de su registro ser\u00e1 rechazado en el momento de la admisi\u00f3n.<\/p>\n<h2>Integraci\u00f3n de la Firma en Pipelines CI\/CD<\/h2>\n<h3>GitHub Actions con Firma Keyless<\/h3>\n<p>GitHub Actions tiene soporte nativo de OIDC, lo que lo convierte en el entorno ideal para la firma keyless. Aqu\u00ed hay un workflow completo que compila, env\u00eda y firma una imagen container:<\/p>\n<pre><code>name: Build and Sign Container Image\n\non:\n  push:\n    branches: [main]\n\npermissions:\n  contents: read\n  packages: write\n  id-token: write  # Required for keyless signing\n\njobs:\n  build-sign:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout code\n        uses: actions\/checkout@v4\n\n      - name: Set up Docker Buildx\n        uses: docker\/setup-buildx-action@v3\n\n      - name: Log in to GHCR\n        uses: docker\/login-action@v3\n        with:\n          registry: ghcr.io\n          username: ${{ github.actor }}\n          password: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Build and push image\n        id: build\n        uses: docker\/build-push-action@v6\n        with:\n          push: true\n          tags: ghcr.io\/${{ github.repository }}:${{ github.sha }}\n\n      - name: Install Cosign\n        uses: sigstore\/cosign-installer@v3\n\n      - name: Sign the image\n        env:\n          DIGEST: ${{ steps.build.outputs.digest }}\n        run: |\n          cosign sign --yes \\\n            ghcr.io\/${{ github.repository }}@${DIGEST}<\/code><\/pre>\n<p>Puntos clave:<\/p>\n<ul>\n<li>El permiso <code>id-token: write<\/code> habilita el proveedor OIDC de GitHub Actions, que Cosign utiliza para la firma keyless.<\/li>\n<li>La imagen se firma por <strong>digest<\/strong>, no por tag, utilizando la salida del paso de compilaci\u00f3n.<\/li>\n<li>No se necesitan secretos ni claves \u2014 el token OIDC de GitHub es la identidad.<\/li>\n<\/ul>\n<h3>Ejemplo de GitLab CI<\/h3>\n<p>GitLab CI tambi\u00e9n soporta tokens OIDC para la firma keyless. El enfoque es similar pero utiliza el mecanismo de ID token de GitLab:<\/p>\n<pre><code>stages:\n  - build\n  - sign\n\nvariables:\n  IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_SHORT_SHA}\n\nbuild:\n  stage: build\n  image: docker:24\n  services:\n    - docker:24-dind\n  script:\n    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY\n    - docker build -t $IMAGE .\n    - docker push $IMAGE\n    - echo \"DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $IMAGE | cut -d@ -f2)\" &gt;&gt; build.env\n  artifacts:\n    reports:\n      dotenv: build.env\n\nsign:\n  stage: sign\n  image: alpine:3.19\n  id_tokens:\n    SIGSTORE_ID_TOKEN:\n      aud: sigstore\n  before_script:\n    - apk add --no-cache cosign\n  script:\n    - cosign sign --yes ${CI_REGISTRY_IMAGE}@${DIGEST}<\/code><\/pre>\n<p>El bloque <code>id_tokens<\/code> instruye a GitLab para generar un token OIDC con la audiencia <code>sigstore<\/code>. Cosign recoge el token de la variable de entorno <code>SIGSTORE_ID_TOKEN<\/code> autom\u00e1ticamente.<\/p>\n<h3>Almacenamiento de Firmas en Registros OCI<\/h3>\n<p>Por defecto, Cosign almacena las firmas en el mismo registro OCI que la imagen firmada. La firma se env\u00eda como un tag separado siguiendo la convenci\u00f3n <code>sha256-&lt;digest&gt;.sig<\/code>. Esto significa:<\/p>\n<ul>\n<li>No se necesita infraestructura adicional para el almacenamiento de firmas.<\/li>\n<li>Las firmas viajan con la imagen cuando se replican o duplican.<\/li>\n<li>La mayor\u00eda de los registros principales (GHCR, Docker Hub, ECR, GCR, ACR, Harbor) soportan artefactos OCI y funcionan con Cosign de forma nativa.<\/li>\n<\/ul>\n<p>Si necesita almacenar firmas en un registro diferente (por ejemplo, un almac\u00e9n de firmas dedicado), puede usar la variable de entorno <code>COSIGN_REPOSITORY<\/code>:<\/p>\n<pre><code>export COSIGN_REPOSITORY=ghcr.io\/myorg\/signatures\ncosign sign --yes ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<h2>Attestations y Adjunci\u00f3n de SBOM<\/h2>\n<p>Las firmas prueban <em>qui\u00e9n<\/em> compil\u00f3 una imagen. Las attestations van m\u00e1s all\u00e1 \u2014 prueban <em>c\u00f3mo<\/em> fue compilada y <em>qu\u00e9<\/em> contiene. Cosign soporta adjuntar metadatos estructurados a las im\u00e1genes en forma de attestations in-toto.<\/p>\n<h3>Adjunci\u00f3n de SLSA Provenance con <code>cosign attest<\/code><\/h3>\n<p>SLSA (Supply-chain Levels for Software Artifacts) provenance describe el proceso de compilaci\u00f3n: qu\u00e9 c\u00f3digo fuente se utiliz\u00f3, qu\u00e9 builder se ejecut\u00f3, qu\u00e9 pasos se realizaron. Puede adjuntar una attestation de SLSA provenance a una imagen:<\/p>\n<pre><code># Create a provenance statement (simplified example)\ncat > provenance.json <<'EOF'\n{\n  \"_type\": \"https:\/\/in-toto.io\/Statement\/v1\",\n  \"subject\": [\n    {\n      \"name\": \"ghcr.io\/myorg\/myapp\",\n      \"digest\": {\n        \"sha256\": \"abc123...\"\n      }\n    }\n  ],\n  \"predicateType\": \"https:\/\/slsa.dev\/provenance\/v1\",\n  \"predicate\": {\n    \"buildDefinition\": {\n      \"buildType\": \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml\",\n      \"resolvedDependencies\": [\n        {\n          \"uri\": \"git+https:\/\/github.com\/myorg\/myapp@refs\/heads\/main\",\n          \"digest\": {\n            \"sha1\": \"def456...\"\n          }\n        }\n      ]\n    },\n    \"runDetails\": {\n      \"builder\": {\n        \"id\": \"https:\/\/github.com\/actions\/runner\"\n      }\n    }\n  }\n}\nEOF\n\n# Attest the image with the provenance statement (keyless)\ncosign attest --yes \\\n  --predicate provenance.json \\\n  --type slsaprovenance \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>En la pr\u00e1ctica, se utilizar\u00eda un generador de SLSA (como <code>slsa-github-generator<\/code>) para producir la provenance autom\u00e1ticamente en lugar de elaborarla manualmente.<\/p>\n<h3>Adjunci\u00f3n de SBOMs<\/h3>\n<p>Un Software Bill of Materials (SBOM) lista cada componente dentro de su imagen container. Cosign puede adjuntar un SBOM a una imagen para que los consumidores puedan inspeccionar su contenido:<\/p>\n<pre><code># Generate an SBOM using Syft\nsyft ghcr.io\/myorg\/myapp@sha256:abc123... -o spdx-json > sbom.spdx.json\n\n# Attach the SBOM as an attestation (recommended approach)\ncosign attest --yes \\\n  --predicate sbom.spdx.json \\\n  --type spdxjson \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Alternativamente, puede usar el comando m\u00e1s antiguo <code>cosign attach sbom<\/code>, aunque el enfoque basado en attestations es preferible porque est\u00e1 firmado y es verificable:<\/p>\n<pre><code># Older approach (attached but not signed)\ncosign attach sbom --sbom sbom.spdx.json \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<h3>Verificaci\u00f3n de Attestations<\/h3>\n<p>Los consumidores pueden verificar attestations de la misma manera que las firmas. El comando <code>cosign verify-attestation<\/code> verifica tanto la firma en la attestation como la identidad del firmante:<\/p>\n<pre><code># Verify SLSA provenance attestation\ncosign verify-attestation \\\n  --type slsaprovenance \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...\n\n# Verify SBOM attestation\ncosign verify-attestation \\\n  --type spdxjson \\\n  --certificate-identity \"https:\/\/github.com\/myorg\/myapp\/.github\/workflows\/release.yml@refs\/heads\/main\" \\\n  --certificate-oidc-issuer \"https:\/\/token.actions.githubusercontent.com\" \\\n  ghcr.io\/myorg\/myapp@sha256:abc123...<\/code><\/pre>\n<p>Tambi\u00e9n puede utilizar motores de pol\u00edticas como Kyverno para verificar attestations en el momento de la admisi\u00f3n, asegurando que solo las im\u00e1genes con provenance o SBOMs v\u00e1lidos se desplieguen en sus cl\u00fasteres.<\/p>\n<h2>Consideraciones de Seguridad y Compromisos<\/h2>\n<p>La firma de artefactos es una herramienta poderosa, pero es importante entender contra qu\u00e9 protege y contra qu\u00e9 no.<\/p>\n<h3>Contra Qu\u00e9 Protege la Firma<\/h3>\n<ul>\n<li><strong>Manipulaci\u00f3n despu\u00e9s de la compilaci\u00f3n<\/strong> \u2014 Si alguien modifica una imagen despu\u00e9s de que ha sido firmada, la firma ya no se verificar\u00e1. Esto detecta compromisos del registro, ataques man-in-the-middle y corrupci\u00f3n accidental.<\/li>\n<li><strong>Suplantaci\u00f3n de identidad<\/strong> \u2014 Con la firma keyless, la identidad del firmante est\u00e1 criptogr\u00e1ficamente vinculada a la firma. Un atacante no puede falsificar una firma que pretenda provenir de su pipeline CI sin comprometer el proveedor OIDC.<\/li>\n<li><strong>Repudio<\/strong> \u2014 El log de transparencia de Rekor proporciona un registro a prueba de manipulaci\u00f3n de los eventos de firma. Los firmantes no pueden negar haber firmado un artefacto.<\/li>\n<\/ul>\n<h3>Contra Qu\u00e9 NO Protege la Firma<\/h3>\n<ul>\n<li><strong>C\u00f3digo fuente malicioso<\/strong> \u2014 La firma prueba que la imagen fue compilada por un pipeline autorizado. No prueba que el c\u00f3digo fuente est\u00e9 libre de vulnerabilidades o puertas traseras. Una cuenta de desarrollador comprometida que env\u00ede c\u00f3digo malicioso producir\u00e1 una imagen leg\u00edtimamente firmada.<\/li>\n<li><strong>Entornos de compilaci\u00f3n comprometidos<\/strong> \u2014 Si el runner de CI en s\u00ed est\u00e1 comprometido (como en el escenario de SolarWinds), el atacante puede producir artefactos firmados. La firma prueba la identidad, no la integridad del entorno de compilaci\u00f3n.<\/li>\n<li><strong>Vulnerabilidades en dependencias<\/strong> \u2014 Una imagen firmada a\u00fan puede contener CVEs conocidos. La firma y el escaneo de vulnerabilidades son complementarios, no sustitutos.<\/li>\n<li><strong>Elusi\u00f3n de pol\u00edticas<\/strong> \u2014 La firma solo funciona si la verificaci\u00f3n se aplica. Si su admission controller tiene excepciones, o si los equipos pueden desplegar sin pasar por \u00e9l, la firma no proporciona protecci\u00f3n para esas rutas.<\/li>\n<\/ul>\n<h3>Supuestos del Modelo de Confianza<\/h3>\n<p>La firma keyless se basa en varios supuestos de confianza:<\/p>\n<ul>\n<li><strong>Confianza en el proveedor OIDC<\/strong> \u2014 Se conf\u00eda en que GitHub, GitLab o Google autentican correctamente las identidades. Un compromiso del proveedor OIDC socava todo el modelo.<\/li>\n<li><strong>Confianza en Fulcio<\/strong> \u2014 Se conf\u00eda en que la instancia de Fulcio de Sigstore verifica correctamente los tokens OIDC y emite certificados solo a identidades autenticadas.<\/li>\n<li><strong>Confianza en Rekor<\/strong> \u2014 Se conf\u00eda en que el log de transparencia es de solo adici\u00f3n y a prueba de manipulaci\u00f3n. La instancia p\u00fablica de Rekor de Sigstore es operada por la comunidad; para entornos de alta seguridad, puede querer ejecutar la suya propia.<\/li>\n<\/ul>\n<p>Para organizaciones con requisitos de cumplimiento estrictos, ejecutar una infraestructura privada de Sigstore (CA privada de Fulcio, log privado de Rekor) proporciona control total sobre la cadena de confianza.<\/p>\n<h3>Consideraciones de Gesti\u00f3n de Claves<\/h3>\n<p>Si elige la firma basada en claves en lugar de keyless:<\/p>\n<ul>\n<li>Almacene las claves privadas en un KMS (AWS KMS, GCP KMS, Azure Key Vault, HashiCorp Vault). Cosign tiene soporte nativo de KMS: <code>cosign sign --key awskms:\/\/\/arn:aws:kms:...<\/code><\/li>\n<li>Rote las claves en un calendario regular y tenga un plan de revocaci\u00f3n.<\/li>\n<li>Evite almacenar claves privadas como secretos de CI\/CD \u2014 t\u00edpicamente se registran, almacenan en cach\u00e9 y replican de maneras que aumentan la exposici\u00f3n.<\/li>\n<li>Use claves separadas para diferentes entornos (staging vs. producci\u00f3n) para limitar el radio de impacto.<\/li>\n<\/ul>\n<h2>Conclusi\u00f3n<\/h2>\n<p>La firma de im\u00e1genes container con Sigstore y Cosign es uno de los pasos m\u00e1s impactantes que puede tomar para asegurar su cadena de suministro de software. Ya no es dif\u00edcil, ya no requiere una profunda experiencia criptogr\u00e1fica y ya no demanda una infraestructura compleja de gesti\u00f3n de claves. Con la firma keyless, un pipeline CI\/CD puede firmar cada imagen que produce con cero secretos que gestionar y total auditabilidad a trav\u00e9s del log de transparencia de Rekor.<\/p>\n<p>Pero la firma es un <strong>bloque de construcci\u00f3n<\/strong>, no una soluci\u00f3n m\u00e1gica. Responde a la pregunta \"\u00bffue esta imagen producida por un proceso autorizado?\" No responde \"\u00bfes seguro ejecutar esta imagen?\" Una estrategia completa de seguridad de la cadena de suministro combina la firma con el escaneo de vulnerabilidades, la generaci\u00f3n de SBOM, SLSA provenance, la aplicaci\u00f3n de pol\u00edticas en la admisi\u00f3n, el monitoreo de seguridad en tiempo de ejecuci\u00f3n y controles de acceso rigurosos en los repositorios de c\u00f3digo fuente y la infraestructura de compilaci\u00f3n.<\/p>\n<p>Comience agregando <code>cosign sign --yes<\/code> a su pipeline CI\/CD. Luego agregue verificaci\u00f3n en su admission controller. Despu\u00e9s agregue attestations y SBOMs. Cada paso reduce la brecha entre compilar software y confiar en \u00e9l.<\/p>\n<p>Las herramientas est\u00e1n maduras, el ecosistema est\u00e1 creciendo y el costo de <em>no<\/em> firmar es cada vez m\u00e1s dif\u00edcil de justificar. La pregunta ya no es si firmar sus artefactos \u2014 es qu\u00e9 tan r\u00e1pido puede convertirlo en el est\u00e1ndar.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introducci\u00f3n: Por qu\u00e9 la Firma de Artefactos es Importante en CI\/CD Los pipelines modernos de entrega de software son extraordinariamente buenos para compilar y desplegar c\u00f3digo r\u00e1pidamente. Pero la velocidad sin confianza es un riesgo. Entre el momento en que el c\u00f3digo fuente se hace commit y el momento en que una imagen container se &#8230; <a title=\"Firma y Verificaci\u00f3n de Im\u00e1genes Container con Sigstore y Cosign\" class=\"read-more\" href=\"https:\/\/secure-pipelines.com\/es\/ci-cd-security\/signing-verifying-container-images-sigstore-cosign\/\" aria-label=\"Leer m\u00e1s sobre Firma y Verificaci\u00f3n de Im\u00e1genes Container con Sigstore y Cosign\">Leer m\u00e1s<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[55,59],"tags":[],"post_folder":[],"class_list":["post-617","post","type-post","status-publish","format-standard","hentry","category-ci-cd-security","category-software-supply-chain"],"_links":{"self":[{"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/posts\/617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/comments?post=617"}],"version-history":[{"count":1,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/posts\/617\/revisions"}],"predecessor-version":[{"id":631,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/posts\/617\/revisions\/631"}],"wp:attachment":[{"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/media?parent=617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/categories?post=617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/tags?post=617"},{"taxonomy":"post_folder","embeddable":true,"href":"https:\/\/secure-pipelines.com\/es\/wp-json\/wp\/v2\/post_folder?post=617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}