Verificación de firmas de artefactos de imagen y no de imagen
Mantenga la integridad de las imágenes que se crean en el conducto de integración continua (CI) antes del despliegue verificando las firmas de imagen.
Antes de empezar
Antes de empezar a trabajar con la verificación de imágenes, asegúrate de que cumples los siguientes requisitos previos.
- Debe tener la clave pública GPG. Para obtener ayuda para generar la clave GPG, consulte la documentación.
- Debe añadir la variable de entorno
code-signing-certificatecon la clave pública GPG codificada en base 64. - Debes configurar las credenciales del registro para acceder a las imágenes de contenedor durante la verificación (consulta «Configuración de las credenciales del registro» ).
Verificación de imágenes
Una nueva etapa prod-verify-artifact verifica la firma de una imagen en el conducto Continuous Delivery (CD). Esta etapa realiza los pasos siguientes:
-
Descodifica la clave pública GPG codificada proporcionada por el usuario en un archivo temporal.
-
Crea una política de contenedor Docker (
/etc/containers/policy.json) con la clave pública.{ "default": [ { "type": "reject" } ], "transports": { "docker-daemon": { "": [ { "type": "reject" } ] }, "docker": { "": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/tmp/GPGPublicKey" } ] } } } -
Recupera la lista de artefactos para cada artefacto utilizando Skopeo para extraer la imagen con la política de contenedor.
skopeo copy docker://"${image}" dir:"${tmp_sign_dir}" --src-creds iamapikey:"${ibmcloud_api_key}"
Si la firma es válida y la ha verificado la clave pública proporcionada por el usuario, la extracción de imagen se realiza correctamente.
Configuración de las credenciales del registro para la verificación
Al verificar las firmas de las imágenes de contenedor, el proceso necesita credenciales para autenticarse en el registro de contenedores y acceder a las imágenes firmadas. El canal « DevSecOps » admite la resolución dinámica de credenciales en tiempo de ejecución, lo que permite configurar las credenciales de diversas formas con mecanismos de alternativa automáticos.
Jerarquía de resolución de credenciales
El proceso resuelve dinámicamente tanto el nombre de usuario como la clave API en tiempo de ejecución siguiendo esta jerarquía:
Orden de resolución de claves API:
- Clave API específica del espacio de nombres:
signing-token-apikey-{registry}-{namespace}(secreto) - Clave API específica del registro:
signing-token-apikey-{registry}(secreto) - Docker Configuración JSON:
signing-dockerconfigjson(secreto) - Soluciones alternativas específicas para ICR:
ciso-ibmcloud-api-key(secreto)ibmcloud-api-key(secreto)
Orden de resolución de nombres de usuario:
- Nombre de usuario específico del espacio de nombres:
signing-token-username-{registry}-{namespace}(variable de entorno) - Nombre de usuario específico del Registro:
signing-token-username-{registry}(variable de entorno) - Por defecto:
iamapikey(si no se ha configurado ningún nombre de usuario)
Donde:
{registry}es el nombre de host del registro (por ejemplo,us.icr.io,de.icr.io){namespace}es la ruta completa del espacio de nombres con las barras y los puntos sustituidos por guiones bajos (por ejemplo,my_namespace_path)
Configuración de credenciales específicas para cada espacio de nombres
Para un control de acceso más detallado, puede configurar credenciales específicas para un espacio de nombres del registro:
Clave API (secreta): signing-token-apikey-{registry}-{namespace}
Nombre de usuario (variable de entorno): signing-token-username-{registry}-{namespace}
Ejemplo: Para la imagen us.icr.io/my-namespace/my-app:latest
- registry:
us.icr.io - Espacio de nombres:
my-namespace - Clave secreta de la API:
signing-token-apikey-us.icr.io-my_namespace - Variable de entorno «username»:
signing-token-username-us.icr.io-my_namespace - Si no se indica el nombre de usuario, se utilizará por defecto:
iamapikey
Configuración de credenciales específicas del registro
Para un acceso más amplio a todos los espacios de nombres de un registro:
Clave API (secreta): signing-token-apikey-{registry}
Nombre de usuario (variable de entorno): signing-token-username-{registry}
Ejemplo: Para cualquier imagen en us.icr.io
- Clave secreta de la API:
signing-token-apikey-us.icr.io - Variable de entorno «username»:
signing-token-username-us.icr.io - Si no se indica el nombre de usuario, se utilizará por defecto:
iamapikey
Configuración del archivo JSON de configuración de « Docker »
Puedes proporcionar un archivo JSON de configuración de base64-encoded Docker que contenga las credenciales de varios registros:
Nombre secreto: signing-dockerconfigjson
Formato: Base64-encoded JSON, compatible con el formato config.json de Docker:
{
"auths": {
"us.icr.io": {
"username": "iamapikey",
"password": "your-api-key"
},
"us.icr.io/my-namespace": {
"username": "iamapikey",
"password": "namespace-specific-key"
}
}
}
El canal de procesamiento coincide primero con la ruta más específica, lo que permite anular la configuración a nivel de espacio de nombres dentro de Docker.
Configuración de ejemplo
Para ver una imagen us.icr.io/production/my-app:v1.0.0:
Opción 1: Específica del espacio de nombres (recomendada para entornos de producción)
- Clave secreta de la API:
signing-token-apikey-us.icr.io-production=your-namespace-api-key - Variable de entorno de nombre de usuario (opcional):
signing-token-username-us.icr.io-production=iamapikey - Si no se especifica el nombre de usuario, el valor predeterminado es
iamapikey
Opción 2: En todo el Registro
- Clave secreta de la API:
signing-token-apikey-us.icr.io=your-registry-api-key - Variable de entorno de nombre de usuario (opcional):
signing-token-username-us.icr.io=iamapikey - Si no se especifica el nombre de usuario, el valor predeterminado es
iamapikey
Opción 3: Archivo JSON de configuración de « Docker »
- Secreto:
signing-dockerconfigjson=base64-encoded-docker-config - El nombre de usuario se extrae del archivo JSON de configuración de Docker
Opción 4: valor predeterminado de « IBM Cloud » (automático para ICR)
- Clave secreta de la API:
ibmcloud-api-key=your-ibmcloud-api-key - El nombre de usuario predeterminado es
iamapikey
Verificación de artefactos que no son de imagen
En los procesos de DevSecOps, la firma de los artefactos firmados está sujeta a verificación. Esta sección describe los requisitos previos que los usuarios deben cumplir antes de continuar con la verificación de artefactos.
Antes de empezar
Antes de poder trabajar con la verificación de imagen, asegúrese de que tiene los siguientes requisitos previos.
-
Modifique la configuración de interconexión para habilitar el proceso de verificación. Añade el siguiente fragmento de código al archivo
.pipeline-config.yaml.verify-artifact: image: icr.io/continuous-delivery/pipeline/image-signing:1.0.0@sha256:e9d8e354668ba3d40be2aaee08298d2aa7f0e1c8a1829cca4094ec93830e3e6a image_pull_policy: IfNotPresent abort_on_failure: false dind: true script: | #!/usr/bin/env bash source /opt/commons/verify-artifact/verify_non_image_artifact.sh -
Descargue el artefacto y almacénelo en el tiempo de ejecución de conducto.
Antes de invocar la etapa
verify-artifact, descargue y almacene los artefactos necesarios en el tiempo de ejecución de Cocoa. De forma predeterminada, se verifican todos los artefactos que figuran en la colección «list_artifacts». Utiliza la propiedad de texto «skip-sign-artifact-type» para omitir la verificación de la firma de la imagen en los tipos de artefactos indicados (por ejemplo: registros; informes; documentación). El siguiente código de ejemplo muestra cómo descargar un artefacto de Cloud Object Storage y guardarlo en el entorno de ejecución de Cocoa:#!/usr/bin/env bash export SECRET_PATH="/config/ibmcloud-api-key" . "${ONE_PIPELINE_PATH}"/iam/get_token SKIP_SIGN_ARTIFACTS_TYPE="$(get_env skip-sign-artifact-type "")" IFS=';' read -ra ARTIFACT_LIST <<<"$SKIP_SIGN_ARTIFACTS_TYPE" list_artifacts | while IFS= read -r artifact; do type="$(load_artifact "$artifact" "type")" if [[ ! "${ARTIFACT_LIST[@]}" =~ "$type" ]] && [[ "$type" != "image" ]]; then inventory_entry="$(load_artifact "$artifact" "inventory-entry")" inventory_entry=${inventory_entry///artifacts/$WORKSPACE} artifact_url=$(jq -r .'app_artifacts.artifact_url' ${inventory_entry}) echo "downloading the artifact ${artifact_url}" curl -H "Authorization: bearer ${IAM_ACCESS_TOKEN}" --output outputfile ${artifact_url} save_file "${artifact}" outputfile fi done
Verificación de artefactos
En el proceso de verificación de artefactos, la clave pública GPG proporcionada por el usuario se importa en el conjunto de claves GPG. Se verificarán todos los artefactos listados en la colección list_artifacts. La etapa intenta
recuperar la firma del inventario y realiza la siguiente verificación:
gpg --verify "${signature}" "${artifactName}"
Si la firma es válida y se verifica utilizando la clave pública proporcionada, la etapa registrará las pruebas y marcará la etapa como satisfactoria.