CI/CD-Einbindung konfigurieren

Durch die CI/CD-Integration werden Ihre CI/CD-Pipelines mit Artifact Guard verbunden, um Container-Sicherheitslücken während der Build-Phase zu erkennen.

Der Scanner unterstützt GitHub Actions, Cloud Build und Jenkins. Wenn es in eine Pipeline eingebunden ist, werden Container-Images anhand Ihrer Artifact Guard-Richtlinien ausgewertet, bevor die Images in eine Registry übertragen werden.

Scannerfunktionen

Die CI/CD-Integration wird als Binärdatei in Ihrem CI/CD-Workflow ausgeführt, um die folgenden Aufgaben auszuführen:

  • Richtlinienauswertung zur Build-Zeit: Neu erstellte Container-Images werden anhand Ihrer konfigurierten Artefakt-Guard-Richtlinien gescannt.
  • Build-Blockierung: Gibt Exit-Codes an Ihren CI/CD-Runner (GitHub Actions, Cloud Build oder Jenkins) zurück, um Builds zu blockieren, die gegen Ihre Sicherheitsrichtlinien verstoßen.
  • Scanberichte: Sendet Ergebnisse von Sicherheitslückenscans an Security Command Center und gibt lokale Berichte im JSON- oder SARIF-Format aus.

Zielrollen und ‑verantwortlichkeiten

Die CI/CD-Integration ist für die folgenden Teams konzipiert:

  • DevOps- oder Platform Engineering-Teams: Erstellen Sie Pipeline-Connectors und fügen Sie CI/CD-Workflowkonfigurationen Schritte für die Ausführung von Scannern hinzu.
  • Sicherheitsadministratoren: Definieren die Richtlinien für Sicherheitslücken zur Build-Zeit, die vom Scanner erzwungen werden.
  • Anwendungsentwickler: Überprüfen Sie die Protokolle der Scan-Ausführung in den CI/CD-Build-Ausgaben, um Richtlinienverstöße zu identifizieren und zu beheben.

Wichtige Begriffe und Konzepte

  • Common Vulnerabilities and Exposures (CVE): Eine öffentlich bekannt gegebene Computersicherheitslücke, der eine eindeutige Kennung zugewiesen wird.
  • Software-Materialliste (SBOM): Ein maschinenlesbares Inventar von Softwarekomponenten und ‑abhängigkeiten, mit dem CVEs und andere Sicherheitsrisiken identifiziert werden.
  • Artefakt: Im Kontext von Artifact Guard ein Container-Image, das von einer CI/CD-Pipeline erstellt wurde.
  • Connector: Eine Ressource, die Ihre CI/CD-Pipeline mit Artifact Guard verknüpft. Wenn die Connector-ID während eines Scans von der CI-Pipeline übergeben wird, bestimmt sie, mit welchen Richtlinien das Image bewertet wird.
  • CI-Richtlinie: Eine Richtlinie für Sicherheitslücken, in der die spezifischen CVE-, Schweregrad- und Paketregeln definiert werden, die während CI/CD-Builds erzwungen werden.

Allgemeiner Workflow

Führen Sie den folgenden Workflow aus, um CI/CD-Sicherheitslückenscans zu konfigurieren und auszuführen:

  1. CI-Connector für Ihre Ziel-CI/CD-Plattform erstellen
  2. Erstellen Sie eine Richtlinie für Artefaktschutz, die die Connector-ID in ihrem Pipeline-Bereich enthält.
  3. CI/CD-Pipeline konfigurieren, um sich beiGoogle Cloudzu authentifizieren, das Container-Image zu erstellen und den Scanner-Container auszuführen.

Wenn die Pipeline ausgeführt wird, bewertet der Scanner das Container-Image anhand Ihrer Richtlinie. Wenn das Bild gegen die Richtlinie verstößt, gibt der Scanner einen Fehler-Exitcode zurück, um den Build fehlschlagen zu lassen. Entwickler können dann die Build-Logs prüfen, anfällige Abhängigkeiten aktualisieren und den Build noch einmal ausführen.

Hinweis

Wenn Sie die CI/CD-Integration verwenden möchten, müssen Sie Artifact Guard aktivieren. Eine Anleitung dazu finden Sie in der Dokumentation zu Artifact Guard unter Vorbereitung.

Connector erstellen

Console

So erstellen Sie einen Connector in der Google Cloud -Konsole:

  1. Gehen Sie in der Google Cloud -Konsole zu Sicherheit > Einstellungen.
  2. Klicken Sie auf der Karte Artifact Guard auf Einstellungen verwalten.
  3. Klicken Sie auf Connector erstellen und geben Sie die folgenden Details für den Connector ein:
    • Connector-ID: Fügen Sie eine ID für den Connector hinzu.
    • Beschreibung: Geben Sie eine Beschreibung des Connectors ein.
    • CI/CD-Plattform: Wählen Sie die entsprechende CI/CD-Plattform aus der Liste aus. Verwenden Sie diesen Connector nur in Pipelines, die mit der ausgewählten CI/CD-Plattform erstellt wurden.
  4. Klicken Sie auf Erstellen.

