CI/CD-Einbindung konfigurieren

Security Command Center-Kunden haben oft Schwierigkeiten, einen zentralen, umfassenden Überblick über die Scanergebnisse aus ihren CI/CD-Umgebungen (Continuous Integration/Continuous Delivery) zu erhalten. Diese fehlende ganzheitliche Übersicht erschwert die Verwaltung von Sicherheitslücken. Die CI/CD-Integration ist eine Komponente von Artifact Guard (Vorabversion), mit der Sie mehrere CI/CD-Pipelines verbinden können, um Sicherheitslücken im gesamten Lebenszyklus der Softwareentwicklung zu erkennen.

Die CI/CD-Integration unterstützt GitHub Actions, Cloud Build und Jenkins. Nach der Verbindung können Sie mit einer dieser CI/CD-Plattformen Artifact Guard-Richtlinien konfigurieren, um Ihren Sicherheitsstatus im Blick zu behalten und proaktiv zu kontrollieren.

Übersicht

Die CI/CD-Integration bietet Folgendes:

  • End-to-End-Richtlinienerzwingung: Unterstützt Artifact Guard bei der Anwendung konsistenter Sicherheitsrichtlinien vom Code bis zur Cloud.
  • Umfassende Bedrohungserkennung: Scannt nach Sicherheitslücken, offengelegten vertraulichen Informationen, problematischen Lizenzen und schädlichen Paketen.
  • Breite CI/CD-Kompatibilität: Funktioniert mit Jenkins und GitHub Actions.
  • Für CI/CD optimiert: Eine schlanke Binärdatei sorgt für einen effizienten Betrieb in lokalen Umgebungen.
  • Flexible Ausgabe: Ergebnisse werden in den Branchenstandardformaten JSON und SARIF bereitgestellt.
  • Zentrale Sicherheitsstatistiken: Bietet Ansichten zur Richtlinienkonformität direkt in Ihrem Sicherheitsdashboard.

Dieser Scanner füllt Security Command Center nativ aus und bietet so eine einheitliche, assetzentrierte Ansicht der Sicherheitsergebnisse ab der Artefakterstellung.

Die CI/CD-Integration hilft Ihnen, Artifact Guard-Richtlinien über den gesamten Softwarelebenszyklus hinweg durchzusetzen. So wird sichergestellt, dass Artefakte vom Build bis zum Deployment auf Konformität geprüft werden.

Zielgruppe

Die CI/CD-Integration kann bei den folgenden Aufgaben helfen:

  • Primäre Nutzer: DevOps- und Platform Engineering-Teams
    • Verwalten und einbinden: Verantwortlich für die Verwaltung des Scan-Tools und die direkte Einbindung in CI/CD-Pipelines.
    • Richtlinien konfigurieren: Richten Sie Scanvorgänge ein.
    • Compliance überwachen: Verfolgen Sie die Build-Compliance und arbeiten Sie mit Sicherheitsadministratoren zusammen, um Richtlinien zu optimieren.
  • Sekundäre Nutzer: Sicherheitsadministratoren
    • Richtlinienautoren: Definieren und erzwingen Sie Sicherheitsrichtlinien basierend auf der geschäftlichen Wichtigkeit.
    • Durchsetzung automatisieren: Automatisieren Sie die Sicherheit in CI/CD, um das Rauschen von Sicherheitslücken zu reduzieren und Gating-Kriterien festzulegen.
    • Aufsicht: Arbeiten Sie mit DevOps zusammen und bieten Sie ein Dashboard für das Management an, um Sicherheitslücken mit Gate zu verfolgen.
  • Sekundäre Nutzer: Anwendungsentwickler
    • Überprüfen und beheben: Interagieren Sie mit den Ergebnissen der Richtlinienbewertung, prüfen Sie die Build-Ergebnisse und beheben Sie gemeldete Sicherheitsprobleme.
    • Bewerten: Die Richtlinienbewertung wird indirekt über den Build-Prozess der CI-Pipeline initiiert.
    • Compliance aufrechterhalten: Sorgen Sie für die Einhaltung von Sicherheitsanforderungen, ohne die Entwicklungsworkflows zu unterbrechen.

Wichtige Begriffe und Konzepte

  • Common Vulnerabilities and Exposures (CVE): Eine öffentlich bekannt gegebene Computersicherheitslücke, der eine eindeutige Kennung zugewiesen wird. Diese Kennungen helfen dabei, Sicherheitslücken zur Behebung zu verfolgen.
  • Software-Materialliste (Software Bill of Materials, SBOM): Ein maschinenlesbares Inventar von Softwarekomponenten und ‑abhängigkeiten. Eine SBOM enthält Informationen zur Version, zum Ursprung und zu anderen relevanten Details jeder Komponente. SBOMs können verwendet werden, um CVEs und andere Sicherheitsrisiken zu identifizieren.
  • Artefakt: Eine versionierte und validierte Ausgabe der Softwareentwicklung, z. B. Daten oder ein Element, das während des Build-Prozesses erstellt wurde.
  • Connector: Ein Tag für Bilder. Wenn ein Connector von der CI-Pipeline an den Artifact Guard-Dienst übergeben wird, bestimmt er, welche Richtlinien für das Image ausgeführt werden, das erstellt wird.
  • CI-Richtlinie: Eine Richtlinie für Sicherheitslücken, in der Regeln oder Kriterien definiert werden, um zu steuern, welche Sicherheitslücken und Pakete in Ihrer Umgebung zulässig sind.

