CodeMender può analizzare ogni richiesta di pull nella pipeline di integrazione continua e
distribuzione continua (CI/CD). Il controllo non riesce quando CodeMender trova una
vulnerabilità con gravità CRITICAL o HIGH nel codice modificato dalla
richiesta pull. I risultati nel codice che la richiesta di pull non ha modificato vengono visualizzati nel report, ma non superano il controllo.
Questo documento mostra come:
- Esegui la scansione delle richieste di pull con GitHub Actions e chiedi a CodeMender di aprire una richiesta di pull con le correzioni.
- Scansiona le richieste di pull con Cloud Build.
- Esegui la scansione delle modifiche prima di ogni commit con un hook pre-commit di Git.
Come funzionano le scansioni delle richieste di pull
Per analizzare una richiesta di pull, esegui cm find con il flag --diff e il ramo di base della richiesta di pull:
cm find . --diff=origin/main
In risposta a questo comando, CodeMender esegue le seguenti operazioni:
- Confronta il ramo della richiesta di pull con il ramo di base ed esegue la scansione dei file di origine modificati e dei file che dipendono direttamente da questi, ad esempio chiamanti e importatori.
- Distingue le nuove vulnerabilità introdotte o esposte dalla richiesta di pull dai risultati preesistenti, etichettati con
[LEGACY / UNTOUCHED]. Il controllo dell'integrazione continua blocca solo le vulnerabilità causate dalla richiesta di pull. - Esce con stato 1 quando un risultato causato dalla richiesta di pull corrisponde a una
gravità in
--fail-on. Il valore predefinito èCRITICAL,HIGH.
Per ulteriori informazioni sul confronto tra --diff e altre modalità di scansione, vedi
Modalità di ricerca
di CodeMender.
Prima di iniziare
CodeMender è disponibile per un numero limitato di clienti in Anteprima pubblica. Contatta il team di vendita per ottenere l'accesso.
- Accedi al tuo account Google Cloud . Se non conosci Google Cloud, crea un account per valutare le prestazioni dei nostri prodotti in scenari reali. I nuovi clienti ricevono anche 300 $di crediti senza costi per l'esecuzione, il test e il deployment dei carichi di lavoro.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
If you're using an existing project for this guide, verify that you have the permissions required to complete this guide. If you created a new project, then you already have the required permissions.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Agent Platform API and Cloud Resource Manager API APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
If you're using an existing project for this guide, verify that you have the permissions required to complete this guide. If you created a new project, then you already have the required permissions.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Agent Platform API and Cloud Resource Manager API APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init
Assicurati che la release della CLI CodeMender supporti le scansioni delle richieste di pull. Le
pipeline in questo documento scaricano l'ultima release stabile ogni volta che
vengono eseguite. Per controllare un'installazione locale, esegui cm find --help e cerca il
flag --diff. Per aggiornare la CLI, esegui cm update. Per saperne di più, consulta
Installare e configurare la
CLI.
Ruoli obbligatori
Per ottenere le autorizzazioni necessarie per configurare le integrazioni CI/CD per CodeMender, chiedi all'amministratore di concederti i seguenti ruoli IAM sul progetto:
- Amministratore service account (
roles/iam.serviceAccountAdmin) - Project IAM Admin (
roles/resourcemanager.projectIamAdmin) -
Configura la federazione delle identità per i workload per GitHub Actions:
Amministratore del pool di identità dei workload (
roles/iam.workloadIdentityPoolAdmin) -
Crea trigger di Cloud Build:
- Editor Cloud Build (
roles/cloudbuild.builds.editor) - Utente Service Account (
roles/iam.serviceAccountUser)
- Editor Cloud Build (
-
Esegui l'hook di pre-commit di Git in locale:
Agent Platform User (
roles/aiplatform.user)
Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.
Potresti anche riuscire a ottenere le autorizzazioni richieste tramite i ruoli personalizzati o altri ruoli predefiniti.
Per assicurarti che il account di servizio CI/CD disponga delle autorizzazioni necessarie per eseguire CodeMender in una pipeline CI/CD, chiedi all'amministratore di concedere i seguenti ruoli IAMaccount di servizioount CI/CD:
- Agent Platform User (
roles/aiplatform.user) sul tuo progetto -
Scrivi i log di build di Cloud Build:
Logs Writer (
roles/logging.logWriter) sul tuo progetto -
Salva i report SARIF in un bucket Cloud Storage:
Storage Object User (
roles/storage.objectUser) sul bucket
Per saperne di più sulla concessione dei ruoli, consulta Gestisci l'accesso a progetti, cartelle e organizzazioni.
L'amministratore potrebbe anche essere in grado di concedere al account di servizio CI/CD le autorizzazioni richieste tramite ruoli personalizzati o altri ruoli predefiniti.
Considerazioni sulla sicurezza
Quando esegui CodeMender in un flusso di lavoro GitHub Actions, in un trigger di build di Cloud Build o in un hook pre-commit Git, CodeMender viene eseguito senza chiedere conferma. Prima di configurare queste integrazioni, tieni presente quanto segue:
- Prompt di conferma: il flag
--yesdisattiva i prompt che ti chiedono di confermare i comandi dell'agente e le scritture dei file. Il flag--bypass-warningignora l'avviso che l'agente può modificare i file ed eseguire comandi sul tuo sistema. Prima di utilizzare questi flag, leggi i termini di anteprima all'inizio di questo documento, inclusi i termini relativi alla disattivazione della conferma umana. - Sandbox: le pipeline disattivano la sandbox CodeMender con
--sandbox=false. I comandi eseguiti dall'agente, come build e test, quando corregge un risultato, hanno lo stesso accesso del job, incluse le relativeGoogle Cloud credenziali e l'accesso alla rete. Il sandbox Linux utilizza gli spazi dei nomi utente, che alcuni ambienti CI, come i container senza privilegi, non supportano. Disattiva la sandbox solo in ambienti isolati e temporanei. Se il tuo ambiente CI supporta la sandbox, rimuovi--sandbox=false. - Runner: esegui il flusso di lavoro GitHub Actions sui runner ospitati da GitHub, ad esempio
ubuntu-24.04, che esegue ogni job in una nuova macchina virtuale. Non utilizzare runner self-hosted riutilizzati tra i job. - Codice non attendibile: il codice in una richiesta di pull può contenere testo che tenta di indirizzare l'agente. Il flusso di lavoro di GitHub Actions analizza solo le richieste di pull dai rami dello stesso repository, che possono essere create solo dagli utenti con accesso in scrittura. Per Cloud Build, utilizza il controllo dei commenti in modo che un proprietario o un collaboratore debba approvare le build per le richieste pull di altri collaboratori.
- Accesso: concedi a ogni account di servizio solo i ruoli IAM richiesti per la relativa pipeline.
Scansionare le richieste di pull con GitHub Actions
Il flusso di lavoro in questa sezione analizza ogni richiesta di pull in un repository su
GitHub.com. Quando CodeMender rileva una vulnerabilità con gravità CRITICAL o HIGH
nelle modifiche della richiesta di pull, il flusso di lavoro esegue le seguenti operazioni:
- Non supera il controllo CodeMender scan.
- Esegue
cm fixper ogni risultato e apre una richiesta di pull con le correzioni nel ramo della richiesta di pull.
Il flusso di lavoro carica anche i risultati nella scansione del codice di GitHub.
Configura la federazione delle identità per i workload
Il flusso di lavoro esegue l'autenticazione su Google Cloud con la federazione delle identità per i workload, in modo da non memorizzare una chiave account di servizio in GitHub. Esegui i seguenti comandi con Google Cloud CLI:
Imposta le variabili della shell per il progetto e il repository:
PROJECT_ID="PROJECT_ID" GITHUB_ORG="GITHUB_ORG" REPO="GITHUB_ORG/REPOSITORY"Sostituisci quanto segue:
PROJECT_ID: il tuo ID progetto Google Cloud .GITHUB_ORG: il nome della tua organizzazione GitHub o il tuo nome utente GitHub per un repository in un account personale.REPOSITORY: il nome del repository GitHub.
Abilita le API utilizzate dalla federazione delle identità per i workload:
gcloud services enable iam.googleapis.com \ cloudresourcemanager.googleapis.com iamcredentials.googleapis.com \ sts.googleapis.com --project="${PROJECT_ID}"Crea un account di servizio per il flusso di lavoro e concedigli il ruolo IAM Utente piattaforma agente (
roles/aiplatform.user):gcloud iam service-accounts create codemender-ci \ --project="${PROJECT_ID}" \ --display-name="CodeMender CI" gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:codemender-ci@${PROJECT_ID}.iam.gserviceaccount.com" \ --role="roles/aiplatform.user"Crea un pool di identità del workload. Se hai già un pool per GitHub Actions, salta questo passaggio e utilizza l'ID del pool anziché
githubnei passaggi successivi.gcloud iam workload-identity-pools create github \ --project="${PROJECT_ID}" \ --location="global" \ --display-name="GitHub Actions"Crea un provider per GitHub nel pool. La condizione dell'attributo accetta token solo dai repository di proprietà di
GITHUB_ORG.gcloud iam workload-identity-pools providers create-oidc codemender \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="github" \ --display-name="CodeMender" \ --attribute-mapping="google.subject=assertion.sub,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \ --attribute-condition="assertion.repository_owner == '${GITHUB_ORG}'" \ --issuer-uri="https://token.actions.githubusercontent.com"Consenti ai flussi di lavoro nel tuo repository di utilizzare il account di servizio:
POOL_ID=$(gcloud iam workload-identity-pools describe github \ --project="${PROJECT_ID}" \ --location="global" \ --format="value(name)") gcloud iam service-accounts add-iam-policy-binding \ "codemender-ci@${PROJECT_ID}.iam.gserviceaccount.com" \ --project="${PROJECT_ID}" \ --role="roles/iam.workloadIdentityUser" \ --member="principalSet://iam.googleapis.com/${POOL_ID}/attribute.repository/${REPO}"Ottieni il nome completo del fornitore. Ti servirà nella prossima sezione.
gcloud iam workload-identity-pools providers describe codemender \ --project="${PROJECT_ID}" \ --location="global" \ --workload-identity-pool="github" \ --format="value(name)"L'output è simile al seguente:
projects/123456789/locations/global/workloadIdentityPools/github/providers/codemender
L'applicazione delle modifiche alla federazione delle identità per i workload e a IAM può richiedere fino a 5 minuti. Per ulteriori informazioni, vedi Configurare la federazione delle identità per i carichi di lavoro con le pipeline di deployment.
Aggiungere i secret del repository
Nel repository, vai a Settings (Impostazioni) > Secrets and variables (Secret e variabili) > Actions (Azioni) e aggiungi i seguenti secret del repository:
| Secret | Valore |
|---|---|
GCP_PROJECT_ID |
L'ID progetto. |
GCP_WIF_PROVIDER |
Il nome completo del fornitore della sezione precedente. |
GCP_WIF_SERVICE_ACCOUNT |
codemender-ci@PROJECT_ID.iam.gserviceaccount.com,
dove PROJECT_ID è il tuo ID progetto.
|
Per maggiori informazioni, consulta Utilizzo dei secret in GitHub Actions.
Configura le impostazioni del repository
- Per consentire al job di correzione automatica di aprire le richieste pull, vai a Impostazioni > Azioni > Generali. In Workflow permissions (Autorizzazioni del flusso di lavoro), seleziona Allow GitHub Actions to create and approve pull requests (Consenti a GitHub Actions di creare e approvare le richieste di pull), quindi fai clic su Save (Salva). Un repository in un'organizzazione eredita questa impostazione dall'organizzazione. Se non riesci a modificarlo, chiedi a un proprietario dell'organizzazione. Se non utilizzi la correzione automatica, salta questo passaggio. Per maggiori informazioni, consulta la sezione Gestione delle impostazioni di GitHub Actions per un repository.
- Assicurati che la scansione del codice GitHub sia disponibile per il repository. Per i repository privati e interni, la scansione del codice richiede GitHub Code Security. Se la scansione del codice non è disponibile, elimina il passaggio Carica i risultati nella
scansione del codice e le autorizzazioni
security-eventseactionsdal job di scansione. In caso contrario, il caricamento non riesce e nemmeno il job di scansione. Per maggiori informazioni, vedi Caricare un file SARIF su GitHub.
Aggiungere il workflow
Esegui il commit del seguente workflow nel repository come
.github/workflows/codemender.yml:
name: CodeMender
on:
pull_request:
permissions: {}
defaults:
run:
shell: bash
env:
CM_DOWNLOAD_URL: https://artifactregistry.googleapis.com/download/v1/projects/cmoc-prod/locations/us/repositories/codemender-cli-production/files/cm%3Astable%3Acm-linux-amd64.zip:download?alt=media
jobs:
scan:
name: CodeMender scan
# Workflows for fork and Dependabot pull requests can't read this
# repository's secrets, so they can't authenticate to Google Cloud.
if: >-
github.event.pull_request.head.repo.full_name == github.repository &&
github.actor != 'dependabot[bot]'
runs-on: ubuntu-24.04
timeout-minutes: 15
permissions:
contents: read
id-token: write # Workload Identity Federation
security-events: write # Upload SARIF to code scanning
actions: read # Upload SARIF from a private repository
outputs:
findings: ${{ steps.scan.outputs.findings }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0 # cm needs the base branch history
persist-credentials: false
- uses: google-github-actions/auth@v3
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
service_account: ${{ secrets.GCP_WIF_SERVICE_ACCOUNT }}
- name: Install the CodeMender CLI
run: |
curl -fsSL -o "$RUNNER_TEMP/cm.zip" "$CM_DOWNLOAD_URL"
unzip -q -o "$RUNNER_TEMP/cm.zip" -d "$RUNNER_TEMP/cm"
echo "$RUNNER_TEMP/cm" >> "$GITHUB_PATH"
- name: Scan the pull request
id: scan
env:
BASE_REF: ${{ github.base_ref }}
FAIL_ON: CRITICAL,HIGH
run: |
cm init
status=0
cm find . \
--diff="origin/$BASE_REF" \
--diff-workers=16 \
--fail-on="$FAIL_ON" \
--format=sarif \
--output=codemender.sarif \
--sandbox=false \
--yes \
--bypass-warning || status=$?
# Save the findings that failed the scan for the autofix job. Like the
# CI gate, skip findings labeled [LEGACY / UNTOUCHED]: they're in code
# that the pull request didn't change.
echo '[]' > "$RUNNER_TEMP/codemender-findings.json"
if [ "$status" -ne 0 ]; then
cm report --format=json --status=OPEN \
| jq --arg fail_on "$FAIL_ON" '
($fail_on | ascii_upcase | split(",")) as $severities
| [.[]
| select(.title | startswith("[LEGACY / UNTOUCHED]") | not)
| select(.severity | ascii_upcase | IN($severities[]))]' \
> "$RUNNER_TEMP/codemender-findings.json"
fi
echo "findings=$(jq length "$RUNNER_TEMP/codemender-findings.json")" >> "$GITHUB_OUTPUT"
exit "$status"
- name: Upload results to code scanning
if: ${{ !cancelled() && hashFiles('codemender.sarif') != '' }}
uses: github/codeql-action/upload-sarif@v4
with:
sarif_file: codemender.sarif
category: codemender
- name: Save findings for autofix
if: ${{ !cancelled() && steps.scan.outputs.findings > 0 }}
uses: actions/upload-artifact@v7
with:
name: codemender-findings
path: ${{ runner.temp }}/codemender-findings.json
retention-days: 1
autofix:
name: CodeMender autofix
needs: scan
if: ${{ !cancelled() && needs.scan.outputs.findings > 0 }}
runs-on: ubuntu-24.04
timeout-minutes: 60
permissions:
contents: write # Push the fix branch
pull-requests: write # Open the fix pull request
id-token: write # Workload Identity Federation
steps:
- uses: actions/checkout@v7
with:
ref: ${{ github.head_ref }}
persist-credentials: false
- uses: google-github-actions/auth@v3
with:
project_id: ${{ secrets.GCP_PROJECT_ID }}
workload_identity_provider: ${{ secrets.GCP_WIF_PROVIDER }}
service_account: ${{ secrets.GCP_WIF_SERVICE_ACCOUNT }}
- name: Install the CodeMender CLI
run: |
curl -fsSL -o "$RUNNER_TEMP/cm.zip" "$CM_DOWNLOAD_URL"
unzip -q -o "$RUNNER_TEMP/cm.zip" -d "$RUNNER_TEMP/cm"
echo "$RUNNER_TEMP/cm" >> "$GITHUB_PATH"
- uses: actions/download-artifact@v8
with:
name: codemender-findings
path: ${{ runner.temp }}/codemender
- name: Fix findings
run: |
# Keep CodeMender state and the auth action's credentials file out of
# the commits, and out of the `git clean` that cm fix runs.
printf '%s\n' .cm_project 'gha-creds-*.json' >> .git/info/exclude
cm init
# Fix in the repository root instead of each file's directory.
printf 'project_paths:\n - "%s"\n' "$GITHUB_WORKSPACE" \
>> ~/.codemender/config.yaml
cm report import -f "$RUNNER_TEMP/codemender/codemender-findings.json"
git config user.name "github-actions[bot]"
git config user.email \
"41898282+github-actions[bot]@users.noreply.github.com"
cm report --format=json --status=OPEN \
| jq -r '.[] | [.finding_id, .title] | @tsv' \
> "$RUNNER_TEMP/findings.tsv"
while IFS=$'\t' read -r id title; do
# cm fix exits 0 when it makes no edits, so also check for changes.
if cm fix "$id" \
--sandbox=false --yes --bypass-warning < /dev/null &&
! git diff --quiet; then
git commit -q -a -m "Fix $title" -m "CodeMender finding $id"
else
echo "::warning::CodeMender didn't fix \"$title\" ($id)."
fi
# Discard files the fix agent created, such as test output.
git reset -q --hard
git clean -q -fd
done < "$RUNNER_TEMP/findings.tsv"
- uses: peter-evans/create-pull-request@v8
with:
branch: codemender/fix-pr-${{ github.event.pull_request.number }}
base: ${{ github.head_ref }}
title: "CodeMender fixes for #${{ github.event.pull_request.number }}"
body: |
CodeMender generated these fixes for findings in #${{ github.event.pull_request.number }}.
Review each commit before you merge this pull request into `${{ github.head_ref }}`.
Dettagli workflow
Il seguente diagramma mostra come interagiscono le scansioni delle richieste di pull e i job di correzione automatica:
Il job CodeMender scan esegue le seguenti operazioni:
- Estrae la richiesta di pull con la relativa cronologia completa. Per le richieste di pull, GitHub estrae un commit di unione del ramo della richiesta di pull nel ramo di base.
- Esegue l'autenticazione su Google Cloud e scarica l'ultima release stabile della CLI CodeMender.
- Esegue
cm find --diffsul ramo di base. Il job non riesce se CodeMender trova una vulnerabilità con una gravità elencata inFAIL_ONnelle modifiche della richiesta pull. - Carica il report nella scansione del codice di GitHub, anche quando la scansione non riesce. Il report include i risultati etichettati come
[LEGACY / UNTOUCHED]. La scansione del codice mostra anche un risultato nei controlli della richiesta pull quando tutte le righe del risultato si trovano nel diff della richiesta pull. - Salva i risultati per cui il job non è riuscito per il job di correzione automatica.
Il job di scansione non viene eseguito per le richieste pull dai fork o da Dependabot,
perché i workflow per queste richieste pull non possono leggere i segreti del repository.
GitHub segnala un job ignorato come riuscito, quindi il controllo non blocca queste
pull request, anche se lo rendi un controllo obbligatorio. Esamina queste richieste pull
oppure scansionale localmente con cm find --diff.
Il job CodeMender autofix viene eseguito quando il job di scansione salva i risultati. Svolge le seguenti operazioni:
- Estrae il ramo della richiesta di pull.
- Esegue
cm fixper ogni risultato e applica ogni correzione separatamente. Se CodeMender non corregge un risultato, il job registra un avviso. Il job esegue il commit solo delle modifiche ai file già presenti nel repository e ignora tutti i file creati dall'agente di correzione, ad esempio l'output del test. - Apre una richiesta di pull dal ramo
codemender/fix-pr-NUMBERal ramo della richiesta di pull, doveNUMBERè il numero della richiesta di pull. Se la richiesta di pull della correzione esiste già, il job la aggiorna. Se CodeMender non corregge alcun problema o se il job raggiunge il timeout di 60 minuti, non viene aperta una richiesta di pull.
Esaminare e unire le correzioni
GitHub non esegue automaticamente i flussi di lavoro per le richieste pull che un flusso di lavoro crea con GITHUB_TOKEN. Per esaminare la richiesta di pull di correzione, un utente con accesso in scrittura al repository fa clic su Approva l'esecuzione dei workflow nella richiesta di pull di correzione.
Quando unisci la richiesta di pull di correzione, il ramo della richiesta di pull cambia e il flusso di lavoro esegue nuovamente la scansione della richiesta di pull originale.
Personalizzare il workflow
Puoi personalizzare il flusso di lavoro nei seguenti modi:
- Per modificare le gravità che non superano il controllo, nel passaggio Analizza la richiesta di pull, imposta
FAIL_ONsu un elenco separato da virgole di gravità senza spazi, ad esempioCRITICAL,HIGH,MEDIUM. I valori validi sonoCRITICAL,HIGH,MEDIUMeLOW. - Per segnalare i risultati senza superare il controllo, imposta
FAIL_ON: "". Il workflow carica comunque i risultati nella scansione del codice, ma non esegue il job di correzione automatica. Per analizzare le richieste di pull solo in alcuni rami, aggiungi un filtro
branchesall'attivatorepull_request. Il flusso di lavoro non esegue la scansione delle richieste di pull di correzione perché la loro base è un ramo della richiesta di pull:on: pull_request: branches: [main]Per disattivare la correzione automatica, elimina il job
autofixe il passaggio Salva i risultati per la correzione automatica.
Scansiona le richieste di pull con Cloud Build
La build in questa sezione analizza ogni richiesta di pull in un repository GitHub connesso a Cloud Build. La build e il controllo GitHub non riescono quando
CodeMender rileva una vulnerabilità con gravità CRITICAL o HIGH nelle modifiche
della richiesta pull. La build non corregge i risultati.
Prima di iniziare, segui questi passaggi:
- Connetti il repository a Cloud Build come repository di seconda generazione. Per maggiori informazioni, consulta la pagina Connettiti a un repository GitHub.
Abilita l'API Cloud Build e l'API IAM nel progetto che ha accesso a CodeMender. La build utilizza CodeMender nel progetto che esegue la build.
PROJECT_ID="PROJECT_ID" gcloud services enable cloudbuild.googleapis.com iam.googleapis.com \ --project="${PROJECT_ID}"Sostituisci
PROJECT_IDcon il tuo ID progetto Google Cloud.
Crea un account di servizio
Crea un account di servizio per la build. Concedi il ruolo IAM Utente Agent Platform (roles/aiplatform.user) per utilizzare CodeMender e il ruolo Writer log (roles/logging.logWriter) per scrivere i log di build:
SA="codemender-build@${PROJECT_ID}.iam.gserviceaccount.com"
gcloud iam service-accounts create codemender-build \
--project="${PROJECT_ID}" \
--display-name="CodeMender Cloud Build"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${SA}" \
--role="roles/aiplatform.user"
gcloud projects add-iam-policy-binding "${PROJECT_ID}" \
--member="serviceAccount:${SA}" \
--role="roles/logging.logWriter"
Per salvare i report SARIF in un bucket Cloud Storage, concedi anche al account di servizio l'accesso al bucket:
BUCKET="BUCKET"
gcloud storage buckets add-iam-policy-binding "gs://${BUCKET}" \
--member="serviceAccount:${SA}" \
--role="roles/storage.objectUser"
Sostituisci BUCKET con il nome del tuo bucket Cloud Storage.
Aggiungi la configurazione build
Esegui il commit della seguente configurazione di build nella radice del repository come
cloudbuild.yaml:
# Scans a pull request with CodeMender. The build fails when CodeMender finds
# a CRITICAL or HIGH vulnerability in the pull request's changes.
steps:
- id: install-codemender
name: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
script: |
#!/usr/bin/env bash
set -euo pipefail
curl -fsSL -o /tmp/cm.zip "$_CM_DOWNLOAD_URL"
python3 -m zipfile -e /tmp/cm.zip /workspace/.codemender-cli
chmod +x /workspace/.codemender-cli/cm
- id: fetch-history
name: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
script: |
#!/usr/bin/env bash
set -euo pipefail
: "${_BASE_BRANCH:?Run this build from a pull request trigger.}"
# Triggers check out only the pull request's commit. CodeMender needs the
# history back to where the pull request branched from the base branch.
# Fetch from origin, or from GitHub if origin isn't configured.
refspec="+refs/heads/$_BASE_BRANCH:refs/remotes/origin/$_BASE_BRANCH"
git fetch --quiet --unshallow origin "$refspec" ||
git fetch --quiet --unshallow \
"https://github.com/$REPO_FULL_NAME.git" "$refspec"
merge_base=$(git merge-base HEAD "origin/$_BASE_BRANCH")
echo "Merge base with $_BASE_BRANCH: $merge_base"
- id: scan
name: gcr.io/google.com/cloudsdktool/google-cloud-cli:slim
script: |
#!/usr/bin/env bash
set -uo pipefail
export PATH="/workspace/.codemender-cli:$PATH"
# The project that has access to CodeMender.
export GOOGLE_CLOUD_PROJECT="$PROJECT_ID"
cm init || exit 1
status=0
cm find . \
--diff="origin/$_BASE_BRANCH" \
--diff-workers=16 \
--fail-on=CRITICAL,HIGH \
--format=sarif \
--output=codemender.sarif \
--sandbox=false \
--yes \
--bypass-warning || status=$?
# cm find writes the SARIF report when the scan completes.
if [ -f codemender.sarif ]; then
# cm find doesn't print finding details, so print them here.
cm report --status=OPEN --format=md
if [ -n "${_REPORT_BUCKET:-}" ]; then
gcloud storage cp codemender.sarif \
"gs://$_REPORT_BUCKET/codemender/$BUILD_ID.sarif" || status=1
fi
fi
exit "$status"
substitutions:
_CM_DOWNLOAD_URL: https://artifactregistry.googleapis.com/download/v1/projects/cmoc-prod/locations/us/repositories/codemender-cli-production/files/cm%3Astable%3Acm-linux-amd64.zip:download?alt=media
_REPORT_BUCKET: '' # Optional: a bucket to save the SARIF report in.
timeout: 1200s
options:
automapSubstitutions: true
logging: CLOUD_LOGGING_ONLY
Crea il trigger
Crea un trigger che esegue la build per ogni richiesta di pull in main:
REGION="REGION"
CONNECTION="CONNECTION"
REPOSITORY="REPOSITORY"
gcloud builds triggers create github \
--project="${PROJECT_ID}" \
--region="${REGION}" \
--name="codemender-scan" \
--repository="projects/${PROJECT_ID}/locations/${REGION}/connections/${CONNECTION}/repositories/${REPOSITORY}" \
--pull-request-pattern='^main$' \
--comment-control=COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY \
--build-config=cloudbuild.yaml \
--service-account="projects/${PROJECT_ID}/serviceAccounts/${SA}"
Sostituisci quanto segue:
REGION: la regione della connessione al repository Cloud Build.CONNECTION: il nome della connessione al repository Cloud Build.REPOSITORY: il nome del repository connesso in Cloud Build.
Tieni presente le seguenti opzioni:
--pull-request-patternè un'espressione regolare per il branch di base della richiesta di pull. Utilizza^e$per trovare una corrispondenza con l'intero nome del ramo.- Con
--comment-control=COMMENTS_ENABLED_FOR_EXTERNAL_CONTRIBUTORS_ONLY, la build viene eseguita automaticamente per le richieste pull dei proprietari del repository e dei collaboratori. Per le richieste di pull di altri collaboratori, la build viene eseguita dopo che un proprietario o un collaboratore commenta/gcbrunla richiesta di pull. - Per salvare i report SARIF in un bucket, aggiungi
--substitutions=_REPORT_BUCKET="${BUCKET}".
Puoi anche creare il trigger nella console Google Cloud . Per maggiori informazioni, vedi Creazione di repository da GitHub.
Per mostrare i log di build in GitHub, aggiungi --include-logs-with-status quando crei il trigger e concedi al account di servizio il ruolo Visualizzatore log (roles/logging.viewer). Chiunque possa visualizzare il controllo in GitHub può leggere i log di build, inclusi i risultati.
Come funziona la build
La build prevede tre passaggi:
install-codemenderscarica l'ultima release stabile della CLI CodeMender.fetch-historyrecupera il ramo di base e la cronologia necessari a CodeMender. Cloud Build estrae solo il commit che ha avviato la build. Il passaggio recupera i dati dal repository remotoorigin. Seoriginnon è configurato, il passaggio recupera i dati da GitHub senza credenziali, il che funziona solo per i repository pubblici. In questo caso, un repository privato richiede credenziali, ad esempio una chiave SSH. Per maggiori informazioni, consulta la pagina Accesso a GitHub da una build tramite chiavi SSH.scaneseguecm find --diffsul ramo di base. Al termine della scansione, il passaggio stampa tutti i risultati nel log di build. Se imposti_REPORT_BUCKET, il passaggio copia anche il report SARIF ings://BUCKET/codemender/BUILD_ID.sarif.
Per modificare le gravità che non superano la build, modifica --fail-on nel passaggio scan. Se esegui la build senza un trigger di richiesta di pull, l'operazione non va a buon fine e viene visualizzato il messaggio Run this build from a pull request trigger.
Esegui la scansione prima di ogni commit
Un hook pre-commit di Git può analizzare le modifiche in attesa di commit e bloccare il commit quando
CodeMender rileva una vulnerabilità con gravità CRITICAL o HIGH. Gli sviluppatori
possono ignorare l'hook, quindi utilizzalo in aggiunta alla scansione nelCI9;integrazione continua, non al suo posto.
Ogni sviluppatore che utilizza l'hook ha bisogno di quanto segue:
- La CLI CodeMender, installata e configurata come descritto in Installare e configurare la CLI, inclusi
gcloud auth application-default loginecm init. Il gancio deve esserecmsulPATH. - Il ruolo Utente della piattaforma Agent Platform (
roles/aiplatform.user) in un progetto con accesso a CodeMender. CodeMender utilizza il progetto nella variabile di ambienteGOOGLE_CLOUD_PROJECT. Se questa variabile non è impostata, CodeMender utilizza il progetto dalle credenziali predefinite dell'applicazione o il progetto predefinito di gcloud CLI.
Per aggiungere l'hook, salva il seguente script come .git/hooks/pre-commit nel tuo
repository:
#!/bin/sh
# Scans staged changes with CodeMender before each commit.
if ! cm find . --diff --staged --fail-on=CRITICAL,HIGH \
--yes --bypass-warning; then
echo "CodeMender blocked this commit. To see the findings, run:" >&2
echo " cm report --status=OPEN" >&2
echo "To commit anyway, run git commit --no-verify." >&2
exit 1
fi
Rendi eseguibile lo script, quindi aggiungi .cm_project al file .gitignore
in modo da non eseguire il commit del file creato da CodeMender per monitorare il
repository:
chmod +x .git/hooks/pre-commit
echo .cm_project >> .gitignore
Quando esegui git commit, l'hook esegue la scansione dei file con modifiche in attesa di commit. La
scansione può richiedere alcuni minuti. L'hook non disattiva la sandbox CodeMender.
Per eseguire il commit senza la scansione, esegui git commit --no-verify.
Flag di scansione
I seguenti flag cm find controllano le scansioni delle richieste di pull. Per tutti i flag, esegui cm
find --help:
| Flag | Predefinito | Descrizione |
|---|---|---|
--diff[=REF] |
Off |
Analizza le modifiche rispetto a REF, ad esempio
origin/main. Senza REF, le scansioni
modifiche non eseguite ai file monitorati (rispetto a
HEAD). Non può essere utilizzato con --deep.
|
--staged |
Off | Con --diff, vengono analizzate solo le modifiche in attesa di commit. |
--diff-depth DEPTH |
1 |
Profondità di attraversamento per l'analisi d'impatto (da 1 a 3, valore predefinito: 1 hop). |
--diff-workers COUNT |
4 |
Il numero di file da scansionare contemporaneamente, da 1 a 16. |
--diff-max-neighbors COUNT |
10 |
Il numero massimo di file dipendenti da scansionare. |
--fail-on SEVERITIES |
CRITICAL,HIGH |
Con --diff, le gravità che fanno uscire cm find
con stato 1. Con un valore vuoto, i risultati non influiscono sullo stato di uscita.
|
--fail-on-truncation |
Off |
Con --diff, esce con lo stato 1 se CodeMender trova più file dipendenti di quelli consentiti da --diff-max-neighbors.
|
--format FORMAT |
table |
Il formato del report: table, json o
sarif.
|
--output FILE |
Output standard | Il file in cui scrivere il report. |
Risoluzione dei problemi
Questa sezione descrive come risolvere i problemi comuni durante l'esecuzione di CodeMender nelle pipeline CI/CD.
Autorizzazione negata
Il log mostra una riga simile alla seguente:
[1/1] ❌ src/app.py: start session failed: StartSession failed with HTTP 403 Forbidden.
Il messaggio può includere anche Permission 'aiplatform.interactions.create'
denied. Verifica quanto segue:
- Il progetto ha accesso a CodeMender.
- Il account di servizio o l'utente dispone del ruolo Utente della piattaforma dell'agente
(
roles/aiplatform.user) nel progetto. - L'API Agent Platform è abilitata nel progetto.
- CodeMender utilizza il progetto corretto. In GitHub Actions, controlla il secret
GCP_PROJECT_ID. Cloud Build utilizza il progetto che esegue la build. A livello locale, controlla la variabile di ambienteGOOGLE_CLOUD_PROJECTo il progetto predefinito se la variabile non è impostata.
Configurazione della risorsa in corso
Se nel log viene visualizzato Resource setup has just started. Please try again shortly. o
Resource setup is in progress. Please try again shortly., CodeMender sta
configurando le risorse per il tuo progetto, il che in genere richiede alcuni minuti. Esegui
di nuovo il job in un secondo momento.
Flag sconosciuto: --diff
Se cm find non riesce con Error: unknown flag: --diff, la tua release della CLI non
supporta le scansioni delle richieste di pull. Esegui cm update o scarica l'ultima release.
Ramo base non trovato
Se cm find non va a buon fine e viene visualizzato un errore simile al seguente, il ramo di base non è
nel checkout:
Error: retrieving VCS diff: git diff failed: exit status 128: fatal: ambiguous argument 'origin/main': unknown revision or path not in the working tree.
Recupera il ramo di base e la relativa cronologia prima di eseguire cm find. In GitHub
Actions, imposta fetch-depth: 0 in actions/checkout.
File non analizzati
Una riga con ❌, ad esempio [1/1] ❌ src/app.py: start session failed, indica che
CodeMender non è riuscito a scansionare il file. Controlla l'errore nella riga, quindi esegui
di nuovo il job.
Nessuna richiesta di pull di correzione
Se il flusso di lavoro non apre una richiesta di pull di correzione, controlla quanto segue:
- Se il job di correzione automatica non riesce a creare la richiesta di pull, attiva l'opzione Consenti a GitHub Actions di creare e approvare le richieste di pull. Per saperne di più, consulta Configurare le impostazioni del repository.
- Se il job di correzione automatica va a buon fine senza aprire una richiesta di pull, CodeMender non ha corretto alcun risultato. Il log del job mostra un avviso per ogni risultato che CodeMender non ha corretto.
Il caricamento della scansione del codice non riesce
Se il passaggio di caricamento non va a buon fine con GitHub Code Security or GitHub Advanced Security
must be enabled for this repository to use code scanning, attiva GitHub Code
Security per il repository o elimina il passaggio di caricamento. Per saperne di più,
consulta Configurare le impostazioni del repository.
Avviso non confermato
Se cm non riesce a eseguire warning not acknowledged. Please run interactively once to
acknowledge or pass --bypass-warning, CodeMender ha bisogno di una conferma che non può richiedere in un ambiente non interattivo. Aggiungi --bypass-warning al comando. Prima di farlo, leggi i termini dell'anteprima nella parte superiore di questa pagina.
Per ulteriore assistenza, contatta il team di vendita.