Sie erhalten eine Benachrichtigung, wenn der Connector erfolgreich erstellt wurde. In der Tabelle Connectors sind die verfügbaren Connectors aufgeführt.

gcloud-CLI

Führen Sie den folgenden Befehl aus, um einen Connector mit der gcloud CLI zu erstellen:

gcloud alpha scc artifact-guard connectors create CONNECTOR_ID \
    --location=LOCATION \
    (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER) \
    --pipeline-type=PIPELINE_TYPE \
    [--description=DESCRIPTION] \
    [--display-name=DISPLAY_NAME]

Ersetzen Sie Folgendes:

  • CONNECTOR_ID: Eine Kennung für den Connector, z. B. my-connector.
  • LOCATION: Der Security Command Center-Standort, an dem Ihre Daten gespeichert sind. Nur global wird unterstützt.
  • ORGANIZATION_ID: Die Organisations-ID.
  • PROJECT_NUMBER: Die numerische Projektnummer.
  • PIPELINE_TYPE: Der Typ der CI/CD-Pipeline. Muss einer der folgenden Datentypen sein:
    • GOOGLE_CLOUD_BUILD
    • GITHUB_ACTIONS
    • JENKINS_PIPELINE
  • DESCRIPTION: Eine Textbeschreibung für den Connector.
  • DISPLAY_NAME: Ein nutzerfreundlicher Anzeigename für den Connector.

Connector aktualisieren

Console

So verknüpfen Sie eine Richtlinie mit einem Connector in der Google Cloud console:

  1. Gehen Sie in der Google Cloud -Konsole zu Sicherheit > Einstellungen.
  2. Klicken Sie auf der Karte Artifact Guard auf Einstellungen verwalten.
  3. Klicken Sie in der Tabelle Connectors neben dem Connector auf  und wählen Sie Add policy (Richtlinie hinzufügen) aus.
  4. Fahren Sie mit den Schritten zum Erstellen oder Aktualisieren einer Artifact Guard-Richtlinie fort. Weitere Informationen finden Sie unter Richtlinie erstellen.

gcloud-CLI

Verwenden Sie die folgenden Befehle, um vorhandene Connectors aufzurufen und ihre Richtlinienzuordnungen mit der gcloud CLI zu aktualisieren:

Connectors auflisten

gcloud alpha scc artifact-guard connectors list PARENT

Ersetzen Sie Folgendes:

  • PARENT: Eine Organisation oder ein Projekt. Zulässige Formate für die übergeordnete Ressource:
    • organizations/ORGANIZATION_ID/locations/LOCATION
    • projects/PROJECT_NUMBER/locations/LOCATION

Connector beschreiben

gcloud alpha scc artifact-guard connectors describe CONNECTOR_ID \
    --location=LOCATION \
    (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)

Connector-Richtlinienzuordnung aktualisieren

Wenn Sie einen Connector mit einer Richtlinie verknüpfen möchten, fügen Sie die Connector-ID in den Pipeline-Bereich Ihrer Richtliniendefinitionsdatei ein und aktualisieren Sie die Richtlinie mit dem Befehl gcloud alpha scc artifact-guard policies update. Weitere Informationen finden Sie unter Richtlinie erstellen.

Connector löschen

Console

So löschen Sie einen Connector in der Google Cloud Console:

  1. Gehen Sie in der Google Cloud -Konsole zu Sicherheit > Einstellungen.
  2. Klicken Sie auf der Karte Artifact Guard auf Einstellungen verwalten.
  3. Klicken Sie in der Tabelle Connectors (Connectors) neben dem Connector auf  und wählen Sie Delete connector (Connector löschen) aus.
  4. Folgen Sie der Anleitung, um den Connector zu löschen. Klicken Sie auf Abbrechen, um den Vorgang abzubrechen.

gcloud-CLI

Führen Sie zum Löschen eines Connectors mit der gcloud CLI den folgenden Befehl aus:

gcloud alpha scc artifact-guard connectors delete CONNECTOR_ID \
    --location=LOCATION \
    (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)

Bewertung vornehmen

Das Scannen auf Sicherheitslücken wird von GitHub Actions und Jenkins-Pipelines unterstützt. So führen Sie eine Bewertung durch:

  1. Secrets für die Authentifizierung erstellen
  2. Erstellen Sie eine Integrationsvorlagendatei speziell für Ihre Pipeline.
  3. Bewertung starten

Secret-Konfiguration

CI/CD-Pipelines, die außerhalb von Google Cloud ausgeführt werden, können sich entweder mit Dienstkontoschlüsseln oder mit der Workload Identity-Föderation authentifizieren. Eine ausführliche Anleitung zum Erstellen von Secrets finden Sie hier:

Dienstkontoschlüssel

Identitätsföderation von Arbeitslasten (für GitHub Actions)

Sie müssen Ihrer CI/CD-Umgebung mit einer der folgenden Methoden Secrets hinzufügen:

Methode mit Dienstkontoschlüssel

