Signaturen von Image-und Nicht-Image-Artefakten überprüfen
Bewahren Sie die Integrität von Images, die in der CI-Pipeline (Continuous Integration) erstellt wurden, vor der Implementierung, indem Sie Imagesignaturen überprüfen.
Vorbereitende Schritte
Bevor Sie mit der Bildüberprüfung beginnen, stellen Sie sicher, dass die folgenden Voraussetzungen erfüllt sind.
- Sie müssen über den öffentlichen GPG-Schlüssel verfügen. Hilfe zum Generieren Ihres GPG-Schlüssels finden Sie in der Dokumentation.
- Sie müssen die Umgebungsvariable
code-signing-certificatemit dem öffentlichen GPG-Schlüssel mit Base64-Codierung hinzufügen. - Sie müssen die Anmeldedaten für das Registry-Konto konfigurieren, um während der Überprüfung auf Container-Images zugreifen zu können (siehe „ Konfigurieren der Anmeldedaten für das Registry-Konto “).
Images überprüfen
Eine neue Stage prod-verify-artifact überprüft die Signatur eines Image in der CD-Pipeline ( Continuous Delivery ). Diese Stufe führt die folgenden Schritte aus:
-
Decodiert den vom Benutzer bereitgestellten codierten öffentlichen GPG-Schlüssel in eine temporäre Datei.
-
Erstellt eine Docker-Containerrichtlinie (
/etc/containers/policy.json) mit dem öffentlichen Schlüssel.{ "default": [ { "type": "reject" } ], "transports": { "docker-daemon": { "": [ { "type": "reject" } ] }, "docker": { "": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "/tmp/GPGPublicKey" } ] } } } -
Ruft die Liste der Artefakte für jedes Artefakt mithilfe von Skopeo ab, um das Image mit der Containerrichtlinie zu extrahieren.
skopeo copy docker://"${image}" dir:"${tmp_sign_dir}" --src-creds iamapikey:"${ibmcloud_api_key}"
Wenn die Signatur gültig ist und durch den vom Benutzer bereitgestellten öffentlichen Schlüssel überprüft wird, ist die Pull-Operation für das Image erfolgreich.
Konfigurieren von Registrierungsanmeldedaten für die Überprüfung
Bei der Überprüfung der Signaturen von Container-Images benötigt die Pipeline Anmeldedaten, um sich bei der Container-Registry zu authentifizieren und auf die signierten Images zuzugreifen. Die „ DevSecOps “-Pipeline unterstützt die dynamische Auflösung von Anmeldedaten zur Laufzeit, sodass Sie Anmeldedaten auf verschiedene Arten konfigurieren können, wobei automatische Ausweichmechanismen zum Einsatz kommen.
Hierarchie der Anmeldeinformationen
Die Pipeline löst sowohl den Benutzernamen als auch den API-Schlüssel zur Laufzeit dynamisch anhand der folgenden Hierarchie auf:
Reihenfolge der API-Schlüsselauflösung:
- Namespace-spezifischer API-Schlüssel:
signing-token-apikey-{registry}-{namespace}(Geheimnis) - Registry-spezifischer API-Schlüssel:
signing-token-apikey-{registry}(geheim) - Docker Konfigurations-JSON:
signing-dockerconfigjson(geheim) - ICR-spezifische Fallbacks:
ciso-ibmcloud-api-key(geheim)ibmcloud-api-key(geheim)
Reihenfolge der Benutzernamenauflösung:
- Namespace-spezifischer Benutzername:
signing-token-username-{registry}-{namespace}(Umgebungsvariable) - Registrierungsspezifischer Benutzername:
signing-token-username-{registry}(Umgebungsvariable) - Standard:
iamapikey(sofern kein Benutzername konfiguriert ist)
Dabei gilt:
{registry}ist der Hostname der Registrierungsstelle (z. B.us.icr.io,de.icr.io){namespace}ist der vollständige Namespace-Pfad, bei dem Schrägstriche und Punkte durch Unterstriche ersetzt wurden (z. B.my_namespace_path)
Konfigurieren von namensraumspezifischen Anmeldedaten
Für eine detaillierte Zugriffskontrolle können Sie für einen bestimmten Registrierungsnamensraum spezifische Anmeldedaten konfigurieren:
API-Schlüssel (Geheimnis): signing-token-apikey-{registry}-{namespace}
Benutzername (Umgebungsvariable): signing-token-username-{registry}-{namespace}
Beispiel: Für ein Bild us.icr.io/my-namespace/my-app:latest
- Registrierung:
us.icr.io - Namensraum:
my-namespace - Geheimer API-Schlüssel:
signing-token-apikey-us.icr.io-my_namespace - Umgebungsvariable „Benutzername“:
signing-token-username-us.icr.io-my_namespace - Wenn kein Benutzername angegeben wird, wird standardmäßig Folgendes verwendet:
iamapikey
Konfigurieren von registrierungsspezifischen Anmeldedaten
Für einen umfassenderen Zugriff auf alle Namensräume in einer Registrierungsstelle:
API-Schlüssel (Geheimnis): signing-token-apikey-{registry}
Benutzername (Umgebungsvariable): signing-token-username-{registry}
Beispiel: Für jedes Bild in us.icr.io
- Geheimer API-Schlüssel:
signing-token-apikey-us.icr.io - Umgebungsvariable „Benutzername“:
signing-token-username-us.icr.io - Wenn kein Benutzername angegeben wird, wird standardmäßig Folgendes verwendet:
iamapikey
Konfigurieren der JSON-Konfigurationsdatei für „ Docker “
Sie können eine JSON-Konfigurationsdatei unter base64-encoded Docker bereitstellen, die Anmeldedaten für mehrere Registries enthält:
Geheimer Name: signing-dockerconfigjson
Format: Base64-encoded JSON, das dem Format von Docker unter config.json entspricht:
{
"auths": {
"us.icr.io": {
"username": "iamapikey",
"password": "your-api-key"
},
"us.icr.io/my-namespace": {
"username": "iamapikey",
"password": "namespace-specific-key"
}
}
}
Die Pipeline gleicht zunächst den spezifischsten Pfad ab, wodurch Überschreibungen auf Namespace-Ebene innerhalb der Konfiguration unter „ Docker “ möglich sind.
Beispielkonfiguration
Für ein Bild us.icr.io/production/my-app:v1.0.0:
Option 1: Namespace-spezifisch (für die Produktion empfohlen)
- API-Schlüssel:
signing-token-apikey-us.icr.io-production=your-namespace-api-key - Umgebungsvariable für den Benutzernamen (optional):
signing-token-username-us.icr.io-production=iamapikey - Wenn kein Benutzername angegeben wird, wird standardmäßig
iamapikey
Option 2: Registrierungsweit
- API-Schlüssel:
signing-token-apikey-us.icr.io=your-registry-api-key - Umgebungsvariable für den Benutzernamen (optional):
signing-token-username-us.icr.io=iamapikey - Wenn kein Benutzername angegeben wird, wird standardmäßig
iamapikey
Option 3: JSON-Konfigurationsdatei für „ Docker “
- Geheimnis:
signing-dockerconfigjson=base64-encoded-docker-config - Der Benutzername wird aus der JSON-Konfigurationsdatei „ Docker “ extrahiert
Option 4: Standardwert für „ IBM Cloud “ (automatisch bei ICR)
- API-Schlüssel:
ibmcloud-api-key=your-ibmcloud-api-key - Der Benutzername lautet standardmäßig
iamapikey
Nicht-Image-Artefakte überprüfen
In „ DevSecOps “-Pipelines wird die Signatur signierter Artefakte überprüft. In diesem Abschnitt werden die Voraussetzungen beschrieben, die Benutzer erfüllen müssen, um mit der Artefaktprüfung fortzufahren.
Vorbereitende Schritte
Bevor Sie mit der Bildprüfung arbeiten können, müssen Sie sicherstellen, dass die folgenden Voraussetzungen erfüllt sind.
-
Ändern Sie Ihre Pipelinekonfiguration, um den Prüfungsprozess zu aktivieren. Füge den folgenden Codeausschnitt in deine Datei „
.pipeline-config.yaml“ ein.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 -
Laden Sie das Artefakt herunter und speichern Sie es in der Pipeline-Laufzeit.
Laden Sie vor dem Aufrufen der Stufe
verify-artifactdie erforderlichen Artefakte herunter und speichern Sie sie in der Cocoa-Laufzeit. Standardmäßig werden alle in der Sammlung „list_artifacts“ aufgeführten Artefakte überprüft. Verwenden Sie die Texteigenschaft „skip-sign-artifact-type“, um die Überprüfung der Bildsignatur für die angegebenen Artefakt-Typen (z. B. Log, Bericht, Dokumentation) zu überspringen. Der folgende Beispielcode zeigt, wie man ein Artefakt von Cloud Object Storage herunterlädt und in der Cocoa-Laufzeitumgebung speichert:#!/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
Artefakte überprüfen
Im Artefaktprüfprozess wird der vom Benutzer bereitgestellte öffentliche GPG-Schlüssel in den GPG-Schlüsselring importiert. Alle Artefakte, die in der Sammlung list_artifacts aufgelistet sind, werden überprüft. Die Phase versucht,
die Signatur aus dem Bestand abzurufen und führt die folgende Überprüfung durch:
gpg --verify "${signature}" "${artifactName}"
Wenn die Signatur gültig und mit dem bereitgestellten öffentlichen Schlüssel verifiziert ist, zeichnet die Phase die Angaben auf und markiert die Phase als erfolgreich.