Pelanggan Security Command Center mungkin kesulitan mendapatkan tampilan terpusat dan komprehensif dari hasil pemindaian dari lingkungan Continuous Integration/Continuous Delivery (CI/CD) mereka. Kurangnya tampilan terpadu ini mempersulit pengelolaan kerentanan. Integrasi CI/CD adalah komponen artifact guard (Pratinjau) yang memungkinkan Anda menghubungkan beberapa pipeline CI/CD untuk membantu Anda mendeteksi kerentanan di sepanjang siklus proses pengembangan software.
Integrasi CI/CD mendukung GitHub Actions, Cloud Build, dan Jenkins. Setelah terhubung, Anda dapat menggunakan salah satu platform CI/CD ini untuk mengonfigurasi kebijakan perlindungan artefak, yang memberikan visibilitas dan kontrol proaktif atas postur keamanan Anda.
Ringkasan
Integrasi CI/CD menawarkan hal berikut:
- Penegakan kebijakan end-to-end: Membantu penjaga artefak dalam menerapkan kebijakan keamanan yang konsisten dari kode ke cloud.
- Deteksi ancaman yang komprehensif: Memindai kerentanan, kredensial yang terekspos, lisensi yang bermasalah, dan paket berbahaya.
- Kompatibilitas CI/CD yang luas: Kompatibel dengan Jenkins dan GitHub Actions.
- Dioptimalkan untuk CI/CD: Biner ringan memastikan operasi yang efisien di lingkungan lokal.
- Output fleksibel: Memberikan hasil dalam format JSON dan SARIF standar industri.
- Insight keamanan terpusat: Memberikan tampilan kepatuhan kebijakan yang jelas langsung di dasbor keamanan Anda.
Pemindai ini secara native mengisi Security Command Center, sehingga memberikan tampilan terpadu dan berfokus pada aset terkait temuan keamanan dari pembuatan artefak.
Integrasi CI/CD membantu Anda menerapkan kebijakan perlindungan artefak di seluruh siklus proses software. Hal ini memastikan bahwa artefak divalidasi untuk kesesuaian dari build hingga deployment.
Audiens
Integrasi CI/CD dapat membantu tugas pemangku kepentingan berikut:
- Pengguna utama: Tim DevOps dan platform engineering
- Mengelola dan mengintegrasikan: Bertanggung jawab untuk mengelola alat pemindaian dan mengintegrasikannya langsung ke dalam pipeline CI/CD.
- Konfigurasi kebijakan: Siapkan langkah-langkah pemindaian.
- Memantau kepatuhan: Lacak kepatuhan build dan bekerja sama dengan administrator keamanan untuk menyempurnakan kebijakan.
- Pengguna sekunder: Administrator keamanan
- Pembuat kebijakan: Menentukan dan menerapkan kebijakan keamanan berdasarkan tingkat kekritisan bisnis.
- Mengotomatiskan penegakan: Mengotomatiskan keamanan dalam CI/CD untuk mengurangi gangguan kerentanan dan menetapkan kriteria gating.
- Memberikan pengawasan: Berkolaborasi dengan DevOps dan menawarkan dasbor bagi manajemen untuk melacak kerentanan yang dibatasi.
- Pengguna sekunder: Developer aplikasi
- Tinjau dan perbaiki: Berinteraksi dengan hasil evaluasi kebijakan, meninjau hasil build, dan memperbaiki masalah keamanan yang ditandai.
- Mengevaluasi: Memulai penilaian kebijakan secara tidak langsung melalui proses build pipeline CI.
- Menjaga kepatuhan: Pastikan kepatuhan terhadap persyaratan keamanan tanpa mengganggu alur kerja pengembangan.
Istilah dan konsep utama
- Kerentanan dan Eksposur Umum (CVE): Kerentanan keamanan komputer yang diungkapkan secara publik dan diberi ID unik. ID ini membantu melacak kerentanan untuk perbaikan.
- Software Bill of Materials (SBOM): Inventaris komponen dan dependensi software yang dapat dibaca mesin. SBOM mencakup informasi tentang versi, asal, dan detail relevan lainnya dari setiap komponen. SBOM dapat digunakan untuk mengidentifikasi CVE dan risiko keamanan lainnya.
- Artefak: Output pengembangan software yang diberi versi dan divalidasi, seperti data atau item yang dibuat selama proses build.
- Konektor: Tag untuk gambar. Saat diteruskan dari pipeline CI ke layanan penjaga artefak, konektor akan menentukan kebijakan mana yang akan dijalankan terhadap image yang sedang dibuat.
- Kebijakan CI: Kebijakan kerentanan yang menentukan aturan atau kriteria untuk mengontrol kerentanan dan paket yang diizinkan di lingkungan Anda.
Alur kerja tingkat tinggi
- Buat konektor CI.
- Buat kebijakan perlindungan artefak menggunakan konektor yang dikonfigurasi pada langkah sebelumnya untuk menentukan cakupan kebijakan.
- Mulai evaluasi artefak.
Selama evaluasi, image dibuat dan dievaluasi berdasarkan kebijakan yang telah ditentukan sebelumnya. Jika kebijakan gagal, build akan gagal. Kemudian, DevOps atau engineer aplikasi harus memeriksa detail kegagalan untuk menemukan kerentanan tertentu, memperbarui dependensi sesuai dengan detail CVE, dan menjalankan ulang pipeline.
Sebelum memulai
Untuk menggunakan integrasi CI/CD, Anda harus mengaktifkan perlindungan artefak. Untuk mengetahui petunjuknya, lihat Sebelum memulai dalam dokumentasi perlindungan artefak.
Kemudian, Anda dapat membuat konektor di konsolGoogle Cloud atau menggunakan Google Cloud CLI.
Membuat konektor di konsol Google Cloud
Untuk membuat konektor, ikuti langkah-langkah berikut:
Di konsol Google Cloud , buka Security > Settings.
Di kartu Artifact guard, klik Kelola setelan.
Klik Buat konektor dan masukkan detail berikut untuk konektor:
- ID Konektor: Tambahkan ID untuk konektor.
- Deskripsi: Masukkan deskripsi konektor.
- Platform CI/CD: Pilih platform CI/CD yang sesuai dari daftar. Konektor ini hanya boleh digunakan di pipeline yang dibuat dengan platform CI/CD yang disediakan.
Klik Create.
Notifikasi akan mengonfirmasi keberhasilan pembuatan konektor. Konektor yang tersedia tercantum dalam tabel Konektor.
Untuk menghapus konektor, klik di samping konektor, pilih Hapus konektor, lalu ikuti petunjuknya. Klik Batalkan untuk membatalkan.
Untuk menautkan kebijakan ke konektor, klik di samping konektor, lalu pilih Tambahkan kebijakan. Lanjutkan dengan langkah-langkah untuk membuat kebijakan perlindungan artefak. Untuk mengetahui informasi selengkapnya, lihat Membuat kebijakan.
Membuat konektor menggunakan Google Cloud CLI
Bagian ini menguraikan perintah gcloud CLI yang tersedia untuk Pemindaian Artefak CI/CD dan cara menggunakannya.
Prasyarat Google Cloud CLI
- Pastikan gcloud CLI Anda versi 559.0.0 atau yang lebih baru.
- Tetapkan project Anda sebagai project konfigurasi.
Untuk melakukannya, jalankan perintah gcloud CLI berikut:
gcloud components update --version=559.0.0
gcloud config set project PROJECT_ID
Perintah Google Cloud CLI
buat
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 konektor yang akan dibuat.
- PIPELINE_TYPE: Jenis pipeline CI/CD. Harus berupa salah satu dari
berikut:
GOOGLE_CLOUD_BUILDGITHUB_ACTIONSJENKINS_PIPELINE
- DESCRIPTION: Deskripsi teks untuk konektor.
- DISPLAY_NAME: Nama tampilan yang mudah digunakan untuk konektor.
get
gcloud alpha scc artifact-guard connectors describe CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
- CONNECTOR_ID: ID konektor yang akan dideskripsikan.
list
gcloud alpha scc artifact-guard connectors list PARENT
- PARENT: Organisasi atau project. Format
yang dapat diterima untuk resource induk meliputi:
{organizations/ORGANIZATION_ID/locations/LOCATION}{projects/PROJECT_NUMBER/locations/LOCATION}
delete
gcloud alpha scc artifact-guard connectors delete CONNECTOR_ID \ --location=LOCATION \ (--organization=ORGANIZATION_ID | --project=PROJECT_NUMBER)
- CONNECTOR_ID: ID konektor yang akan dihapus.
Jalankan evaluasi
Pemindaian kerentanan didukung untuk pipeline GitHub Actions dan Jenkins. Untuk melakukan evaluasi, Anda harus melakukan hal berikut:
- Buat secret untuk autentikasi.
- Buat file template integrasi khusus untuk pipeline Anda.
- Mulai evaluasi.
Konfigurasi rahasia
Pipeline CI/CD yang berjalan di luar Google Cloud dapat melakukan autentikasi menggunakan kunci akun layanan atau Workload Identity Federation. Untuk mengetahui petunjuk mendetail tentang cara membuat secret, lihat artikel berikut:
Kunci akun layanan
Workload Identity Federation (untuk GitHub Actions)
Anda harus menambahkan secret ke lingkungan CI/CD menggunakan salah satu metode berikut:
Metode kunci akun layanan
Satu rahasia:
GCP_CREDENTIALS: Isi file kunci JSON akun layanan yang Anda download.
Metode Workload Identity Federation
Dua rahasia:
GCP_WORKLOAD_IDENTITY_PROVIDER: Nama lengkap resource Penyedia Workload Identity Anda. Contoh,projects/12345/locations/global/workloadIdentityPools/my-pool/providers/my-provider.GCP_SERVICE_ACCOUNT: Alamat email akun layanan yang akan di-impersonate.
Template integrasi pipeline
Untuk memicu evaluasi, Anda harus membuat file khusus untuk pipeline (Cloud Build, GitHub Actions, atau Jenkins) menggunakan contoh template berikut:
Cloud Build
Lihat Definisi variabel untuk mengetahui informasi tentang setiap kolom.
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)
Template ini ditujukan untuk GitHub Actions yang menggunakan kunci rahasia.
- Tambahkan kunci rahasia akun layanan Anda (
GCP_CREDENTIALS). Lihat Definisi variabel untuk mengetahui informasi tentang kolom tambahan.
# 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)
Template ini ditujukan untuk GitHub Actions yang menggunakan Workload Identity Federation.
- Tambahkan Penyedia Identitas Workload Anda di secret GitHub (
GCP_WORKLOAD_IDENTITY_PROVIDER). - Tambahkan Akun Layanan Anda di secret GitHub (
GCP_SERVICE_ACCOUNT). Lihat Definisi variabel untuk mengetahui informasi tentang kolom tambahan.
# 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 (rahasia)
- Tambahkan kunci rahasia akun layanan (
GCP_CREDENTIALS). Lihat Definisi variabel untuk mengetahui informasi tentang kolom tambahan.
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}" } } } }
Definisi variabel
Bagian ini memberikan informasi tentang kolom variabel yang digunakan dalam Template integrasi pipeline.
IMAGE_NAME_TO_SCAN (Wajib)
- Menentukan tag image aplikasi yang akan dibuat.
GCP_PROJECT_ID (Wajib)
- Menentukan Google Cloud Project ID yang digunakan untuk autentikasi dan konfigurasi.
AR_REPOSITORY (Opsional)
- Menentukan nama repositori Artifact Registry tempat image akan dipublikasikan jika build berhasil.
ORGANIZATION_ID (Wajib)
- ID organisasi Google Cloud .
CONNECTOR_ID (Wajib)
- Menentukan ID konektor pipeline yang akan digunakan.
SCANNER_IMAGE (Wajib)
Image pemindai bawaan menganalisis kode, mengidentifikasi kerentanan dengan mengevaluasi image berdasarkan kebijakan selama build, dan menghasilkan hasil kepatuhan untuk menentukan apakah pipeline CI/CD lulus atau gagal.
Detail gambar:
us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest
VERBOSITY (Opsional)
- Pemindai mendukung tanda
VERBOSITYopsional yang mengontrol tingkat detail yang ditampilkan dalam output pemindaian. Output pemindai bervariasi berdasarkan tingkat kejelasan dan hasil kepatuhan (Lulus atau Gagal). Flag kejelasan dapat disetel ke
LOWatauHIGH. Nilai defaultnya adalahLOWjika tidak diberikan.
Verbositas rendah (ringkas)
Kesesuaian ArtifactGuard : Salah
- Menjelaskan alasan kegagalan.
- Hanya mencantumkan CVE spesifik yang menyebabkan kegagalan.
- Memberikan jumlah CVE yang diringkas dan dikategorikan berdasarkan tingkat keparahan.
Kesesuaian ArtifactGuard : Lulus
- Mencantumkan nama kebijakan.
- Hanya memberikan jumlah CVE yang diringkas menurut tingkat keparahan.
Panjang informasi tinggi (mendetail)
Memberikan daftar lengkap semua kerentanan yang ditemukan.
Kesesuaian ArtifactGuard : Salah
- Mencakup alasan kegagalan.
- Mencantumkan CVE yang menyebabkan kegagalan.
- Memberikan daftar semua CVE yang terdeteksi untuk kebijakan.
- Menyediakan jumlah ringkasan CVE yang dikelompokkan berdasarkan tingkat keparahan.
- Memberikan daftar lengkap semua kerentanan yang terdeteksi.
Kesesuaian ArtifactGuard : Lulus
- Memberikan daftar semua CVE yang terdeteksi untuk kebijakan.
- Menyediakan jumlah ringkasan CVE yang dikelompokkan berdasarkan tingkat keparahan.
- Memberikan daftar lengkap semua kerentanan yang terdeteksi.
IGNORE_SERVER_ERRORS (Opsional)
- Flag boolean opsional. Jika
true, pipeline akan berlanjut meskipun terjadi error server. Nilai defaultnya adalahfalse.
Mulai evaluasi
Selama proses build, strategi berbasis Docker mengevaluasi image berdasarkan kebijakan yang telah ditentukan sebelumnya. Logika pemindaian kerentanan terdapat dalam
us-central1-docker.pkg.dev/ci-plugin/ci-images/scc-artifactguard-scan-image:latest
image.
Untuk memulai pemindaian kerentanan di pipeline CI/CD, jalankan perintah berikut:
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=$?
Integrasi CI/CD menyebarkan kode keluar container Docker ke runtime Jenkins atau GitHub Actions, yang kemudian menentukan status lulus atau gagal pipeline.
Performa dan batasan
- Evaluasi artefak: Gambar hanya dievaluasi jika memenuhi kriteria berikut:
- Ukuran objek Package Uniform Resource Locator (pURL) tidak boleh melebihi 100 MB.
- Gambar harus berisi 500 pURL atau kurang.
- Hingga 1.200 permintaan API per menit (20 QPS) per project konsumen untuk semua metode dalam layanan penjaga artefak.
- SLO: Evaluasi artefak memerlukan waktu sekitar dua menit.
Pemecahan masalah
Bagian ini menguraikan error umum beserta cara menyelesaikannya.
Kegagalan CreateConnector
| Kolom | Wajib/Opsional | Batasan |
|---|---|---|
name |
Wajib | Format: Harus cocok dengan ekspresi reguler
[a-zA-Z0-9\\-\\s_]+$ Cocokkan satu atau beberapa hal berikut:
Panjang Maksimum: 64 karakter. |
pipeline_type |
Wajib | Harus berupa salah satu nilai enum berikut:
|
description |
Opsional | Tidak boleh melebihi 256 karakter. |
display_name |
Opsional | Tidak boleh melebihi 256 karakter. |
Error lainnya
Tabel berikut menguraikan beberapa error umum dan cara menyelesaikannya.
| Pesan Error | Penyebab | Tindakan/Penyelesaian |
|---|---|---|
Izin artifactscanguard.connectors.create
ditolak pada resource |
Pengguna atau akun layanan tidak memiliki izin IAM artifactscanguard.connectors.create
pada resource (project, folder, atau
organisasi). |
Berikan peran IAM yang menyertakan izin artifactscanguard.connectors.create kepada pemanggil. |
status.ErrFailedPrecondition |
Proses aktivasi mungkin sedang berlangsung meskipun Google Cloud konsol menampilkan layanan sebagai diaktifkan. | Laporkan masalah kepada tim dukungan. |
status.ErrInvalidArgument |
Kegagalan validasi kolom | Pastikan permintaan CreateConnector memenuhi batasan yang ditentukan. |