Ein Secret:

  • GCP_CREDENTIALS: Der Inhalt der heruntergeladenen JSON-Schlüsseldatei des Dienstkontos.

Methode für die Workload Identity-Föderation

Zwei Secrets:

  • GCP_WORKLOAD_IDENTITY_PROVIDER: Der vollständige Ressourcenname Ihres Workload Identity-Anbieters. Beispiel: projects/12345/locations/global/workloadIdentityPools/my-pool/providers/my-provider.

  • GCP_SERVICE_ACCOUNT: Die E-Mail-Adresse des Dienstkontos, dessen Identität angenommen werden soll.

Vorlagen für die Pipeline-Integration

Um eine Bewertung auszulösen, müssen Sie eine Datei erstellen, die für Ihre Pipeline (Cloud Build, GitHub Actions oder Jenkins) spezifisch ist. Verwenden Sie dazu die folgenden Vorlagenbeispiele:

Cloud Build

  • Informationen zu den einzelnen Feldern finden Sie unter Variablendefinitionen.

    steps:
          # Step 1: Generate auth token
          - name: 'gcr.io/cloud-builders/gcloud'
          id: 'Generate Token'
          entrypoint: 'bash'
          args:
                - '-c'
                - |
                echo "Starting token generation..."
                gcloud auth print-access-token > /workspace/gcp_token.txt
                if [ $? -eq 0 ]; then
                      echo "Token generated successfully."
                else
                      echo "Failed to generate token." >&2
                      exit 1
                fi
    
          # Step 2: Build the image locally
          - name: 'gcr.io/cloud-builders/docker'
          id: 'Build Image'
          entrypoint: 'bash'
          args:
                - '-c'
                - |
                echo "🚧 Building Docker image from source code..."
                docker build -t ${_IMAGE_NAME_TO_SCAN}:${_IMAGE_TAG} .
                if [ $? -ne 0 ]; then
                      echo "❌ Docker build failed."
                      exit 1
                fi
                echo "✅ Docker image built successfully: ${_IMAGE_NAME_TO_SCAN}:${_IMAGE_TAG}"
    
          # Step 3: Image scan for vulnerabilities
          - id: 'Image-Analysis'
          name: '${_SCANNER_IMAGE}'
          entrypoint: 'bash'
          args:
                - '-c'
                - |
                echo "Starting image scan with scanner: ${_SCANNER_IMAGE}"
    
                exit_code=0
    
                docker run --rm \
                      -v /var/run/docker.sock:/var/run/docker.sock \
                      -v /workspace:/workspace \
                      -e GCP_PROJECT_ID="${_PROJECT_ID}" \
                      -e ORGANIZATION_ID="${_ORGANIZATION_ID}" \
                      -e IMAGE_NAME="${_IMAGE_NAME_TO_SCAN}" \
                      -e IMAGE_TAG="${_IMAGE_TAG}" \
                      -e CONNECTOR_ID="${_CONNECTOR_ID}" \
                      -e TRIGGER_ID="${_TRIGGER_ID}" \
                      -e IGNORE_ERRORS="${_IGNORE_ERRORS}" \
                      -e GCP_ACCESS_TOKEN="$(cat /workspace/gcp_token.txt)" \
                      "${_SCANNER_IMAGE}" || exit_code=$?
    
                echo "Docker run finished with exit code: $exit_code"
    
                if [ $exit_code -eq 0 ]; then
                      echo "✅ Evaluation succeeded: Conformant image."
                elif [ $exit_code -eq 1 ]; then
                      echo "❌ Scan failed: Non-conformant image."
                      exit 1
                else
                      if [ "${_IGNORE_ERRORS}" = "true" ]; then
                            echo "⚠️ Server/internal error ignored. Continuing."
                      else
                            echo "❌ Server/internal error. Exiting."
                            exit 1
                      fi
                fi
    
          # Step 4: Configure Docker authentication for Artifact Registry
          - name: 'gcr.io/cloud-builders/gcloud'
          id: 'Configure Docker Auth'
          entrypoint: 'bash'
          args:
                - '-c'
                - |
                echo "🔐 Configuring Docker authentication for Artifact Registry..."
                gcloud auth configure-docker us-east1-docker.pkg.dev -q
                echo "✅ Docker authentication configured."
    
          # Step 5: Push image to Artifact Registry
          - name: 'gcr.io/cloud-builders/docker'
          id: 'Push Image to Artifact Registry'
          entrypoint: 'bash'
          args:
                - '-c'
                - |
    
                docker tag "${_IMAGE_NAME_TO_SCAN}:${_IMAGE_TAG}" "us-east1-docker.pkg.dev/${_PROJECT_ID}/${_AR_REPOSITORY}/${_IMAGE_NAME_TO_SCAN}:${_IMAGE_TAG}"
    
                echo "🚀 Pushing $_FULL_AR_TAG..."
                docker push "us-east1-docker.pkg.dev/${_PROJECT_ID}/${_AR_REPOSITORY}/${_IMAGE_NAME_TO_SCAN}:${_IMAGE_TAG}"
    
                echo "✅ Image pushed successfully."
    
    substitutions:
          _IMAGE_NAME_TO_SCAN: 'checkout-image'
          _ORGANIZATION_ID: 'orgId'
          _CONNECTOR_ID: 'connectorId'
          _SCANNER_IMAGE: 'us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest'
          _IMAGE_TAG: 'latest'
          _TRIGGER_ID: 'cloud-build-job'
          _PROJECT_ID: 'projectId'
          _AR_REPOSITORY: 'images'
          _IGNORE_ERRORS: "false"
    
    serviceAccount: "projects/projectId/serviceAccounts/id-compute@developer.gserviceaccount.com"
    
    options:
          logging: CLOUD_LOGGING_ONLY
    

