L'integrazione CI/CD connette le tue pipeline CI/CD a protezione artefatti per rilevare le vulnerabilità dei container durante la fase di build.
Lo scanner supporta GitHub Actions, Cloud Build e Jenkins. Quando viene integrato in una pipeline, valuta le immagini container in base alle policy di protezione artefatti prima che le immagini vengano inviate a un registro.
Funzionalità dello scanner
L'integrazione CI/CD viene eseguita come binario all'interno del flusso di lavoro CI/CD per svolgere le seguenti attività:
- Valutazione delle policy in fase di compilazione: esegue la scansione delle immagini container appena create in base alle policy di protezione degli artefatti configurate.
- Blocco delle build: restituisce codici di uscita al runner CI/CD (GitHub Actions, Cloud Build o Jenkins) per bloccare le build che violano le tue norme di sicurezza.
- Report di scansione: invia i risultati della scansione delle vulnerabilità a Security Command Center e genera report locali in formato JSON o SARIF.
Ruoli e responsabilità target
L'integrazione CI/CD è progettata per i seguenti team:
- Team DevOps o di ingegneria della piattaforma: crea connettori di pipeline e aggiungi passaggi di esecuzione dello scanner alle configurazioni del flusso di lavoro CI/CD.
- Amministratori della sicurezza: definiscono i criteri per le vulnerabilità in fase di compilazione che lo scanner applica.
- Sviluppatori di applicazioni: esamina i log di esecuzione della scansione negli output della build CI/CD per identificare e correggere le violazioni delle norme.
Termini e concetti chiave
- Vulnerabilità ed esposizioni comuni (CVE): una vulnerabilità di sicurezza informatica divulgata pubblicamente a cui viene assegnato un identificatore univoco.
- Software Bill of Materials (SBOM): una distinta base leggibile da macchina dei componenti software e delle dipendenze utilizzati per identificare CVE e altri rischi per la sicurezza.
- Artefatto: nel contesto di protezione artefatti, un'immagine container creata da una pipeline CI/CD.
- Connettore: una risorsa che collega la pipeline CI/CD a protezione artefatti. Se passato dalla pipeline CI durante una scansione, l'ID connettore determina quali policy valutano l'immagine.
- Policy CI: una policy sulle vulnerabilità che definisce le regole specifiche per CVE, gravità e pacchetti applicate durante le build CI/CD.
Workflow di alto livello
Per configurare ed eseguire le scansioni delle vulnerabilità CI/CD, completa il seguente flusso di lavoro:
- Crea un connettore CI per la tua piattaforma CI/CD di destinazione.
- Crea un criterio di protezione degli artefatti che includa l'ID connettore nell'ambito della pipeline.
- Configura la pipeline CI/CD per l'autenticazione a Google Cloud, crea l'immagine container ed esegui il container scanner.
Quando la pipeline viene eseguita, lo scanner valuta l'immagine container in base alla tua policy. Se l'immagine viola le norme, lo scanner restituisce un codice di uscita di errore per impedire la creazione. Gli sviluppatori possono quindi esaminare i log di build, aggiornare le dipendenze vulnerabili ed eseguire nuovamente la build.
Prima di iniziare
Per utilizzare l'integrazione CI/CD, devi abilitare la protezione artefatti. Per le istruzioni, vedi Prima di iniziare nella documentazione di protezione artefatti.
Crea connettore
Console
Per creare un connettore nella console Google Cloud :
- Nella console Google Cloud , vai a Sicurezza > Impostazioni.
- Nella scheda protezione artefatti, fai clic su Gestisci impostazioni.
- Fai clic su Crea connettore e inserisci i seguenti dettagli per il connettore:
- ID connettore: aggiungi un ID per il connettore.
- Description (Descrizione): inserisci una descrizione del connettore.
- Piattaforma CI/CD: seleziona la piattaforma CI/CD corrispondente dall'elenco. Utilizza questo connettore solo nelle pipeline create con la piattaforma CI/CD selezionata.
- Fai clic su Crea.
Una notifica conferma la creazione del connettore. La tabella Connettori elenca i connettori disponibili.
gcloud CLI
Per creare un connettore utilizzando gcloud CLI, esegui questo comando:
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]
Sostituisci quanto segue:
- CONNECTOR_ID: un identificatore per il connettore (ad esempio,
my-connector). - LOCATION: la posizione di Security Command Center in cui sono archiviati i dati. È supportato solo
global. - ORGANIZATION_ID: l'ID organizzazione.
- PROJECT_NUMBER: il numero di progetto numerico.
- PIPELINE_TYPE: il tipo di pipeline CI/CD. Deve essere uno dei seguenti:
GOOGLE_CLOUD_BUILDGITHUB_ACTIONSJENKINS_PIPELINE
- DESCRIPTION: una descrizione testuale del connettore.
- DISPLAY_NAME: un nome visualizzato facile da usare per il connettore.
Aggiorna un connettore
Console
Per collegare una policy a un connettore nella console Google Cloud :
- Nella console Google Cloud , vai a Sicurezza > Impostazioni.
- Nella scheda protezione artefatti, fai clic su Gestisci impostazioni.
- Nella tabella Connettori, fai clic su accanto al connettore e seleziona Aggiungi criterio.
- Procedi con i passaggi per creare o aggiornare una policy di protezione artefatti. Per saperne di più, consulta Creare una policy.
gcloud CLI
Per visualizzare i connettori esistenti e aggiornare le relative associazioni di policy utilizzando gcloud CLI, utilizza i seguenti comandi:
Elenco connettori
gcloud alpha scc artifact-guard connectors list PARENT
Sostituisci quanto segue:
- PARENT: Un'organizzazione o un progetto. I formati accettabili per la risorsa padre includono:
organizations/ORGANIZATION_ID/locations/LOCATIONprojects/PROJECT_NUMBER/locations/LOCATION
Descrivere un connettore
gcloud alpha scc artifact-guard connectors describe CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
Aggiorna l'associazione dei criteri del connettore
Per collegare un connettore a una policy, includi l'ID connettore nell'ambito della pipeline del file di definizione della policy e aggiorna la policy utilizzando il comando gcloud alpha scc artifact-guard policies update. Per saperne di più, consulta Creare una policy.
Elimina un connettore
Console
Per eliminare un connettore nella console Google Cloud :
- Nella console Google Cloud , vai a Sicurezza > Impostazioni.
- Nella scheda protezione artefatti, fai clic su Gestisci impostazioni.
- Nella tabella Connettori, fai clic su accanto al connettore e seleziona Elimina connettore.
- Segui le istruzioni di conferma per eliminare il connettore. Fai clic su Annulla per interrompere l'operazione.
gcloud CLI
Per eliminare un connettore utilizzando gcloud CLI, esegui questo comando:
gcloud alpha scc artifact-guard connectors delete CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
Esegui una valutazione
Le pipeline GitHub Actions e Jenkins supportano l'analisi delle vulnerabilità. Per eseguire una valutazione, devi:
- Crea secret per l'autenticazione.
- Crea un file modello di integrazione specifico per la tua pipeline.
- Avvia una valutazione.
Configurazione del secret
Le pipeline CI/CD in esecuzione al di fuori di Google Cloud possono autenticarsi utilizzando le chiavi account di servizio o la federazione delle identità per i workload. Per istruzioni dettagliate sulla creazione dei secret, consulta quanto segue:
Chiavi service account
Federazione delle identità per i workload (per GitHub Actions)
Devi aggiungere i secret al tuo ambiente CI/CD utilizzando uno dei seguenti metodi:
Metodo della chiave del service account
Un segreto:
GCP_CREDENTIALS: i contenuti del file della chiave JSON del account di servizio scaricato.
Metodo di federazione delle identità per i workload
Due segreti:
GCP_WORKLOAD_IDENTITY_PROVIDER: il nome completo della risorsa del provider di identità del workload. Ad esempio,projects/12345/locations/global/workloadIdentityPools/my-pool/providers/my-provider.GCP_SERVICE_ACCOUNT: l'indirizzo email del service account da rappresentare.
Modelli di integrazione delle pipeline
Per attivare una valutazione, devi creare un file specifico per la tua pipeline (Cloud Build, GitHub Actions o Jenkins) utilizzando i seguenti esempi di modelli:
Cloud Build
Per informazioni su ciascun campo, consulta Definizioni delle variabili.
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)
Questo modello è per GitHub Actions che utilizza una chiave segreta.
- Aggiungi la chiave segreta del account di servizio (
GCP_CREDENTIALS). Per informazioni su campi aggiuntivi, consulta Definizioni delle variabili.
# 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)
Questo modello è per GitHub Actions che utilizza la federazione delle identità per i workload.
- Aggiungi il tuo provider di identità del workload nel secret GitHub (
GCP_WORKLOAD_IDENTITY_PROVIDER). - Aggiungi il tuo account di servizio nel segreto GitHub (
GCP_SERVICE_ACCOUNT). Per informazioni su campi aggiuntivi, consulta Definizioni delle variabili.
# 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)
- Aggiungi la chiave segreta del account di servizio (
GCP_CREDENTIALS). Per informazioni su campi aggiuntivi, consulta Definizioni delle variabili.
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}" } } } }
Definizioni delle variabili
Questa sezione fornisce informazioni sui campi variabili utilizzati nei modelli di integrazione delle pipeline.
IMAGE_NAME_TO_SCAN (obbligatorio)
- Specifica il tag dell'immagine dell'applicazione da creare.
GCP_PROJECT_ID (obbligatorio)
- Specifica l' Google Cloud ID progetto utilizzato per l'autenticazione e la configurazione.
AR_REPOSITORY (facoltativo)
- Specifica il nome del repository Artifact Registry in cui la pipeline pubblica l'immagine se la build ha esito positivo.
ORGANIZATION_ID (obbligatorio)
- L'ID organizzazione Google Cloud .
CONNECTOR_ID (obbligatorio)
- Specifica l'ID connettore della pipeline da utilizzare.
SCANNER_IMAGE (obbligatorio)
L'immagine dello scanner predefinita analizza il codice, identifica le vulnerabilità valutando le immagini rispetto ai criteri durante la build e produce un risultato di conformità per determinare se la pipeline CI/CD viene superata o meno.
Dettagli dell'immagine:
us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest
VERBOSITY (facoltativo)
- Lo scanner supporta un flag
VERBOSITYfacoltativo che controlla il livello di dettaglio visualizzato nell'output della scansione. L'output dello scanner varia in base al livello di verbosità e al risultato di conformità (superata o non superata). Il flag di verbosità può essere impostato su
LOWoHIGH. Se non viene fornito, il valore predefinito èLOW.
Preferenze di lettura: basse (concise)
Conformità di ArtifactGuard: superata
- Specifica i nomi delle policy.
- Fornisce solo il conteggio riepilogativo delle CVE per gravità.
Conformità di ArtifactGuard: errore
- Specifica il motivo dell'errore.
- Elenca solo le CVE specifiche che hanno causato l'errore.
- Fornisce un conteggio riepilogativo delle CVE classificate per gravità.
Preferenze di lettura: elevate (dettagliate)
Fornisce un elenco completo di tutte le vulnerabilità rilevate.
Conformità di ArtifactGuard: superata
- Fornisce un elenco di tutte le CVE rilevate per la policy.
- Fornisce un conteggio riepilogativo delle CVE suddivise per gravità.
- Fornisce un elenco completo di tutte le vulnerabilità rilevate.
Conformità di ArtifactGuard: errore
- Include il motivo dell'errore.
- Elenca le CVE che causano l'errore.
- Fornisce un elenco di tutte le CVE rilevate per la policy.
- Fornisce un conteggio riepilogativo delle CVE suddivise per gravità.
- Fornisce un elenco completo di tutte le vulnerabilità rilevate.
IGNORE_SERVER_ERRORS (facoltativo)
- Un flag booleano facoltativo. Se
true, la pipeline continua nonostante gli errori del server. Il valore predefinito èfalse.
Avviare una valutazione
Durante il processo di compilazione, una strategia basata su Docker valuta l'immagine in base a policy predefinite. La logica di analisi delle vulnerabilità è contenuta nell'immagine
us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest.
Per avviare una scansione delle vulnerabilità nella pipeline CI/CD, esegui questo comando:
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=$?
L'integrazione CI/CD propaga i codici di uscita del container Docker all'ambiente di runtime Jenkins o GitHub Actions, che determina lo stato di superamento o errore della pipeline.
Risoluzione dei problemi
Questa sezione descrive gli errori comuni e come risolverli.
Errori CreateConnector
| Campo | Obbligatorio/Facoltativo | Vincoli |
|---|---|---|
name |
Obbligatorio | Formato:deve corrispondere all'espressione regolare
[a-zA-Z0-9\\-\\s_]+$ Corrispondere a uno o più dei seguenti elementi:
Lunghezza massima:64 caratteri. |
pipeline_type |
Obbligatorio | Deve essere uno dei seguenti valori enum:
|
description |
Facoltativo | Non deve superare i 256 caratteri. |
display_name |
Facoltativo | Non deve superare i 256 caratteri. |
Altri errori
La seguente tabella descrive alcuni errori comuni e come risolverli.
| Messaggio di errore | Causa | Azione/Risoluzione |
|---|---|---|
Autorizzazione artifactscanguard.connectors.create
negata per la risorsa |
L'utente o il account di servizio non dispone dell'autorizzazione IAM artifactscanguard.connectors.create
per la risorsa (progetto, cartella o
organizzazione). |
Concedi al chiamante un ruolo IAM che includa l'autorizzazione
artifactscanguard.connectors.create. |
status.ErrFailedPrecondition |
L'onboarding potrebbe essere in corso anche se la Google Cloud console mostra il servizio come abilitato. | Segnala un problema al team di assistenza. |
status.ErrInvalidArgument |
Errori di convalida dei campi | Assicurati che la richiesta CreateConnector soddisfi i vincoli specificati. |