Allgemeiner Workflow

  1. CI-Connectors erstellen
  2. Erstellen Sie Artifact Guard-Richtlinien mit den im vorherigen Schritt konfigurierten Connectors, um den Richtlinienbereich zu definieren.
  3. Artefaktbewertungen initiieren:

Bei einer Auswertung wird ein Image erstellt und anhand vordefinierter Richtlinien ausgewertet. Wenn Richtlinien fehlschlagen, schlägt der Build fehl. DevOps- oder Anwendungsentwickler müssen dann die Fehlerdetails untersuchen, um die spezifische Sicherheitslücke zu finden, die Abhängigkeit gemäß den CVE-Details aktualisieren und die Pipeline 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.

Anschließend können Sie Connectors in der Google Cloud Console oder mit der Google Cloud CLI erstellen.

Connector in der Google Cloud Console erstellen

So erstellen Sie einen Connector:

  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. Dieser Connector sollte nur in den Pipelines verwendet werden, die mit der bereitgestellten CI/CD-Plattform erstellt wurden.
  4. Klicken Sie auf Erstellen.

Sie erhalten eine Benachrichtigung, wenn der Connector erfolgreich erstellt wurde. Verfügbare Connectors sind in der Tabelle „Connectors“ aufgeführt.

Wenn Sie einen Connector entfernen möchten, klicken Sie neben dem Connector auf  und wählen Sie Connector löschen aus. Folgen Sie dann der Anleitung. Klicken Sie auf Abbrechen, um den Vorgang abzubrechen.

Wenn Sie eine Richtlinie mit einem Connector verknüpfen möchten, klicken Sie neben dem Connector auf  und wählen Sie Richtlinie hinzufügen aus. Fahren Sie mit den Schritten zum Erstellen einer Artifact Guard-Richtlinie fort. Weitere Informationen finden Sie unter Richtlinie erstellen.

Connector mit der Google Cloud CLI erstellen

In diesem Abschnitt werden die gcloud CLI-Befehle beschrieben, die für das CI/CD-Artifact-Scanning verfügbar sind, und wie Sie sie verwenden.

Voraussetzungen für die Google Cloud CLI

  • Achten Sie darauf, dass Ihre gcloud CLI-Version 559.0.0 oder höher ist.
  • Legen Sie Ihr Projekt als Konfigurationsprojekt fest.

Führen Sie dazu die folgenden gcloud CLI-Befehle aus:

   gcloud components update --version=559.0.0
   gcloud config set project PROJECT_ID

Google Cloud CLI-Befehle

create

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]
  • CONNECTOR_ID: Die ID des zu erstellenden Connectors.
  • PIPELINE_TYPE: Der Typ der CI/CD-Pipeline. Muss einer der folgenden Werte sein:
    • GOOGLE_CLOUD_BUILD
    • GITHUB_ACTIONS
    • JENKINS_PIPELINE
  • DESCRIPTION: Eine Textbeschreibung für den Connector.
  • DISPLAY_NAME: Ein nutzerfreundlicher Anzeigename für den Connector.

get

gcloud alpha scc artifact-guard connectors describe CONNECTOR_ID \
    --location=LOCATION \
    (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
  • CONNECTOR_ID: Die ID des zu beschreibenden Connectors.

list

gcloud alpha scc artifact-guard connectors list PARENT
  • PARENT: Eine Organisation oder ein Projekt. Zulässige Formate für die übergeordnete Ressource sind:
    • {organizations/ORGANIZATION_ID/locations/LOCATION}
    • {projects/PROJECT_NUMBER/locations/LOCATION}

Löschen

gcloud alpha scc artifact-guard connectors delete CONNECTOR_ID \
    --location=LOCATION \
    (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
  • CONNECTOR_ID: Die ID des zu löschenden Connectors.

Bewertung vornehmen

Das Scannen auf Sicherheitslücken wird für 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 Pipelineintegration

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, die einen geheimen Schlüssel verwenden.

  • 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 vordefinierte 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 zu bestimmen, 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 Conformance : False

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

ArtifactGuard-Konformität : Bestanden

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

Hohe Ausführlichkeit (detailliert)

Bietet eine umfassende Liste aller gefundenen Sicherheitslücken.

ArtifactGuard Conformance : False

  • Enthält den Grund für den Fehler.
  • Listet die CVEs auf, die den Fehler verursachen.
  • 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 : 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.

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.

Leistung und Einschränkungen

  • Bewertung von Artefakten: Ein Bild wird nur bewertet, wenn es die folgenden Kriterien erfüllt:
    • Die Größe des pURL-Objekts (Package Uniform Resource Locator) darf 100 MB nicht überschreiten.
    • Das Bild darf maximal 500 pURLs enthalten.
  • Bis zu 1.200 API-Anfragen pro Minute (20 QPS) pro Nutzerprojekt für alle Methoden im Artifact Guard-Dienst.
  • SLO: Die Artefaktbewertung dauert etwa zwei Minuten.

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 die angegebenen Einschränkungen erfüllt.