GitHub Actions (Secret)

Diese Vorlage ist für GitHub Actions mit einem geheimen Schlüssel.

  • Fügen Sie den geheimen Schlüssel Ihres Dienstkontos (GCP_CREDENTIALS) hinzu.
  • Weitere Informationen zu zusätzlichen Feldern finden Sie unter Variablendefinitionen.

    # A workflow to BUILD the app image, RUN the scanner, and PUSH to AR if scan passes
    name: Build, Scan and Push
    
    on:
     workflow_dispatch:
       inputs:
          IMAGE_NAME_TO_SCAN:
                description: 'The tag for your application image to be built (e.g., my-app:latest)'
                required: true
                default: 'checkout-image'
          GCP_PROJECT_ID:
                description: 'GCP Project ID for authentication'
                required: true
                default: 'projectId'
          AR_REPOSITORY:
                description: 'Artifact Registry repository name (e.g., app-repo)'
                required: false
                default: 'images'
          ORGANIZATION_ID:
                description: 'Your GCP Organization ID'
                required: true
                default: 'orgId'
          CONNECTOR_ID:
                description: 'The ID for your pipeline connector'
                required: true
                default: 'connectorId'
          SCANNER_IMAGE:
                description: 'The full registry path for your PRE-BUILT scanner tool'
                required: true
                default: 'us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest'
          IMAGE_TAG:
                description: 'The Docker image version (of the app image)'
                required: true
                default: 'latest'
          IGNORE_SERVER_ERRORS:
                description: 'Ignore server errors'
                required: false
                type: boolean
                default: false
          VERBOSITY:
                description: 'Verbosity flag'
                required: false
                default: 'HIGH'
    
    jobs:
     build-and-scan:
       runs-on: ubuntu-latest
       steps:
          # 1. Check out repository (for your app's Dockerfile)
          - name: Check out repository
            uses: actions/checkout@v4
    
          # 2. Authenticate to Google Cloud
          - name: Authenticate to GCP
            id: auth
            uses: 'google-github-actions/auth@v2'
            with:
                credentials_json: '${{ secrets.GCP_CREDENTIALS }}'
    
          # 3. Set up the gcloud CLI
          - name: Set up Cloud SDK
            uses: 'google-github-actions/setup-gcloud@v2'
            with:
                project_id: ${{ inputs.GCP_PROJECT_ID }}
    
           # 4. Configure Docker (needed to pull SCANNER_IMAGE and push app image)
          - name: Configure Docker
            run: gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
    
          # 5. Build Application Image Locally (IMAGE_NAME_TO_SCAN)
          - name: Build Application Image Locally
            uses: docker/build-push-action@v5
            with:
                context: .
                file: ./Dockerfile
                push: false  # <-- Do not push
                load: true   # <-- Load image into the runner's local daemon
                # Tag the image with the name the scanner will look for
                tags: |
                ${{ inputs.IMAGE_NAME_TO_SCAN }}:${{ inputs.IMAGE_TAG }}
    
          # 6. Run Image Scan (Using the SCANNER_IMAGE)
          - name: 'Run Image Analysis Scan'
            if: steps.auth.outcome == 'success'
            run: |
                echo "📦 Pulling scanner image and running scan..."
    
          SCANNER_IMAGE="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.SCANNER_IMAGE || env.SCANNER_IMAGE }}"
          GCP_PROJECT_ID="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.GCP_PROJECT_ID || env.GCP_PROJECT_ID }}"
          ORGANIZATION_ID="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.ORGANIZATION_ID || env.ORGANIZATION_ID }}"
          IMAGE_NAME="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.IMAGE_NAME_TO_SCAN || env.IMAGE_NAME_TO_SCAN }}"
          IMAGE_TAG="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.IMAGE_TAG || env.IMAGE_TAG }}"
          CONNECTOR_ID="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.CONNECTOR_ID || env.CONNECTOR_ID }}"
          VERBOSITY="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.VERBOSITY || env.VERBOSITY }}"
          IGNORE_ERRORS="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.IGNORE_SERVER_ERRORS || (env.IGNORE_SERVER_ERRORS == 'true') }}"
    
          exit_code=0
    
          # This 'docker run' pulls the SCANNER_IMAGE from the registry
          # and passes the name of the locally-built app image (IMAGE_NAME)
          docker run --rm \
                -v /var/run/docker.sock:/var/run/docker.sock \
                -v ${{ steps.auth.outputs.credentials_file_path }}:/tmp/scc-key.json \
                -e GCLOUD_KEY_PATH=/tmp/scc-key.json \
                -e GCP_PROJECT_ID="${GCP_PROJECT_ID}" \
                -e ORGANIZATION_ID="${ORGANIZATION_ID}" \
                -e IMAGE_NAME="${IMAGE_NAME}" \
                -e IMAGE_TAG="${IMAGE_TAG}" \
                -e CONNECTOR_ID="${CONNECTOR_ID}" \
                -e BUILD_TAG="${{ github.workflow }}" \
                -e BUILD_ID="${{ github.run_number }}" \
                -e VERBOSITY="${VERBOSITY}" \
                "${SCANNER_IMAGE}" \
                || exit_code=$?
    
          echo "Docker run finished with exit code: $exit_code"
    
          # --- Replicate Jenkins Exit Code Logic ---
          if [ $exit_code -eq 0 ]; then
            echo "✅ Evaluation succeeded: Conformant image."
          elif [ $exit_code -eq 1 ]; then
            echo "❌ Scan failed: Non-conformant image (vulnerabilities found)."
            exit 1 # Fail the step
          else
           if [ "$IGNORE_ERRORS" = "true" ]; then
                echo "⚠️ Server/internal error occurred (Code: $exit_code), but IGNORE_SERVER_ERRORS=true. Proceeding."
          else
            echo "❌ Server/internal error occurred (Code: $exit_code) during evaluation. Set IGNORE_SERVER_ERRORS=true to override."
            exit 1 # Fail the step
          fi
          fi
    
          # 8. Push Application Image (ONLY if scan succeeded)
          # This step only runs if the 'Run Image Analysis Scan' step above exited with 0
          - name: Push Application Image to Artifact Registry
            run: |
            # Define the local and remote tags
            LOCAL_IMAGE_NAME="${{ inputs.IMAGE_NAME_TO_SCAN }}:${{ inputs.IMAGE_TAG }}"
    
            # This path is based on your 'Configure Docker' step (us-central1)
            # and the new AR_REPOSITORY input.
            FULL_AR_TAG="us-central1-docker.pkg.dev/${{ inputs.GCP_PROJECT_ID }}/${{ inputs.AR_REPOSITORY }}/${{ inputs.IMAGE_NAME_TO_SCAN }}:${{ inputs.IMAGE_TAG }}"
    
            echo "Tagging local image ${LOCAL_IMAGE_NAME} as ${FULL_AR_TAG}"
            docker tag "${LOCAL_IMAGE_NAME}" "${FULL_AR_TAG}"
    
            echo "Pushing ${FULL_AR_TAG} to Artifact Registry..."
            docker push "${FULL_AR_TAG}"
    

