Les clients Security Command Center peuvent avoir du mal à obtenir une vue centralisée et complète des résultats d'analyse de leurs environnements d'intégration continue/de déploiement continu (CI/CD). Cette absence de vue unifiée complique la gestion des failles. L'intégration CI/CD est un composant de artifact guard (aperçu) qui vous permet de connecter plusieurs pipelines CI/CD pour vous aider à détecter les failles tout au long du cycle de vie du développement logiciel.
L'intégration CI/CD est compatible avec GitHub Actions, Cloud Build et Jenkins. Une fois connectée, vous pouvez utiliser l'une de ces plates-formes CI/CD pour configurer des règles Artifact Guard, ce qui vous permet de bénéficier d'une visibilité et d'un contrôle proactifs sur votre stratégie de sécurité.
Présentation
L'intégration CI/CD offre les avantages suivants :
- Application des règles de bout en bout : aide Artifact Guard à appliquer des règles de sécurité cohérentes du code au cloud.
- Détection complète des menaces : analyse les failles, les secrets exposés, les licences problématiques et les packages malveillants.
- Compatibilité CI/CD étendue : fonctionne avec Jenkins et GitHub Actions.
- Optimisé pour CI/CD : un binaire léger assure un fonctionnement efficace dans les environnements locaux.
- Sortie flexible : fournit des résultats aux formats JSON et SARIF standards du secteur.
- Insights centralisés sur la sécurité : fournit des vues claires sur la conformité aux règles directement dans votre tableau de bord de sécurité.
Ce scanner remplit nativement Security Command Center, ce qui permet d'obtenir une vue unifiée et axée sur les composants des résultats de sécurité dès la création des artefacts.
L'intégration CI/CD vous aide à appliquer des règles Artifact Guard tout au long du cycle de vie du logiciel. Cela permet de s'assurer que les artefacts sont validés pour la conformité, de la compilation au déploiement.
Audience
L'intégration CI/CD peut aider les parties prenantes à effectuer les tâches suivantes :
- Utilisateurs principaux : équipes DevOps et d'ingénierie des plates-formes
- Gérer et intégrer : responsable de la gestion de l'outil d'analyse et de son intégration directe aux pipelines CI/CD.
- Configurer des règles : configurez les étapes d'analyse.
- Surveiller la conformité : suivez la conformité des compilations et collaborez avec les administrateurs de sécurité pour affiner les règles.
- Utilisateurs secondaires : administrateurs de la sécurité
- Auteurs de règles : définissez et appliquez des règles de sécurité en fonction de la criticité métier.
- Automatiser l'application : automatisez la sécurité dans CI/CD pour réduire le bruit des failles et définir des critères de gating.
- Superviser : collaborez avec l'équipe DevOps et proposez un tableau de bord à la direction pour qu'elle puisse suivre les failles bloquées.
- Utilisateurs secondaires : développeurs d'applications
- Examiner et corriger : interagissez avec les résultats de l'évaluation des règles, examinez les résultats de compilation et corrigez les problèmes de sécurité signalés.
- Évaluer : lancez l'évaluation des règles indirectement via le processus de compilation du pipeline CI.
- Assurez la conformité : respectez les exigences de sécurité sans perturber les workflows de développement.
Termes et concepts clés
- Common Vulnerabilities and Exposures (CVE) : faille de sécurité informatique divulguée publiquement et à laquelle est attribué un identifiant unique. Ces identifiants permettent de suivre les failles à corriger.
- Nomenclature logicielle (SBOM, software bill of materials) : inventaire lisible par machine des composants logiciels et des dépendances. Une SBOM inclut des informations sur la version, l'origine et d'autres détails pertinents de chaque composant. Les SBOM peuvent être utilisées pour identifier les CVE et d'autres risques de sécurité.
- Artefact : résultat validé et versionné du développement logiciel, tel que des données ou un élément créé lors du processus de compilation.
- Connecteur : tag pour les images. Lorsqu'il est transmis du pipeline CI au service Artifact Guard, un connecteur détermine les règles à exécuter sur l'image en cours de création.
- Règle CI : règle de sécurité définissant les règles ou les critères permettant de contrôler les failles et les packages autorisés dans votre environnement.
Workflow de haut niveau
- Créez des connecteurs CI.
- Créez des règles Artifact Guard à l'aide des connecteurs configurés à l'étape précédente pour définir le champ d'application des règles.
- Lancer des évaluations d'artefacts
Lors d'une évaluation, une image est créée et évaluée par rapport à des règles prédéfinies. Si les règles échouent, la compilation échoue. Les ingénieurs DevOps ou d'application doivent ensuite examiner les détails de l'échec pour trouver la faille spécifique, mettre à jour la dépendance en fonction des détails du CVE et réexécuter le pipeline.
Avant de commencer
Pour utiliser l'intégration CI/CD, vous devez activer Artifact Guard. Pour obtenir des instructions, consultez la section Avant de commencer de la documentation sur Artifact Guard.
Vous pouvez ensuite créer des connecteurs dans la consoleGoogle Cloud ou à l'aide de la Google Cloud CLI.
Créer un connecteur dans la console Google Cloud
Pour créer un connecteur, procédez comme suit :
Dans la console Google Cloud , accédez à Sécurité > Paramètres.
Sur la fiche Protection contre les artefacts, cliquez sur Gérer les paramètres.
Cliquez sur Créer un connecteur et saisissez les informations suivantes :
- ID du connecteur : ajoutez un ID pour le connecteur.
- Description : saisissez une description du connecteur.
- Plate-forme CI/CD : sélectionnez la plate-forme CI/CD correspondante dans la liste. Ce connecteur ne doit être utilisé que dans les pipelines créés avec la plate-forme CI/CD fournie.
Cliquez sur Créer.
Une notification confirme la création du connecteur. Les connecteurs disponibles sont listés dans le tableau "Connecteurs".
Pour supprimer un connecteur, cliquez sur à côté du connecteur, puis sélectionnez Supprimer le connecteur et suivez les instructions. Cliquez sur Annuler pour annuler.
Pour associer une règle à un connecteur, cliquez sur à côté du connecteur, puis sélectionnez Ajouter une règle. Suivez les étapes pour créer une règle Artifact Guard. Pour en savoir plus, consultez Créer une règle.
Créer un connecteur à l'aide de Google Cloud CLI
Cette section décrit les commandes gcloud CLI disponibles pour l'analyse des artefacts CI/CD et explique comment les utiliser.
Prérequis de Google Cloud CLI
- Assurez-vous que votre version de gcloud CLI est 559.0.0 ou ultérieure.
- Définissez votre projet comme projet de configuration.
Pour ce faire, exécutez les commandes gcloud CLI suivantes :
gcloud components update --version=559.0.0
gcloud config set project PROJECT_ID
Commandes Google Cloud CLI
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 : ID du connecteur à créer.
- PIPELINE_TYPE : type de pipeline CI/CD. Il doit s'agir de l'une des options suivantes :
GOOGLE_CLOUD_BUILDGITHUB_ACTIONSJENKINS_PIPELINE
- DESCRIPTION : description textuelle du connecteur.
- DISPLAY_NAME : nom à afficher convivial pour le connecteur.
get
gcloud alpha scc artifact-guard connectors describe CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
- CONNECTOR_ID : ID du connecteur à décrire.
list
gcloud alpha scc artifact-guard connectors list PARENT
- PARENT : une organisation ou un projet. Les formats acceptés pour la ressource parente sont les suivants :
{organizations/ORGANIZATION_ID/locations/LOCATION}{projects/PROJECT_NUMBER/locations/LOCATION}
supprimer
gcloud alpha scc artifact-guard connectors delete CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
- CONNECTOR_ID : ID du connecteur à supprimer.
Exécuter une évaluation
L'analyse des failles est compatible avec les actions GitHub et les pipelines Jenkins. Pour effectuer une évaluation, vous devez procéder comme suit :
- Créez des secrets pour l'authentification.
- Créez un fichier de modèle d'intégration spécifique à votre pipeline.
- Lancez une évaluation.
Configuration des secrets
Les pipelines CI/CD exécutés en dehors de Google Cloud peuvent s'authentifier à l'aide de clés de compte de service ou de la fédération d'identité de charge de travail. Pour obtenir des instructions détaillées sur la création de secrets, consultez les pages suivantes :
Clés de compte de service
Fédération d'identité de charge de travail (pour GitHub Actions)
Vous devez ajouter des secrets à votre environnement CI/CD à l'aide de l'une des méthodes suivantes :
Méthode de la clé de compte de service
Un secret :
GCP_CREDENTIALS: contenu du fichier de clé JSON de compte de service que vous avez téléchargé.
Méthode de fédération d'identité de charge de travail
Deux secrets :
GCP_WORKLOAD_IDENTITY_PROVIDER: nom complet de la ressource de votre fournisseur d'identité de charge de travail. Exemple :projects/12345/locations/global/workloadIdentityPools/my-pool/providers/my-providerGCP_SERVICE_ACCOUNT: adresse e-mail du compte de service dont l'identité doit être empruntée.
Modèles d'intégration de pipeline
Pour déclencher une évaluation, vous devez créer un fichier spécifique à votre pipeline (Cloud Build, GitHub Actions ou Jenkins) à l'aide des exemples de modèles suivants :
Cloud Build
Pour en savoir plus sur chaque champ, consultez Définitions des variables.
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)
Ce modèle est destiné aux actions GitHub utilisant une clé secrète.
- Ajoutez la clé secrète de votre compte de service (
GCP_CREDENTIALS). Pour en savoir plus sur les autres champs, consultez Définitions des variables.
# 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)
Ce modèle est destiné aux actions GitHub utilisant la fédération d'identité de charge de travail.
- Ajoutez votre fournisseur d'identité de charge de travail au secret GitHub (
GCP_WORKLOAD_IDENTITY_PROVIDER). - Ajoutez votre compte de service au secret GitHub (
GCP_SERVICE_ACCOUNT). Pour en savoir plus sur les autres champs, consultez Définitions des variables.
# 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)
- Ajoutez la clé secrète du compte de service (
GCP_CREDENTIALS). Pour en savoir plus sur les autres champs, consultez Définitions des variables.
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}" } } } }
Définitions des variables
Cette section fournit des informations sur les champs de variables utilisés dans les modèles d'intégration de pipeline.
IMAGE_NAME_TO_SCAN (obligatoire)
- Spécifie le tag de l'image d'application à créer.
GCP_PROJECT_ID (obligatoire)
- Spécifie l'ID du projet Google Cloud utilisé pour l'authentification et la configuration.
AR_REPOSITORY (facultatif)
- Indique le nom du dépôt Artifact Registry dans lequel l'image sera publiée si la compilation réussit.
ORGANIZATION_ID (obligatoire)
- ID de l'organisation Google Cloud .
CONNECTOR_ID (obligatoire)
- Spécifie l'ID de connecteur du pipeline à utiliser.
SCANNER_IMAGE (obligatoire)
L'image du scanner prédéfini analyse le code, identifie les failles en évaluant les images par rapport aux règles lors de la compilation et produit un résultat de conformité pour déterminer si le pipeline CI/CD réussit ou échoue.
Détails de l'image :
us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest
VERBOSITY (facultatif)
- Le scanner est compatible avec un indicateur
VERBOSITYfacultatif qui contrôle le niveau de détail affiché dans le résultat de l'analyse. La sortie du scanner varie en fonction du niveau de détail et du résultat de conformité (réussite ou échec). L'option de verbosité peut être définie sur
LOWouHIGH. Si aucune valeur n'est indiquée, cet attribut est défini par défaut surLOW.
Faible niveau de détail (concis)
ArtifactGuard Conformance : False
- Indique la raison de l'échec.
- Liste uniquement les CVE spécifiques qui ont causé l'échec.
- Fournit un récapitulatif du nombre de CVE classées par niveau de gravité.
Conformité ArtifactGuard : réussite
- Détaille les noms des règles.
- Fournit uniquement le nombre récapitulatif de CVE par niveau de gravité.
Verbosité élevée (détaillée)
Fournit une liste complète de toutes les failles détectées.
ArtifactGuard Conformance : False
- Indique la raison de l'échec.
- Liste les CVE à l'origine de l'échec.
- Fournit la liste de toutes les CVE détectées pour la règle.
- Fournit un récapitulatif du nombre de CVE par niveau de gravité.
- Fournit une liste complète de toutes les failles détectées.
Conformité ArtifactGuard : réussite
- Fournit la liste de toutes les CVE détectées pour la règle.
- Fournit un récapitulatif du nombre de CVE par niveau de gravité.
- Fournit une liste complète de toutes les failles détectées.
IGNORE_SERVER_ERRORS (facultatif)
- Option booléenne facultative. Si la valeur est
true, le pipeline se poursuit malgré les erreurs de serveur. La valeur par défaut estfalse.
Lancer une évaluation
Lors du processus de compilation, une stratégie basée sur Docker évalue l'image par rapport à des règles prédéfinies. La logique d'analyse des failles est contenue dans l'image us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest.
Pour lancer une analyse des failles dans votre pipeline CI/CD, exécutez la commande suivante :
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'intégration CI/CD propage les codes de sortie du conteneur Docker à l'environnement d'exécution Jenkins ou GitHub Actions, qui détermine ensuite l'état de réussite ou d'échec du pipeline.
Performances et limites
- Évaluation des artefacts : une image n'est évaluée que si elle répond aux critères suivants :
- La taille de l'objet URL (Uniform Resource Locator) du package ne peut pas dépasser 100 Mo.
- L'image ne doit pas contenir plus de 500 URL de page personnalisées.
- Jusqu'à 1 200 requêtes API par minute (20 RPS) par projet client pour toutes les méthodes du service Artifact Guard.
- SLO : L'évaluation des artefacts prend environ deux minutes.
Dépannage
Cette section décrit les erreurs courantes et explique comment les résoudre.
Échecs CreateConnector
| Champ | Obligatoire/Facultatif | Contraintes |
|---|---|---|
name |
Obligatoire | Format : doit correspondre à l'expression régulière
[a-zA-Z0-9\\-\\s_]+$ Correspond à un ou plusieurs des éléments suivants :
Longueur maximale : 64 caractères. |
pipeline_type |
Obligatoire | Doit correspondre à l'une des valeurs d'énumération suivantes :
|
description |
Facultatif | Ne doit pas dépasser 256 caractères. |
display_name |
Facultatif | Ne doit pas dépasser 256 caractères. |
Autres erreurs
Le tableau suivant présente certaines erreurs courantes et explique comment les résoudre.
| Message d'erreur | Cause | Action/Résolution |
|---|---|---|
Autorisation artifactscanguard.connectors.create
refusée pour la ressource |
L'utilisateur ou le compte de service ne dispose pas de l'autorisation IAM artifactscanguard.connectors.create sur la ressource (projet, dossier ou organisation). |
Attribuez à l'appelant un rôle IAM incluant l'autorisation artifactscanguard.connectors.create. |
status.ErrFailedPrecondition |
Il est possible que l'intégration soit en cours même si la console Google Cloud indique que le service est activé. | Signalez un problème à l'équipe d'assistance. |
status.ErrInvalidArgument |
Échecs de validation des champs | Assurez-vous que la requête CreateConnector respecte les contraintes spécifiées. |