A los clientes de Security Command Center les puede resultar difícil obtener una vista centralizada y completa de los resultados del análisis de sus entornos de integración continua y entrega continua (CI/CD). Esta falta de una vista unificada dificulta la gestión de vulnerabilidades. La integración de CI/CD es un componente de protección de artefactos (versión preliminar) que te permite conectar varias canalizaciones de CI/CD para ayudarte a detectar vulnerabilidades durante todo el ciclo de vida del desarrollo de software.
La integración de CI/CD admite GitHub Actions, Cloud Build y Jenkins. Una vez que se conecten, puedes usar cualquiera de estas plataformas de CI/CD para configurar políticas de protección de artefactos, lo que te brindará visibilidad y control proactivo sobre tu postura de seguridad.
Descripción general
La integración de CI/CD ofrece lo siguiente:
- Aplicación de políticas de extremo a extremo: Ayuda a protección de artefactos a aplicar políticas de seguridad coherentes desde el código hasta la nube.
- Detección integral de amenazas: Analiza en busca de vulnerabilidades, secretos expuestos, licencias problemáticas y paquetes maliciosos.
- Compatibilidad amplia con CI/CD: Funciona con Jenkins y GitHub Actions.
- Optimizado para CI/CD: Un objeto binario ligero garantiza un funcionamiento eficiente en entornos locales.
- Salida flexible: Proporciona resultados en formatos JSON y SARIF estándares de la industria.
- Estadísticas de seguridad centralizadas: Proporciona vistas claras del cumplimiento de las políticas directamente en tu panel de seguridad.
Este analizador completa de forma nativa Security Command Center, lo que proporciona una vista unificada y centrada en los recursos de los resultados de seguridad desde la creación de artefactos.
La integración de CI/CD te ayuda a aplicar políticas de protección de artefactos en todo el ciclo de vida del software. Esto garantiza que los artefactos se validen para verificar su conformidad desde la compilación hasta la implementación.
Público
La integración de CI/CD puede ayudar con las siguientes tareas de los interesados:
- Usuarios principales: Equipos de DevOps y de ingeniería de plataformas
- Administrar e integrar: Es responsable de administrar la herramienta de análisis y de integrarla directamente en las canalizaciones de CI/CD.
- Configura políticas: Establece los pasos de análisis.
- Supervisa el cumplimiento: Realiza un seguimiento del cumplimiento de la compilación y trabaja con los administradores de seguridad para definir mejor las políticas.
- Usuarios secundarios: Administradores de seguridad
- Autores de políticas: Definen y aplican políticas de seguridad según la importancia para el negocio.
- Automatiza la aplicación: Automatiza la seguridad dentro de la CI/CD para reducir el ruido de las vulnerabilidades y establecer criterios de bloqueo.
- Supervisión: Colabora con DevOps y ofrece un panel para que la administración haga un seguimiento de las vulnerabilidades controladas.
- Usuarios secundarios: Desarrolladores de aplicaciones
- Revisión y corrección: Interactúa con los resultados de la evaluación de políticas, revisa los resultados de la compilación y corrige los problemas de seguridad marcados.
- Evaluar: Inicia la evaluación de políticas de forma indirecta a través del proceso de compilación de la canalización de CI.
- Mantener el cumplimiento: Garantiza el cumplimiento de los requisitos de seguridad sin interrumpir los flujos de trabajo de desarrollo.
Términos y conceptos clave
- Vulnerabilidades y exposiciones comunes (CVE): Es una vulnerabilidad de seguridad informática divulgada públicamente a la que se le asigna un identificador único. Estos identificadores ayudan a hacer un seguimiento de las vulnerabilidades para su corrección.
- Lista de materiales de software (SBOM): Es un inventario legible por máquina de los componentes y las dependencias de software. Una SBOM incluye información sobre la versión, el origen y otros detalles relevantes de cada componente. Las SBOM se pueden usar para identificar CVE y otros riesgos de seguridad.
- Artefacto: Es un resultado validado y con versiones del desarrollo de software, como datos o un elemento creado durante el proceso de compilación.
- Conector: Es una etiqueta para imágenes. Cuando se pasa de la canalización de CI al servicio de protección de artefactos, un conector determina qué políticas se deben ejecutar en la imagen que se está compilando.
- Política de CI: Es una política de vulnerabilidades que define reglas o criterios para controlar qué vulnerabilidades y paquetes se permiten en tu entorno.
Flujo de trabajo de alto nivel
- Crea conectores de CI.
- Crea políticas de protección de artefactos con los conectores configurados en el paso anterior para definir el alcance de la política.
- Inicia evaluaciones de artefactos.
Durante una evaluación, se compila una imagen y se evalúa en función de políticas predefinidas. Si fallan las políticas, falla la compilación. Luego, los ingenieros de DevOps o de aplicaciones deben examinar los detalles del error para encontrar la vulnerabilidad específica, actualizar la dependencia según los detalles del CVE y volver a ejecutar la canalización.
Antes de comenzar
Para usar la integración de CI/CD, debes habilitar la protección de artefactos. Para obtener instrucciones, consulta Antes de comenzar en la documentación de protección de artefactos.
Luego, puedes crear conectores en la Google Cloud consola o con Google Cloud CLI.
Crea un conector en la consola de Google Cloud
Para crear un conector, sigue estos pasos:
En la consola de Google Cloud , ve a Seguridad > Configuración.
En la tarjeta protección de artefactos, haz clic en Administrar configuración.
Haz clic en Crear conector y escribe los siguientes detalles para el conector:
- ID del conector: Agrega un ID para el conector.
- Descripción: Ingresa una descripción del conector.
- Plataforma de CI/CD: Selecciona la plataforma de CI/CD correspondiente de la lista. Este conector solo se debe usar en las canalizaciones creadas con la plataforma de CI/CD proporcionada.
Haz clic en Crear.
Una notificación confirma que se creó el conector correctamente. Los conectores disponibles se enumeran en la tabla Conectores.
Para quitar un conector, haz clic en junto a él y selecciona Borrar conector. Luego, sigue las indicaciones. Haz clic en Cancelar para anular.
Para vincular una política a un conector, haz clic en junto al conector y selecciona Agregar política. Continúa con los pasos para crear una política de protección de artefactos. Para obtener más información, consulta Crea una política.
Crea un conector con Google Cloud CLI
En esta sección, se describen los comandos de la gcloud CLI disponibles para el análisis de artefactos de CI/CD y cómo usarlos.
Requisitos previos de Google Cloud CLI
- Asegúrate de que tu versión de gcloud CLI sea 559.0.0 o posterior.
- Configura tu proyecto como el proyecto de configuración.
Para ello, ejecuta los siguientes comandos de gcloud CLI:
gcloud components update --version=559.0.0
gcloud config set project PROJECT_ID
Comandos de 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: Es el ID del conector que se creará.
- PIPELINE_TYPE: Es el tipo de canalización de CI/CD. Debe ser uno de los siguientes:
GOOGLE_CLOUD_BUILDGITHUB_ACTIONSJENKINS_PIPELINE
- DESCRIPTION: Es una descripción de texto para el conector.
- DISPLAY_NAME: Es un nombre visible descriptivo para el conector.
get
gcloud alpha scc artifact-guard connectors describe CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
- CONNECTOR_ID: ID del conector que se describirá.
list
gcloud alpha scc artifact-guard connectors list PARENT
- PARENT: Es una organización o un proyecto. Los formatos aceptables para el recurso principal incluyen los siguientes:
{organizations/ORGANIZATION_ID/locations/LOCATION}{projects/PROJECT_NUMBER/locations/LOCATION}
borrar
gcloud alpha scc artifact-guard connectors delete CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
- CONNECTOR_ID: Es el ID del conector que se borrará.
Ejecutar una evaluación
El análisis de vulnerabilidades es compatible con las canalizaciones de GitHub Actions y Jenkins. Para realizar una evaluación, debes hacer lo siguiente:
- Crea secretos para la autenticación.
- Crea un archivo de plantilla de integración específico para tu canalización.
- Inicia una evaluación.
Configuración de Secret
Las canalizaciones de CI/CD que se ejecutan fuera de Google Cloud pueden autenticarse con claves de cuentas de servicio o con la federación de identidades para cargas de trabajo. Para obtener instrucciones detalladas sobre cómo crear secretos, consulta lo siguiente:
Claves de cuenta de servicio
Federación de identidades para cargas de trabajo (para acciones de GitHub)
Debes agregar secretos a tu entorno de CI/CD con uno de los siguientes métodos:
Método de clave de cuenta de servicio
Un secreto:
GCP_CREDENTIALS: El contenido del archivo de clave JSON de la cuenta de servicio que descargaste.
Método de federación de identidades para cargas de trabajo
Dos secretos:
GCP_WORKLOAD_IDENTITY_PROVIDER: Es el nombre completo del recurso de tu proveedor de identidades para cargas de trabajo. Por ejemplo,projects/12345/locations/global/workloadIdentityPools/my-pool/providers/my-providerGCP_SERVICE_ACCOUNT: Es la dirección de correo electrónico de la cuenta de servicio que se representará.
Plantillas de integración de canalizaciones
Para activar una evaluación, debes crear un archivo específico para tu canalización (Cloud Build, GitHub Actions o Jenkins) con los siguientes ejemplos de plantillas:
Cloud Build
Consulta Definiciones de variables para obtener información sobre cada campo.
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
Acciones de GitHub (secreto)
Esta plantilla es para las acciones de GitHub que usan una clave secreta.
- Agrega la clave secreta de tu cuenta de servicio (
GCP_CREDENTIALS). Consulta Definiciones de variables para obtener información sobre los campos adicionales.
# 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}"
Acciones de GitHub (WIF)
Esta plantilla es para las acciones de GitHub que usan la federación de identidades para cargas de trabajo.
- Agrega tu proveedor de identidades para cargas de trabajo en el secreto de GitHub (
GCP_WORKLOAD_IDENTITY_PROVIDER). - Agrega tu cuenta de servicio en el secreto de GitHub (
GCP_SERVICE_ACCOUNT). Consulta Definiciones de variables para obtener información sobre los campos adicionales.
# 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 (secreto)
- Agrega la clave secreta de la cuenta de servicio (
GCP_CREDENTIALS). Consulta Definiciones de variables para obtener información sobre los campos adicionales.
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}" } } } }
Definiciones de variables
En esta sección, se proporciona información sobre los campos de variables que se usan en las plantillas de integración de canalizaciones.
IMAGE_NAME_TO_SCAN (obligatorio)
- Especifica la etiqueta de la imagen de la aplicación que se compilará.
GCP_PROJECT_ID (obligatorio)
- Especifica el Google Cloud ID del proyecto que se usa para la autenticación y la configuración.
AR_REPOSITORY (opcional)
- Especifica el nombre del repositorio de Artifact Registry en el que se publicará la imagen si la compilación se realiza correctamente.
ORGANIZATION_ID (obligatorio)
- ID de la organización Google Cloud .
CONNECTOR_ID (obligatorio)
- Especifica el ID del conector de la canalización que se usará.
SCANNER_IMAGE (obligatorio)
La imagen del analizador prediseñado analiza el código, identifica vulnerabilidades evaluando las imágenes en función de las políticas durante la compilación y genera un resultado de cumplimiento para determinar si la canalización de CI/CD pasa o falla.
Detalles de la imagen:
us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest
VERBOSITY (opcional)
- El analizador admite una marca
VERBOSITYopcional que controla el nivel de detalle que se muestra en el resultado del análisis. El resultado del análisis varía según el nivel de detalle y el resultado de cumplimiento (aprobado o no aprobado). La marca de verbosidad se puede establecer en
LOWoHIGH. Si no se proporciona, el valor predeterminado esLOW.
Poca verbosidad (conciso)
ArtifactGuard Conformance : False
- Detalla el motivo del error.
- Enumera solo los CVE específicos que causaron la falla.
- Proporciona un recuento resumido de los CVE categorizados por gravedad.
ArtifactGuard Conformance : Pass
- Detalla los nombres de las políticas.
- Proporciona solo el recuento resumido de CVE por gravedad.
Alta verbosidad (detallada)
Proporciona una lista completa de todas las vulnerabilidades encontradas.
ArtifactGuard Conformance : False
- Incluye el motivo del error.
- Enumera los CVE que causan la falla.
- Proporciona una lista de todos los CVE detectados para la política.
- Proporciona un recuento resumido de los CVE desglosados por gravedad.
- Proporciona una lista completa de todas las vulnerabilidades detectadas.
ArtifactGuard Conformance : Pass
- Proporciona una lista de todos los CVE detectados para la política.
- Proporciona un recuento resumido de los CVE desglosados por gravedad.
- Proporciona una lista completa de todas las vulnerabilidades detectadas.
IGNORE_SERVER_ERRORS (opcional)
- Es una marca booleana opcional. Si es
true, la canalización continúa a pesar de los errores del servidor. La configuración predeterminada esfalse.
Cómo iniciar una evaluación
Durante el proceso de compilación, una estrategia basada en Docker evalúa la imagen según políticas predefinidas. La lógica del análisis de vulnerabilidades se encuentra dentro de la imagen us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest.
Para iniciar un análisis de vulnerabilidades en tu canalización de CI/CD, ejecuta el siguiente 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=$?
La integración de CI/CD propaga los códigos de salida del contenedor de Docker al tiempo de ejecución de Jenkins o GitHub Actions, que luego determina el estado de aprobación o falla de la canalización.
Rendimiento y limitaciones
- Evaluación de artefactos: Una imagen se evalúa solo si cumple con los siguientes criterios:
- El tamaño del objeto del localizador uniforme de recursos (URL) del paquete no puede superar los 100 MB.
- La imagen debe contener 500 o menos pURLs.
- Hasta 1,200 solicitudes a la API por minuto (20 QPS) por proyecto del consumidor para todos los métodos dentro del servicio de protección de artefactos.
- SLO: La evaluación de artefactos tarda unos dos minutos.
Soluciona problemas
En esta sección, se describen los errores comunes y cómo resolverlos.
Fallas de CreateConnector
| Campo | Obligatorio/Opcional | Limitaciones |
|---|---|---|
name |
Obligatorio | Formato: Debe coincidir con la expresión regular [a-zA-Z0-9\\-\\s_]+$. Debe coincidir con uno o más de los siguientes elementos:
Longitud máxima: 64 caracteres. |
pipeline_type |
Obligatorio | Debe ser uno de los siguientes valores de enumeración:
|
description |
Opcional | No debe superar los 256 caracteres. |
display_name |
Opcional | No debe superar los 256 caracteres. |
Otros errores
En la siguiente tabla, se describen algunos errores comunes y cómo resolverlos.
| Mensaje de error | Causa | Acción/Resolución |
|---|---|---|
Permiso artifactscanguard.connectors.create
denegado en el recurso |
El usuario o la cuenta de servicio no tienen el permiso de IAM artifactscanguard.connectors.create en el recurso (proyecto, carpeta u organización). |
Otorga al llamador un rol de IAM que incluya el permiso
artifactscanguard.connectors.create. |
status.ErrFailedPrecondition |
Es posible que la incorporación esté en curso incluso si la consola Google Cloud muestra que el servicio está habilitado. | Informa un problema al equipo de asistencia al cliente. |
status.ErrInvalidArgument |
Errores de validación de campos | Asegúrate de que la solicitud CreateConnector cumpla con las restricciones especificadas. |