GitHub Actions (WIF)

Diese Vorlage ist für GitHub Actions mit der Identitätsföderation von Arbeitslasten vorgesehen.

  • Fügen Sie Ihren Workload Identity Provider im GitHub-Secret (GCP_WORKLOAD_IDENTITY_PROVIDER) hinzu.
  • Fügen Sie Ihr Dienstkonto im GitHub-Secret (GCP_SERVICE_ACCOUNT) hinzu.
  • Weitere Informationen zu zusätzlichen Feldern finden Sie unter Variablendefinitionen.

    # A workflow to BUILD the app image, RUN the scanner, and PUSH to AR if scan passes
    name: Build, Scan and Push
    
    on:
      push:
        branches:
          - main
      workflow_dispatch:
      inputs:
        IMAGE_NAME_TO_SCAN:
          description: 'The tag for your application image to be built (e.g., my-app:latest)'
          required: true
          default: 'checkout-image'
        GCP_PROJECT_ID:
          description: 'GCP Project ID for authentication and configuration'
          required: true
          default: 'projectId'
        ORGANIZATION_ID:
          description: 'Your GCP Organization ID'
          required: true
          default: 'orgId'
        CONNECTOR_ID:
          description: 'The ID for your pipeline connector'
          required: true
          default: 'connectorId'
        SCANNER_IMAGE:
          description: 'The Docker image that contains your scanner script'
          required: true
          default: 'us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest'
        IMAGE_TAG:
          description: 'The Docker image version'
          required: true
          default: 'latest'
        IGNORE_SERVER_ERRORS:
          description: 'If true, the pipeline continues on server/internal scanner errors.'
          required: false
          type: boolean
          default: false
    
    jobs:
      image-analysis-job:
      runs-on: ubuntu-latest
      permissions:
          contents: 'read'
          id-token: 'write'
    
      env:
          IMAGE_NAME_TO_SCAN: 'webgoat/webgoat'
          GCP_PROJECT_ID: 'projectId'
          ORGANIZATION_ID: 'orgId'
          CONNECTOR_ID: 'connectorId'
          SCANNER_IMAGE: 'us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest'
          IMAGE_TAG: 'imageTag'
          IGNORE_SERVER_ERRORS: 'false'
    
      steps:
          # Step 1: Authenticate and create credential file
          - name: 'Authenticate to Google Cloud'
          id: 'auth'
          uses: 'google-github-actions/auth@v2'
          with:
          workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
          service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
          create_credentials_file: true
    
          # Step 2: Set up gcloud SDK
          - name: 'Set up gcloud SDK'
          uses: 'google-github-actions/setup-gcloud@v2'
    
          # Step 3: Configure Docker for registries
          - name: 'Configure Docker for Artifact Registry'
          run: |
          gcloud auth configure-docker us-central1-docker.pkg.dev --quiet
    
          # Step 4: Run Image Analysis Scan and Handle Exit Codes
          - name: 'Run Image Analysis Scan'
          run: |
          echo "📦 Running container from scanner image..."
    
          # Determine values: Use manual inputs if available (event_name=workflow_dispatch), otherwise use env defaults
          SCANNER_IMAGE="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.SCANNER_IMAGE || env.SCANNER_IMAGE }}"
          GCP_PROJECT_ID="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.GCP_PROJECT_ID || env.GCP_PROJECT_ID }}"
          ORGANIZATION_ID="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.ORGANIZATION_ID || env.ORGANIZATION_ID }}"
          IMAGE_NAME="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.IMAGE_NAME_TO_SCAN || env.IMAGE_NAME_TO_SCAN }}"
          IMAGE_TAG="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.IMAGE_TAG || env.IMAGE_TAG }}"
          CONNECTOR_ID="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.CONNECTOR_ID || env.CONNECTOR_ID }}"
          IGNORE_ERRORS="${{ github.event_name == 'workflow_dispatch' && github.event.inputs.IGNORE_SERVER_ERRORS || (env.IGNORE_SERVER_ERRORS == 'true') }}"
    
          # Variable to store exit code
          exit_code=0
    
          # Run docker and capture exit code using || trick
          docker run --rm \
                -v /var/run/docker.sock:/var/run/docker.sock \
                -v ${{ steps.auth.outputs.credentials_file_path }}:/gcp-creds.json \
                -e GOOGLE_APPLICATION_CREDENTIALS=/gcp-creds.json \
                -e GCP_PROJECT_ID="${GCP_PROJECT_ID}" \
                -e ORGANIZATION_ID="${ORGANIZATION_ID}" \
                -e IMAGE_NAME="${IMAGE_NAME}" \
                -e IMAGE_TAG="${IMAGE_TAG}" \
                -e CONNECTOR_ID="${CONNECTOR_ID}" \
                -e RUN_ID="${{ github.run_number }}" \
                "${SCANNER_IMAGE}" \
                || exit_code=$?
    
          echo "Docker run finished with exit code: $exit_code"
    
          if [ $exit_code -eq 0 ]; then
                echo "✅ Evaluation succeeded: Conformant image."
          elif [ $exit_code -eq 1 ]; then
                echo "❌ Scan failed: Non-conformant image (vulnerabilities found)."
                exit 1 # Fail the step
          else
                if [ "$IGNORE_ERRORS" = "true" ]; then
                echo "⚠️ Server/internal error occurred (Code: $exit_code), but IGNORE_SERVER_ERRORS=true. Proceeding."
                # Do nothing, step passes
                else
                echo "❌ Server/internal error occurred (Code: $exit_code) during evaluation. Set IGNORE_SERVER_ERRORS=true to override."
                exit 1 # Fail the step
                fi
          fi
    

