Descripción General
Los Software Bills of Materials (SBOMs) se están convirtiendo rápidamente en un componente obligatorio de la transparencia en la cadena de suministro de software. Órdenes ejecutivas, marcos regulatorios como NIST SSDF y estándares de la industria ahora requieren que las organizaciones produzcan, distribuyan y verifiquen SBOMs para cada lanzamiento de software. Un SBOM enumera cada componente, biblioteca y dependencia dentro de tu software — brindando a los consumidores la capacidad de evaluar riesgos, rastrear vulnerabilidades y verificar la procedencia.
En este laboratorio práctico, construirás un pipeline completo de SBOM desde cero. Al finalizar, serás capaz de:
- Generar SBOMs en formatos SPDX y CycloneDX usando Syft
- Escanear SBOMs en busca de vulnerabilidades conocidas usando Grype
- Adjuntar SBOMs como attestations firmadas a imágenes de contenedores usando Cosign
- Automatizar todo el flujo de trabajo en GitHub Actions y GitLab CI
- Aplicar requisitos de attestation de SBOM en el despliegue usando Kyverno
- Comparar SBOMs entre versiones para detectar cambios en las dependencias
Este laboratorio refleja flujos de trabajo de producción reales utilizados por equipos que adoptan SLSA, in-toto y seguridad de cadena de suministro basada en Sigstore.
Prerrequisitos
Antes de comenzar, asegúrate de tener las siguientes herramientas instaladas y configuradas:
| Herramienta | Propósito | Instalación |
|---|---|---|
| Syft | Generación de SBOM | curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin |
| Grype | Escaneo de vulnerabilidades | curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin |
| Cosign | Firma y attestation | go install github.com/sigstore/cosign/v2/cmd/cosign@latest |
| Docker | Construcción de contenedores | docs.docker.com |
| GitHub CLI (gh) | Acceso al repositorio y GHCR | brew install gh o cli.github.com |
También necesitas una cuenta de GitHub con acceso a GitHub Container Registry (GHCR), y una aplicación básica con un Dockerfile.
Configuración del Entorno
Crearemos una aplicación mínima de Node.js, la contenedorizaremos y la subiremos a GHCR. Esta imagen se convierte en el objetivo de todos los ejercicios posteriores de SBOM.
Paso 1: Crear el repositorio de prueba
mkdir sbom-pipeline-lab && cd sbom-pipeline-lab
git init
Paso 2: Crear una aplicación simple de Node.js
cat > package.json <<'EOF'
{
"name": "sbom-lab-app",
"version": "1.0.0",
"description": "SBOM pipeline lab application",
"main": "server.js",
"dependencies": {
"express": "^4.18.2",
"lodash": "^4.17.21",
"axios": "^1.6.0"
}
}
EOF
cat > server.js <<'EOF'
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({ status: 'ok', message: 'SBOM Pipeline Lab' });
});
app.listen(3000, () => console.log('Listening on port 3000'));
EOF
Paso 3: Crear el Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Paso 4: Construir y subir la imagen del contenedor
# Authenticate to GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u YOUR_GITHUB_USERNAME --password-stdin
# Build the image
docker build -t ghcr.io/YOUR_GITHUB_USERNAME/sbom-lab-app:v1.0.0 .
# Push to GHCR
docker push ghcr.io/YOUR_GITHUB_USERNAME/sbom-lab-app:v1.0.0
Reemplaza YOUR_GITHUB_USERNAME con tu nombre de usuario real de GitHub a lo largo de este laboratorio. Una vez completada la subida, anota el digest completo de la imagen — lo necesitarás para las operaciones de firma.
# Capture the image digest
export IMAGE=$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/YOUR_GITHUB_USERNAME/sbom-lab-app:v1.0.0)
echo $IMAGE
# Output: ghcr.io/YOUR_GITHUB_USERNAME/sbom-lab-app@sha256:abc123...
Ejercicio 1: Generar SBOM con Syft
Syft es una herramienta de código abierto de Anchore que genera SBOMs analizando imágenes de contenedores, sistemas de archivos y archivos comprimidos. Soporta múltiples formatos de salida incluyendo SPDX y CycloneDX — los dos estándares de SBOM dominantes.
Generar un SBOM en formato SPDX
syft $IMAGE -o spdx-json=sbom.spdx.json
Inspecciona la salida:
cat sbom.spdx.json | jq '.packages | length'
# Output: 287 (count varies based on image content)
# View detected packages
cat sbom.spdx.json | jq '.packages[] | {name: .name, version: .versionInfo, license: .licenseDeclared}' | head -40
Generar un SBOM en formato CycloneDX
syft $IMAGE -o cyclonedx-json=sbom.cyclonedx.json
Inspecciona la salida de CycloneDX:
cat sbom.cyclonedx.json | jq '.components | length'
# View components with licenses
cat sbom.cyclonedx.json | jq '.components[] | {name: .name, version: .version, type: .type}' | head -40
SPDX vs. CycloneDX: Diferencias Clave
| Característica | SPDX | CycloneDX |
|---|---|---|
| Origen | Linux Foundation | OWASP |
| Enfoque Principal | Cumplimiento de licencias y PI | Seguridad y análisis de riesgos |
| Estándar ISO | ISO/IEC 5962:2021 | ECMA-424 |
| Datos de Vulnerabilidades | Soporte nativo limitado | Campo vulnerabilities de primera clase |
| Formatos | JSON, RDF, XML, YAML, tag-value | JSON, XML, Protobuf |
| Mejor Para | Cumplimiento regulatorio, auditorías de licencias | DevSecOps, seguimiento de vulnerabilidades |
Para este laboratorio, usamos principalmente SPDX JSON porque es el formato requerido por muchos estándares de adquisición gubernamental y se integra bien con las attestations de Cosign. Sin embargo, ambos formatos son compatibles con Grype y Cosign.
Generar un resumen legible por humanos
syft $IMAGE -o syft-table
Esto imprime una tabla de todos los paquetes con nombre, versión y tipo — útil para una revisión rápida durante el desarrollo.
Ejercicio 2: Escanear SBOM en Busca de Vulnerabilidades con Grype
Grype es el escáner de vulnerabilidades de Anchore. Puede escanear imágenes de contenedores directamente, pero también puede escanear un archivo SBOM — lo cual es significativamente más rápido porque omite el paso de análisis de la imagen.
Escanear el SBOM
grype sbom:./sbom.spdx.json
Salida de ejemplo:
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
lodash 4.17.21 npm CVE-2025-XXXXX Medium
node 20.10.0 20.11.1 apk CVE-2024-22019 High
libcrypto3 3.1.4-r1 3.1.4-r3 apk CVE-2024-0727 Medium
Filtrar por severidad
# Show only Critical and High vulnerabilities
grype sbom:./sbom.spdx.json --fail-on critical
# Output results in JSON for CI processing
grype sbom:./sbom.spdx.json -o json > vulnerabilities.json
# Count vulnerabilities by severity
cat vulnerabilities.json | jq '[.matches[].vulnerability.severity] | group_by(.) | map({severity: .[0], count: length})'
Escaneo de imagen vs. escaneo de SBOM
Existe una distinción importante entre escanear la imagen directamente y escanear el SBOM:
# Direct image scan — Grype pulls and analyzes the image layers
grype $IMAGE
# SBOM scan — Grype reads the pre-generated package list
grype sbom:./sbom.spdx.json
| Enfoque | Velocidad | Precisión | Caso de Uso |
|---|---|---|---|
| Escaneo directo de imagen | Más lento (descarga capas) | Descubre todos los paquetes | Primer análisis, desarrollo local |
| Escaneo de SBOM | Rápido (lee archivo JSON) | Limitado al contenido del SBOM | Pipelines de CI, escaneos repetidos, auditoría |
El escaneo de SBOM es tan completo como el propio SBOM. Si Syft omitió un paquete (por ejemplo, un binario compilado estáticamente), Grype no encontrará vulnerabilidades para él. Para máxima cobertura, genera el SBOM con la opción --catalogers all de Syft.
Ejercicio 3: Adjuntar SBOM como Attestation de Cosign
Una attestation es una declaración firmada sobre un artefacto de software. Al adjuntar el SBOM como attestation, vinculas criptográficamente el SBOM al digest específico de la imagen — cualquiera puede verificar que el SBOM fue producido para esa imagen exacta y no ha sido alterado.
Adjuntar la attestation del SBOM
Usando el flujo keyless (Sigstore Fulcio) de Cosign:
cosign attest --predicate sbom.spdx.json \
--type spdxjson \
--yes \
$IMAGE
Este comando:
- Abre un navegador para autenticación OIDC (firma keyless vía Fulcio)
- Crea una attestation in-toto con tu SBOM como predicado
- Firma la attestation y la registra en el log de transparencia Rekor
- Sube la attestation al registry junto con la imagen
Verificar la attestation
cosign verify-attestation \
--type spdxjson \
--certificate-identity=YOUR_EMAIL@example.com \
--certificate-oidc-issuer=https://accounts.google.com \
$IMAGE | jq '.payload | @base64d | fromjson | .predicate'
Reemplaza la identidad del certificado y el emisor OIDC con los valores que correspondan a tu identidad de Sigstore. En entornos de CI (GitHub Actions), estos serían:
--certificate-identity=https://github.com/YOUR_ORG/YOUR_REPO/.github/workflows/build.yml@refs/heads/main
--certificate-oidc-issuer=https://token.actions.githubusercontent.com
Inspeccionar la attestation en el registry
# List referrers (OCI 1.1 registries)
cosign tree $IMAGE
Deberías ver la attestation listada como un referrer adjunto al manifiesto de la imagen. La attestation se almacena como un artefacto OCI en el mismo repositorio, etiquetada con la convención sha256-<digest>.att.
Ejercicio 4: Construir el Pipeline Completo en GitHub Actions
Ahora automatizamos todo en un único flujo de trabajo de CI/CD. Este pipeline construye la imagen, genera el SBOM, escanea vulnerabilidades y adjunta el SBOM como una attestation firmada.
Crea .github/workflows/sbom-pipeline.yml:
name: SBOM Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
permissions:
contents: read
packages: write
id-token: write # Required for Cosign keyless signing
attestations: write
jobs:
build-and-attest:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push image
id: build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
- name: Get image digest
id: digest
run: |
echo "image=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}@${{ steps.build.outputs.digest }}" >> $GITHUB_OUTPUT
- name: Install Syft
uses: anchore/sbom-action/download-syft@v0
- name: Generate SPDX SBOM
run: |
syft ${{ steps.digest.outputs.image }} -o spdx-json=sbom.spdx.json
echo "### SBOM Summary" >> $GITHUB_STEP_SUMMARY
echo "Package count: $(cat sbom.spdx.json | jq '.packages | length')" >> $GITHUB_STEP_SUMMARY
- name: Install Grype
uses: anchore/scan-action/download-grype@v4
- name: Scan SBOM for vulnerabilities
run: |
grype sbom:./sbom.spdx.json -o json > vulnerabilities.json
grype sbom:./sbom.spdx.json -o table >> $GITHUB_STEP_SUMMARY
# Fail if critical vulnerabilities are found
CRITICAL_COUNT=$(cat vulnerabilities.json | jq '[.matches[] | select(.vulnerability.severity=="Critical")] | length')
echo "Critical vulnerabilities: $CRITICAL_COUNT"
if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "::error::Found $CRITICAL_COUNT critical vulnerabilities. Failing pipeline."
exit 1
fi
- name: Install Cosign
uses: sigstore/cosign-installer@v3
- name: Attest SBOM
run: |
cosign attest --predicate sbom.spdx.json \
--type spdxjson \
--yes \
${{ steps.digest.outputs.image }}
- name: Verify attestation
run: |
cosign verify-attestation \
--type spdxjson \
--certificate-identity-regexp="https://github.com/${{ github.repository }}/" \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
${{ steps.digest.outputs.image }}
- name: Upload SBOM as artifact
uses: actions/upload-artifact@v4
with:
name: sbom-spdx
path: sbom.spdx.json
retention-days: 90
- name: Upload vulnerability report
uses: actions/upload-artifact@v4
if: always()
with:
name: vulnerability-report
path: vulnerabilities.json
retention-days: 90
Este flujo de trabajo utiliza firma keyless mediante la identidad OIDC de GitHub Actions. No se almacenan claves privadas en los secrets — Cosign obtiene un certificado de corta duración de la CA Fulcio de Sigstore, y el evento de firma se registra en el log de transparencia Rekor.
El pipeline falla si se detectan vulnerabilidades críticas. Ajusta el umbral cambiando el filtro de severidad en el paso de escaneo de Grype.
Ejercicio 5: Construir el Pipeline en GitLab CI
El pipeline equivalente en GitLab CI utiliza las mismas herramientas pero se adapta al modelo basado en stages de GitLab y su registry de contenedores integrado.
Crea .gitlab-ci.yml:
stages:
- build
- sbom
- scan
- attest
variables:
IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
IMAGE_DIGEST: ""
build:
stage: build
image: docker:24
services:
- docker:24-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker build -t $IMAGE .
- docker push $IMAGE
- |
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $IMAGE)
echo "IMAGE_DIGEST=$DIGEST" >> build.env
artifacts:
reports:
dotenv: build.env
generate-sbom:
stage: sbom
image: alpine:3.19
needs: [build]
before_script:
- apk add --no-cache curl jq
- curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
script:
- syft $IMAGE_DIGEST -o spdx-json=sbom.spdx.json
- echo "Package count:" $(cat sbom.spdx.json | jq '.packages | length')
artifacts:
paths:
- sbom.spdx.json
expire_in: 90 days
scan-vulnerabilities:
stage: scan
image: alpine:3.19
needs: [generate-sbom]
before_script:
- apk add --no-cache curl jq
- curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
script:
- grype sbom:./sbom.spdx.json -o json > vulnerabilities.json
- grype sbom:./sbom.spdx.json -o table
- |
CRITICAL_COUNT=$(cat vulnerabilities.json | jq '[.matches[] | select(.vulnerability.severity=="Critical")] | length')
echo "Critical vulnerabilities found: $CRITICAL_COUNT"
if [ "$CRITICAL_COUNT" -gt 0 ]; then
echo "ERROR: Critical vulnerabilities detected. Failing pipeline."
exit 1
fi
artifacts:
paths:
- vulnerabilities.json
expire_in: 90 days
when: always
attest-sbom:
stage: attest
image: alpine:3.19
needs: [build, generate-sbom, scan-vulnerabilities]
id_tokens:
SIGSTORE_ID_TOKEN:
aud: sigstore
before_script:
- apk add --no-cache curl
- curl -sSfL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o /usr/local/bin/cosign
- chmod +x /usr/local/bin/cosign
script:
- cosign attest --predicate sbom.spdx.json
--type spdxjson
--yes
$IMAGE_DIGEST
- cosign verify-attestation
--type spdxjson
--certificate-identity-regexp="https://gitlab.com/$CI_PROJECT_PATH//"
--certificate-oidc-issuer=https://gitlab.com
$IMAGE_DIGEST
Diferencias clave con respecto a la versión de GitHub Actions:
- GitLab utiliza stages en lugar de un solo job con steps
- El digest de la imagen se pasa entre stages mediante artefactos
dotenv - El token OIDC de GitLab se expone a través de
id_tokensy la variableSIGSTORE_ID_TOKEN - El emisor OIDC para verificación es
https://gitlab.com
Ejercicio 6: Verificar SBOM en el Despliegue
Generar y atestar SBOMs es solo la mitad de la historia. El verdadero beneficio de seguridad viene de aplicar la verificación en el momento del despliegue — rechazando cualquier imagen que carezca de una attestation de SBOM válida.
Opción A: Verificar en un script de despliegue
#!/bin/bash
# deploy.sh — Verify SBOM attestation before deploying
set -euo pipefail
IMAGE="$1"
echo "Verifying SBOM attestation for: $IMAGE"
cosign verify-attestation \
--type spdxjson \
--certificate-identity-regexp="https://github.com/YOUR_ORG/YOUR_REPO/" \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
"$IMAGE" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "SBOM attestation verified successfully."
kubectl set image deployment/myapp myapp="$IMAGE"
else
echo "ERROR: SBOM attestation verification failed. Deployment blocked."
exit 1
fi
Opción B: Aplicar con Kyverno en Kubernetes
Kyverno es un motor de políticas nativo de Kubernetes que puede verificar firmas de imágenes y attestations en el momento de admisión. La siguiente política rechaza cualquier pod cuya imagen carezca de una attestation de SBOM válida.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-sbom-attestation
spec:
validationFailureAction: Enforce
webhookTimeoutSeconds: 30
rules:
- name: check-sbom-attestation
match:
any:
- resources:
kinds:
- Pod
verifyImages:
- imageReferences:
- "ghcr.io/YOUR_ORG/*"
attestations:
- type: spdxjson
attestors:
- entries:
- keyless:
subject: "https://github.com/YOUR_ORG/YOUR_REPO/.github/workflows/sbom-pipeline.yml@refs/heads/main"
issuer: "https://token.actions.githubusercontent.com"
rekor:
url: https://rekor.sigstore.dev
conditions:
- all:
- key: "{{ len(spdxVersion) }}"
operator: GreaterThan
value: "0"
Aplica la política:
kubectl apply -f require-sbom-attestation.yaml
Prueba de admisión: imagen con attestation
# This should be ADMITTED
kubectl run test-admitted \
--image=ghcr.io/YOUR_ORG/sbom-lab-app@sha256:abc123... \
--restart=Never
# Expected output:
# pod/test-admitted created
Prueba de admisión: imagen sin attestation
# This should be REJECTED
kubectl run test-rejected \
--image=ghcr.io/YOUR_ORG/sbom-lab-app:unattested \
--restart=Never
# Expected output:
# Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request:
# resource Pod/default/test-rejected was blocked due to the following policies:
# require-sbom-attestation:
# check-sbom-attestation: 'image verification failed for ghcr.io/YOUR_ORG/sbom-lab-app:unattested:
# attestation spdxjson not found'
Este es el bucle de aplicación que hace que los SBOMs sean operacionalmente significativos — sin verificación en el despliegue, la generación de SBOM es solo documentación.
Ejercicio 7: Diferencias de SBOM Entre Versiones
Cuando lanzas una nueva versión, necesitas entender qué cambió en tu árbol de dependencias. Comparar SBOMs entre versiones revela paquetes añadidos, eliminados y actualizados — información crítica para evaluar nuevos riesgos.
Paso 1: Generar SBOMs para dos versiones
# Generate SBOM for v1.0.0
syft ghcr.io/YOUR_GITHUB_USERNAME/sbom-lab-app:v1.0.0 -o spdx-json=sbom-v1.spdx.json
# Generate SBOM for v1.1.0 (after updating dependencies)
syft ghcr.io/YOUR_GITHUB_USERNAME/sbom-lab-app:v1.1.0 -o spdx-json=sbom-v2.spdx.json
Paso 2: Extraer listas de paquetes
# Extract sorted package lists
cat sbom-v1.spdx.json | jq -r '.packages[] | "\(.name)@\(.versionInfo)"' | sort > packages-v1.txt
cat sbom-v2.spdx.json | jq -r '.packages[] | "\(.name)@\(.versionInfo)"' | sort > packages-v2.txt
Paso 3: Comparar las listas de paquetes
diff --unified packages-v1.txt packages-v2.txt
Salida de ejemplo:
--- packages-v1.txt
+++ packages-v2.txt
@@ -12,7 +12,8 @@
express@4.18.2
lodash@4.17.21
- axios@1.6.0
+ axios@1.7.2
+ helmet@7.1.0
mime-types@2.1.35
Paso 4: Identificar vulnerabilidades recién introducidas
# Scan only the new/changed packages
grype sbom:./sbom-v2.spdx.json -o json > vulns-v2.json
grype sbom:./sbom-v1.spdx.json -o json > vulns-v1.json
# Compare vulnerability counts
echo "v1.0.0 vulnerabilities: $(cat vulns-v1.json | jq '.matches | length')"
echo "v1.1.0 vulnerabilities: $(cat vulns-v2.json | jq '.matches | length')"
# Find NEW vulnerabilities in v1.1.0
comm -13 \
<(cat vulns-v1.json | jq -r '.matches[].vulnerability.id' | sort -u) \
<(cat vulns-v2.json | jq -r '.matches[].vulnerability.id' | sort -u)
Este proceso de comparación se puede automatizar en CI para comentar en pull requests con los cambios de dependencias, dando a los revisores visibilidad sobre el impacto en la cadena de suministro antes de fusionar.
Limpieza
Elimina los recursos creados durante este laboratorio:
# Delete local files
rm -f sbom.spdx.json sbom.cyclonedx.json vulnerabilities.json
rm -f sbom-v1.spdx.json sbom-v2.spdx.json packages-v1.txt packages-v2.txt
rm -f vulns-v1.json vulns-v2.json
# Remove the test image from GHCR (requires gh CLI)
gh api -X DELETE /user/packages/container/sbom-lab-app/versions/PACKAGE_VERSION_ID
# Remove the Kyverno policy
kubectl delete clusterpolicy require-sbom-attestation
# Remove the test pods
kubectl delete pod test-admitted test-rejected --ignore-not-found
# Remove the local repository
cd .. && rm -rf sbom-pipeline-lab
Conclusiones Clave
- Los SBOMs son una base para la seguridad de la cadena de suministro — proporcionan el inventario que permite el escaneo de vulnerabilidades, el cumplimiento de licencias y la verificación de procedencia.
- Syft genera SBOMs en todos los formatos principales — SPDX para cumplimiento regulatorio, CycloneDX para flujos de trabajo de seguridad, ambos compatibles en todo el ecosistema.
- Escanear el SBOM es más rápido que escanear la imagen — usa Grype con el prefijo
sbom:en pipelines de CI para ciclos de retroalimentación rápidos sin descargar capas de imagen. - Las attestations de Cosign vinculan criptográficamente los SBOMs a las imágenes — las attestations firmadas demuestran que un SBOM específico fue producido para un digest de imagen específico, almacenado en el registry junto a la imagen.
- La verificación en el despliegue es lo que hace que los SBOMs sean aplicables — sin control de admisión (Kyverno, OPA Gatekeeper o scripts de despliegue), los SBOMs permanecen como documentación sin fuerza.
- Las comparaciones de SBOM revelan cambios en la cadena de suministro entre versiones — automatizar la comparación de dependencias en CI da a los equipos visibilidad sobre nuevos riesgos antes de que el código llegue a producción.
Próximos Pasos
Continúa construyendo tu práctica de seguridad de cadena de suministro con estas guías relacionadas:
- Procedencia de Artefactos y Attestations — Aprende cómo los frameworks SLSA e in-toto extienden las attestations más allá de los SBOMs para cubrir la procedencia de construcción, la integridad del código fuente y las políticas de despliegue.
- Firma y Verificación de Imágenes de Contenedores con Sigstore y Cosign — Profundiza en la firma keyless, certificados Fulcio, logs de transparencia Rekor y políticas de verificación de firmas de imágenes.