Verificando assinaturas de artefato de imagem e não imagem
Mantenha a integridade de imagens que são construídas no pipeline de Integração Contínua (CI) antes da implementação, verificando as assinaturas de imagem
Antes de Iniciar
Antes de começar a trabalhar com a verificação por imagem, certifique-se de que cumpre os seguintes pré-requisitos.
- Você deve ter a chave pública GPG. Para obter ajuda na geração de sua chave GPG, consulte a documentação
- Deve-se incluir a variável de ambiente
code-signing-certificatecom a chave pública GPG codificada em base 64. - É necessário configurar as credenciais do registro para acessar imagens de contêiner durante a verificação (consulte Configurando credenciais do registro ).
Verificando imagens
Um novo estágio prod-verify-artifact verifica a assinatura de uma imagem no pipeline do Continuous Delivery (CD) Esse estágio executa as seguintes etapas:
-
Decodifica a chave pública GPG fornecida pelo usuário em um arquivo temporário.
-
Cria uma política de contêiner Docker (
/etc/containers/policy.json) com a chave pública.{ "default": [ { "type": "reject" } ], "transports": { "docker-daemon": { "": [ { "type": "reject" } ] }, "docker": { "": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/tmp/GPGPublicKey" } ] } } } -
Recupera a lista de artefatos para cada artefato usando Skopeo para fazer pull da imagem com a política de contêiner
skopeo copy docker://"${image}" dir:"${tmp_sign_dir}" --src-creds iamapikey:"${ibmcloud_api_key}"
Se a assinatura for válida e verificada pela chave pública fornecida pelo usuário, a extração de imagem será bem-sucedida.
Configurando credenciais do Registro para verificação
Ao verificar as assinaturas das imagens de contêiner, o pipeline precisa de credenciais para se autenticar no registro de contêineres e acessar as imagens assinadas. O pipeline do DevSecOps oferece suporte à resolução dinâmica de
credenciais em tempo de execução, permitindo que você configure credenciais de várias maneiras com mecanismos automáticos de fallback.
Hierarquia de resolução de credenciais
O pipeline resolve dinamicamente as credenciais de nome de usuário e chave de API em tempo de execução, utilizando a seguinte hierarquia:
Ordem de resolução da chave da API:
- Chave de API específica do namespace:
signing-token-apikey-{registry}-{namespace}(segredo) - Chave de API específica do registro:
signing-token-apikey-{registry}(segredo) - Docker Arquivo de configuração JSON:
signing-dockerconfigjson(segredo) - Soluções alternativas específicas para ICR:
ciso-ibmcloud-api-key(segredo)ibmcloud-api-key(segredo)
Ordem de resolução de nomes de usuário:
- Nome de usuário específico do namespace:
signing-token-username-{registry}-{namespace}(variável de ambiente) - Nome de usuário específico do Registro:
signing-token-username-{registry}(variável de ambiente) - Padrão:
iamapikey(se nenhum nome de usuário estiver configurado)
Em que:
{registry}é o nome de host do registro (por exemplo,us.icr.io,de.icr.io){namespace}é o caminho completo do namespace, com barras e pontos substituídos por sublinhados (por exemplo,my_namespace_path)
Configurando credenciais específicas do namespace
Para um controle de acesso mais detalhado, é possível configurar credenciais específicas para um namespace do registro:
Chave da API (Segredo): signing-token-apikey-{registry}-{namespace}
Nome de usuário (variável de ambiente): signing-token-username-{registry}-{namespace}
Exemplo: Para a imagem us.icr.io/my-namespace/my-app:latest
- Registro:
us.icr.io - Espaço de nomes:
my-namespace - Chave secreta da API:
signing-token-apikey-us.icr.io-my_namespace - Variável de ambiente "username":
signing-token-username-us.icr.io-my_namespace - Se o nome de usuário não for fornecido, o padrão será:
iamapikey
Configurando credenciais específicas do registro
Para obter acesso mais amplo a todos os espaços de nomes em um registro:
Chave da API (Segredo): signing-token-apikey-{registry}
Nome de usuário (variável de ambiente): signing-token-username-{registry}
Exemplo: Para qualquer imagem em us.icr.io
- Chave secreta da API:
signing-token-apikey-us.icr.io - Variável de ambiente "username":
signing-token-username-us.icr.io - Se o nome de usuário não for fornecido, o padrão será:
iamapikey
Configurando o arquivo JSON de configuração d Docker
Você pode fornecer um arquivo JSON de configuração do tipo base64-encoded Docker que contenha credenciais para vários registros:
Nome secreto: signing-dockerconfigjson
Formato: Base64-encoded JSON compatível com o formato config.json do site Docker:
{
"auths": {
"us.icr.io": {
"username": "iamapikey",
"password": "your-api-key"
},
"us.icr.io/my-namespace": {
"username": "iamapikey",
"password": "namespace-specific-key"
}
}
}
O pipeline corresponde primeiro ao caminho mais específico, permitindo substituições no nível do namespace dentro da configuração do Docker.
Configuração de exemplo
Para ver uma imagem us.icr.io/production/my-app:v1.0.0:
Opção 1: Específico do namespace (recomendado para produção)
- Chave secreta da API:
signing-token-apikey-us.icr.io-production=your-namespace-api-key - Variável de ambiente de nome de usuário (opcional):
signing-token-username-us.icr.io-production=iamapikey - Se o nome de usuário não for especificado, o padrão será
iamapikey
Opção 2: Em todo o Registro
- Chave secreta da API:
signing-token-apikey-us.icr.io=your-registry-api-key - Variável de ambiente de nome de usuário (opcional):
signing-token-username-us.icr.io=iamapikey - Se o nome de usuário não for especificado, o padrão será
iamapikey
Opção 3: Arquivo JSON de configuração do Docker
- Segredo:
signing-dockerconfigjson=base64-encoded-docker-config - O nome de usuário é extraído do arquivo JSON de configuração Docker
Opção 4: Padrão do IBM Cloud (automático para ICR)
- Chave secreta da API:
ibmcloud-api-key=your-ibmcloud-api-key - O nome de usuário padrão é
iamapikey
Verificando artefatos sem imagem
Nos pipelines do DevSecOps, a assinatura dos artefatos assinados está sujeita a verificação. Esta seção descreve os pré-requisitos que os usuários devem atender antes de prosseguir com a verificação de artefato
Antes de Iniciar
Antes de poder trabalhar com a verificação de imagem, certifique-se de ter os pré-requisitos a seguir.
-
Modifique a configuração de seu pipeline para ativar o processo de verificação Adicione o seguinte trecho de código ao seu arquivo
.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 -
Faça download do artefato e o armazene no tempo de execução do pipeline.
Antes de chamar o estágio
verify-artifact, fazer download e armazenar os artefatos necessários no tempo de execução do Cocoa. Por padrão, todos os artefatos listados na coleçãolist_artifactssão verificados. Use a propriedade de texto "skip-sign-artifact-type" para ignorar a verificação da assinatura da imagem para os tipos de artefato especificados (por exemplo: log; relatório; documentação). O código de exemplo a seguir demonstra como baixar um artefato do site Cloud Object Storage e salvá-lo no ambiente de execução do 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
Verificando artefatos
No processo de verificação de artefato, a chave pública GPG fornecida pelo usuário é importada para o conjunto de chaves GPG. Todos os artefatos listados na coleção do list_artifacts serão verificados O estágio tenta recuperar
a assinatura do inventário e executa a verificação a seguir:
gpg --verify "${signature}" "${artifactName}"
Se a assinatura for válida e verificada usando a chave pública fornecida, o estágio registrará a evidência e marcará o estágio como bem-sucedido..