Jenkins (Secret)

  • Fügen Sie den geheimen Schlüssel des Dienstkontos (GCP_CREDENTIALS) hinzu.
  • Weitere Informationen zu zusätzlichen Feldern finden Sie unter Variablendefinitionen.

    pipeline {
          agent any
    
          parameters {
                string(
                      name: 'IMAGE_NAME_TO_SCAN',
                      defaultValue: 'checkout-image',
                      description: 'The tag for your application image to be built (e.g., my-app:latest)'
                )
                string(
                      name: 'GCP_PROJECT_ID',
                      defaultValue: 'projectId',
                      description: 'GCP Project ID for authentication'
                )
                string(
                      name: 'AR_REPOSITORY',
                      defaultValue: 'images',
                      description: 'Artifact Registry repository name (e.g., app-repo)'
                )
                string(
                      name: 'ORGANIZATION_ID',
                      defaultValue: 'orgId',
                      description: 'Your GCP Organization ID'
                )
                string(
                      name: 'CONNECTOR_ID',
                      defaultValue: 'connectorId',
                      description: 'The ID for your pipeline connector'
                )
                string(
                      name: 'SCANNER_IMAGE',
                      defaultValue: 'us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest',
                      description: 'The full registry path for your PRE-BUILT scanner tool'
                )
                string(
                      name: 'IMAGE_TAG',
                      defaultValue: 'latest',
                      description: 'The Docker image version (of the app image)'
                )
                booleanParam(
                      name: 'IGNORE_SERVER_ERRORS',
                      defaultValue: false,
                      description: 'Ignore server errors'
                )
                string(
                      name: 'VERBOSITY',
                      defaultValue: 'HIGH',
                      description: 'Verbosity flag'
                )
          }
    
    stages {
          // Stage 1: Check out the source code
          stage('Checkout') {
                steps {
                echo "Checking out source code..."
                checkout scm
                }
          }
    
          // Stage 2: Build application image
          stage('Build Application Image') {
                steps {
                echo "Building application image: ${params.IMAGE_NAME_TO_SCAN}:${params.IMAGE_TAG}"
                sh "docker build -t ${params.IMAGE_NAME_TO_SCAN}:${params.IMAGE_TAG} -f ./Dockerfile ."
                }
          }
    
          // Stage 3: Authenticate to Google Cloud and run scanner
          stage('Scan Image') {
                steps {
                script {
                      withCredentials([file(credentialsId: 'GCP_CREDENTIALS', variable: 'GCP_KEY_FILE')]) {
                            // Authenticate
                            sh "gcloud auth activate-service-account --key-file=\"$GCP_KEY_FILE\""
                            sh 'gcloud auth list'
                            sh 'gcloud auth configure-docker gcr.io --quiet'
                            sh 'gcloud auth configure-docker us-central1-docker.pkg.dev --quiet'
    
                            // Run scanner container
                            def exitCode = sh(
                            script: """
                                  echo "📦 Running scanner container from image: ${params.SCANNER_IMAGE}"
    
                                  docker run --rm \\
                                        -v /var/run/docker.sock:/var/run/docker.sock \\
                                        -v "$GCP_KEY_FILE":/tmp/scc-key.json \\
                                        -e GCLOUD_KEY_PATH=/tmp/scc-key.json \\
                                        -e GCP_PROJECT_ID="${params.GCP_PROJECT_ID}" \\
                                        -e ORGANIZATION_ID="${params.ORGANIZATION_ID}" \\
                                        -e IMAGE_NAME="${params.IMAGE_NAME_TO_SCAN}" \\
                                        -e IMAGE_TAG="${params.IMAGE_TAG}" \\
                                        -e CONNECTOR_ID="${params.CONNECTOR_ID}" \\
                                        -e BUILD_TAG="${env.JOB_NAME}" \\
                                        -e BUILD_ID="${env.BUILD_NUMBER}" \\
                                        "${params.SCANNER_IMAGE}"
                            """,
                            returnStatus: true
                            )
    
                            if (exitCode == 0) {
                            echo "✅ Evaluation succeeded: Conformant image."
                            } else if (exitCode == 1) {
                            error("❌ Scan failed: Non-conformant image (vulnerabilities found).")
                            } else {
                            if (params.IGNORE_SERVER_ERRORS) {
                                  echo "⚠️ Server/internal error occurred, but IGNORE_SERVER_ERRORS=true. Proceeding with pipeline."
                            } else {
                                  error("❌ Server/internal error occurred during evaluation. Set IGNORE_SERVER_ERRORS=true to override.")
                            }
                            }
                      }
                }
                }
          }
    
          // Stage 4: Push Application Image
          stage('Push Application Image') {
                steps {
                script {
                      def localImage = "${params.IMAGE_NAME_TO_SCAN}:${params.IMAGE_TAG}"
                      def remoteTag = "us-central1-docker.pkg.dev/${params.GCP_PROJECT_ID}/${params.AR_REPOSITORY}/${params.IMAGE_NAME_TO_SCAN}:${params.IMAGE_TAG}"
    
                      echo "Tagging local image ${localImage} as ${remoteTag}"
                      sh "docker tag ${localImage} ${remoteTag}"
    
                      echo "Pushing ${remoteTag} to Artifact Registry..."
                      sh "docker push ${remoteTag}"
                }
                }
          }
    }
    

Variablendefinitionen

In diesem Abschnitt finden Sie Informationen zu den Variablenfeldern, die in den Vorlagen für die Pipeline-Integration verwendet werden.

IMAGE_NAME_TO_SCAN (erforderlich)

  • Gibt das Tag des zu erstellenden Anwendungs-Images an.

GCP_PROJECT_ID (erforderlich)

  • Gibt die Google Cloud Projekt-ID an, die für die Authentifizierung und Konfiguration verwendet wird.

AR_REPOSITORY (optional)

  • Gibt den Namen des Artifact Registry-Repositorys an, in dem das Image veröffentlicht wird, wenn der Build erfolgreich ist.

ORGANIZATION_ID (erforderlich)

  • Die Google Cloud Organisations-ID.

CONNECTOR_ID (erforderlich)

  • Gibt die Connector-ID der zu verwendenden Pipeline an.

SCANNER_IMAGE (erforderlich)

  • Das vorgefertigte Scanner-Image analysiert Code, identifiziert Sicherheitslücken, indem es Images während des Builds anhand von Richtlinien auswertet, und gibt ein Konformitätsergebnis aus, um festzustellen, ob die CI/CD-Pipeline erfolgreich ist oder fehlschlägt.

    Bilddetails: us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest

VERBOSITY (optional)

  • Der Scanner unterstützt ein optionales VERBOSITY-Flag, mit dem die Detailgenauigkeit der Scanausgabe gesteuert wird. Die Scannerausgabe variiert je nach Ausführlichkeitsgrad und Konformitätsergebnis (Bestanden oder Nicht bestanden).
  • Das Flag für die Ausführlichkeit kann auf LOW oder HIGH gesetzt werden. Wenn kein Wert angegeben ist, wird standardmäßig LOW verwendet.

Geringe Ausführlichkeit (prägnant)

ArtifactGuard-Konformität: Bestanden

  • Hier werden die Richtliniennamen aufgeführt.
  • Es wird nur die zusammengefasste Anzahl von CVEs nach Schweregrad angegeben.

ArtifactGuard-Konformität: Fehler

  • Details zum Grund für den Fehler.
  • Es werden nur die spezifischen CVEs aufgeführt, die den Fehler verursacht haben.
  • Hier finden Sie eine zusammengefasste Anzahl von CVEs, kategorisiert nach Schweregrad.

Hohe Ausführlichkeit (detailliert)

Bietet eine umfassende Liste aller gefundenen Sicherheitslücken.

ArtifactGuard-Konformität: Bestanden

  • Gibt eine Liste aller für die Richtlinie erkannten CVEs zurück.
  • Bietet eine Zusammenfassung der Anzahl der CVEs, aufgeschlüsselt nach Schweregrad.
  • Bietet eine umfassende Liste aller erkannten Sicherheitslücken.

ArtifactGuard-Konformität: Fehler

  • Enthält den Grund für den Fehler.
  • Listet die CVEs auf, die den Fehler verursachen.
  • Stellt eine Liste aller für die Richtlinie erkannten CVEs bereit.
  • Bietet eine Zusammenfassung der Anzahl der CVEs, aufgeschlüsselt nach Schweregrad.
  • Bietet eine umfassende Liste aller erkannten Sicherheitslücken.

IGNORE_SERVER_ERRORS (optional)

  • Ein optionales boolesches Flag. Bei true wird die Pipeline trotz Serverfehlern fortgesetzt. Die Standardeinstellung ist false.

Bewertung starten

Während des Build-Prozesses wird das Image mit einer Docker-basierten Strategie anhand vordefinierter Richtlinien bewertet. Die Logik für das Scannen auf Sicherheitslücken ist im us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest-Image enthalten.

Führen Sie den folgenden Befehl aus, um einen Sicherheitslückenscan in Ihrer CI/CD-Pipeline zu starten:

docker run --rm \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v ${{ steps.auth.outputs.credentials_file_path }}:/gcp-creds.json \
    -e GOOGLE_APPLICATION_CREDENTIALS=/gcp-creds.json \
    -e GCP_PROJECT_ID="${GCP_PROJECT_ID}" \
    -e ORGANIZATION_ID="${ORGANIZATION_ID}" \
    -e IMAGE_NAME="${IMAGE_NAME}" \
    -e IMAGE_TAG="${IMAGE_TAG}" \
    -e CONNECTOR_ID="${CONNECTOR_ID}" \
    -e RUN_ID="${{ github.run_number }}" \
    "${SCANNER_IMAGE}" \
    || exit_code=$?

Die CI/CD-Integration überträgt die Exit-Codes des Docker-Containers an die Jenkins- oder GitHub Actions-Laufzeitumgebung, die dann den Status der Pipeline bestimmt.

Fehlerbehebung

In diesem Abschnitt werden häufige Fehler und ihre Behebung beschrieben.

Fehler bei CreateConnector

Feld Erforderlich/Optional Einschränkungen
name Erforderlich Format:Muss dem regulären Ausdruck [a-zA-Z0-9\\-\\s_]+$
entsprechen. Muss mindestens einem der folgenden Elemente entsprechen:
  • Buchstaben (Groß- oder Kleinbuchstaben)
  • Ziffern
  • Bindestrich –
  • Leerzeichen (\s)
  • Unterstrich _


Maximale Länge:64 Zeichen.
pipeline_type Erforderlich Muss einer der folgenden Enumerationswerte sein:
  • JENKINS_PIPELINE
  • GITHUB_ACTIONS
  • GOOGLE_CLOUD_BUILD
description Optional Darf nicht länger als 256 Zeichen sein.
display_name Optional Darf nicht länger als 256 Zeichen sein.

Weitere Fehler

In der folgenden Tabelle sind einige häufige Fehler und ihre Behebung aufgeführt.

Fehlermeldung Ursache Maßnahme/Lösung
Berechtigung artifactscanguard.connectors.create für Ressource verweigert Dem Nutzer oder Dienstkonto fehlt die IAM-Berechtigung artifactscanguard.connectors.create für die Ressource (Projekt, Ordner oder Organisation). Weisen Sie dem Aufrufer eine IAM-Rolle mit der Berechtigung artifactscanguard.connectors.create zu.
status.ErrFailedPrecondition Das Onboarding kann auch dann noch laufen, wenn der Dienst in der Google Cloud -Konsole als aktiviert angezeigt wird. Melden Sie ein Problem an das Supportteam.
status.ErrInvalidArgument Fehler bei der Feldvalidierung Achten Sie darauf, dass die CreateConnector-Anfrage den angegebenen Einschränkungen entspricht.