Zabezpieczanie potoku CI/CD za pomocą CodeMender

1. Zanim zaczniesz

Witamy w praktycznym ćwiczeniu z programowania Zabezpieczanie potoku CI/CD za pomocą CodeMender.

W nowoczesnym procesie dostarczania oprogramowania narzędzia do analizy statycznej (takie jak CodeQL) są niezbędne do wykrywania znanych wzorców składniowych, ale często nie zauważają niuansów luk w zabezpieczeniach ukrytych głęboko w logice biznesowej i generują niepotrzebne, niezweryfikowane alerty.

CodeMender (plik wykonywalny interfejsu wiersza poleceń: cm) ulepsza potok CI/CD, działając razem z istniejącymi narzędziami SAST, dzięki wdrażaniu agentów rozumowania bezpieczeństwa opartych na Gemini od Google, które:

Wykrywanie złożonych błędów logiki biznesowej: analizowanie kontekstu aplikacji i przepływów danych architektonicznych poza sztywnymi regułami wzorców statycznych.

Znaczne zmniejszenie liczby wyników fałszywie dodatnich dzięki samodzielnej weryfikacji luk w zabezpieczeniach: dynamiczne sprawdzanie możliwości wykorzystania luk w zabezpieczeniach w środowiskach piaskownicy przed powiadomieniem deweloperów.

Autonomiczne naprawianie zweryfikowanych wyników: syntezowanie poprawek kodu, sprawdzanie ich pod kątem zestawów testów w celu zapobiegania regresjom i przesyłanie żądań pull gotowych do sprawdzenia.

W tym ćwiczeniu zintegrujesz CodeMender z repozytorium OWASP Juice Shop za pomocą GitHub Actions i federacji tożsamości zadań Google Cloud (WIF) bez użycia kluczy.

Wymagania wstępne

  • Zalecane: podstawowa znajomość pojęć związanych z CodeMender (omówionych w module Zabezpieczanie aplikacji za pomocą CodeMender)
  • Podstawowa znajomość przepływów pracy, aktywatorów i składni YAML w GitHub Actions.
  • podstawowa znajomość poleceń Git i procesów sprawdzania żądań pull.
  • podstawowa znajomość pojęć związanych z Cloud IAM w Google Cloud (konta usługi, role i interfejsy API);
  • znajomość typowych luk w zabezpieczeniach aplikacji internetowych (takich jak wstrzyknięcie kodu SQL i XSS).

Czego się nauczysz

  • jak skonfigurować uwierzytelnianie bez klucza w modelu zero-trust między GitHub Actions a Google Cloud za pomocą federacji tożsamości zadań (WIF);
  • Jak utworzyć zautomatyzowany przepływ pracy skanowania pod kątem luk w zabezpieczeniach za pomocą CodeMender i gemini-3.8-flash.
  • Jak publikować raporty dotyczące bezpieczeństwa z możliwością podjęcia działań za pomocą OASIS SARIF w wersji 2.1.0 i natywnych podsumowań zadań GitHub Actions.
  • jak utworzyć autonomiczny przepływ pracy naprawy, który generuje poprawki kodu zweryfikowane przez testy i otwiera żądania pull do weryfikacji manualnej;
  • Jak wymusić automatyczne rygorystyczne kontrole jakości (--fail-on) i buforowanie potoku, aby zapewnić szybkie i ciągłe bezpieczeństwo

Czego potrzebujesz

  • projekt Google Cloud z włączonymi płatnościami i uprawnieniami właściciela/edytującego projekt,
  • Konto GitHub z uprawnieniami do tworzenia repozytoriów, konfigurowania obiektów tajnych i zarządzania działaniami (w kroku 3 utworzysz rozwidlenie repozytorium OWASP Juice Shop na GitHubie za pomocą interfejsu wiersza poleceń GitHuba).

2. Zrozumienie architektury CI/CD CodeMender

W nowoczesnych procesach DevSecOps w przedsiębiorstwach zabezpieczenia oparte na AI nie mogą być tylko ręcznym narzędziem na komputerze. Musi działać jako automatyczny strażnik (blokujący niebezpieczne żądania pull) i autonomiczny współtwórca (proponujący zweryfikowane poprawki bezpośrednio w Git).

Aby to osiągnąć, wdrożysz architekturę podwójnego przepływu pracy opartą na federacji tożsamości zadań (WIF) w Google Cloud i modelach rozumowania Gemini Enterprise.

Architektura podwójnego przepływu pracy

Architektura autonomicznego potoku CI/CD CodeMender

Zamiast upychać wykrywanie i naprawianie w jednym monolitycznym skrypcie, potok dzieli zabezpieczenia na 2 oddzielne, specjalnie zaprojektowane przepływy pracy:

Przepływ pracy

Aktywator główny

Główne obowiązki

Wymóg jakościowy

1. Vulnerability Scanner(codemender-scan.yml)

Żądania pull, wypchnięcia do gałęzi głównej, cotygodniowe zadania cron, ręczne wysyłanie

• Szybkie skanowanie AST w PR (~15 s), szybkie skanowanie bazowe w pushach (–quick) i równoczesne szczegółowe audyty w harmonogramach• Weryfikacja gotowości z wyprzedzeniem za pomocą cm health –strict• Generowanie natywnych podsumowań zadań Actions i przesyłanie OASIS SARIF na kartę Bezpieczeństwo w GitHubie

Blokuje scalanie PR, jeśli zostaną wykryte nowo wprowadzone luki o wysokim lub krytycznym poziomie zagrożenia (–fail-on).

2. Autonomous Remediator(codemender-remediate.yml)

Aktywator ręczny (workflow_dispatch), nocny cron

• Wznawia stan na podstawie artefaktów skanowania (cm report import) i state.db• Syntetyzuje poprawki przy użyciu wnioskowania Gemini• Zachowuje czyste granice obszaru roboczego i przesyła gotowe do sprawdzenia żądania pull

Zapewnia czyste różnice produkcyjne przed otwarciem PR.

3 główne zasady projektowania dla firm

Podczas tworzenia tych przepływów pracy w kolejnych sekcjach pamiętaj o tych 3 podstawowych filarach architektury:

🔑 Uwierzytelnianie bez kluczy i weryfikacja wstępna w modelu Zero Trust:

W GitHub Secrets nie są przechowywane żadne długotrwałe klucze JSON konta usługi Google Cloud. Program uruchamiający generuje krótkotrwały token OIDC wymieniany za pośrednictwem Google Cloud STS na efemeryczne poświadczenie ważne godzinę, ustawia persist-credentials: false w przypadku pobrań w Git i uruchamia cm health --strict w celu sprawdzenia poświadczeń, dostępności sieci i uprawnień IAM przed wykorzystaniem limitu modelu wykorzystania.

⚡ Adaptacyjne kierowanie skanowania i starsza wersja eliminowania szumu:

Zamiast przeprowadzać powolne audyty całego repozytorium przy każdym żądaniu pull, CodeMender kieruje każde zdarzenie CI do optymalnego trybu skanowania: żądania pull wyzwalają analizę AST (--diff="origin/$BASE_REF") zmodyfikowanych plików i wywołujących w odległości 1 skoku w mniej niż 15 sekund; wypchnięcia do gałęzi głównej uruchamiają szybkie skanowanie bazowe w ramach jednej sesji (--quick); a harmonogramy tygodniowe uruchamiają równoczesne szczegółowe audyty poszczególnych plików (domyślnie cm find .). Istniejące wcześniej luki w zabezpieczeniach bazy kodu, które nie zostały zmienione przez żądanie pull, są oznaczone jako [LEGACY / UNTOUCHED]. Pojawiają się one w raportach SARIF, aby były widoczne, ale nie blokują bramki scalania żądania pull i nie wyzwalają automatycznej naprawy.

🛡️ Odporna, nieblokująca obserwacja zabezpieczeń:

Nawet jeśli --fail-on zakończy działanie z kodem 1, aby zablokować niebezpieczne żądanie pull, zabezpieczenie kroków eksportowania raportu i przesyłania pliku SARIF za pomocą steps.scan.outputs.completed == 'true' i hashFiles('results.sarif') != '' gwarantuje, że alerty OASIS SARIF i podsumowania zadań będą nadal publikowane, a eksportowanie i przesyłanie zostanie pominięte, jeśli uruchomienie zostanie anulowane lub przerwane z powodu błędu konfiguracji lub pojemności (10–60).

3. Uwierzytelnianie i przygotowywanie repozytorium docelowego w Cloud Shell

Aby skonfigurować uwierzytelnianie bez kluczy i uruchamiać automatyczne potoki zabezpieczeń, musisz mieć dostęp do docelowego repozytorium GitHub, którego jesteś właścicielem. W tym ćwiczeniu użyjesz OWASP Juice Shop – aplikacji internetowej Node.js, która celowo zawiera luki w zabezpieczeniach – jako gotowego środowiska do testowania zabezpieczeń.

Użyjesz interfejsu wiersza poleceń GitHuba (gh) wstępnie zainstalowanego w Google Cloud Shell, aby uwierzytelnić się w GitHubie, automatycznie przechwycić dane użytkownika i przygotować repozytorium w jednym uproszczonym procesie.

Krok 1. Otwórz Cloud Shell i uwierzytelnij interfejs wiersza poleceń GitHuba

Otwórz konsolę Google Cloud i aktywuj Cloud Shell (ikona >_ na górnym pasku nawigacyjnym).

Uwierzytelnij interfejs wiersza poleceń GitHub (gh), aby skonfigurować zarządzanie danymi logowania Git:

gh auth login --hostname github.com --git-protocol https --web

Postępuj zgodnie z instrukcjami wyświetlanymi na ekranie:

Skopiuj 8-znakowy kod jednorazowy wyświetlony w Cloud Shell (np. 1234-ABCD).

Naciśnij Enter, aby otworzyć https://github.com/login/device w przeglądarce.

Wklej kod i kliknij Authorize github (Autoryzuj GitHub).

Krok 2. Dynamicznie wyeksportuj zmienne i utwórz rozwidlenie OWASP Juice Shop

Aby automatycznie przechwycić nazwę użytkownika GitHub i przygotować repozytorium, uruchom w Cloud Shell te polecenia:

# 1. Automatically capture your GitHub username (customize GITHUB_REPO if desired)
export GITHUB_ORG=$(gh api user -q .login)
export GITHUB_REPO="${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_ORG:+${GITHUB_ORG}/${GITHUB_REPO}}"
echo "Authenticated as: ${GITHUB_REPOSITORY}"

# 2. Fork on GitHub server using GITHUB_REPO as the fork name
gh repo fork juice-shop/juice-shop --fork-name "${GITHUB_REPO}" --default-branch-only --clone=false 2>/dev/null || true

# 3. Shallow clone your fork (downloads only ~15 MB in 3-5 seconds, skipping heavy upstream git history)
[ -d ~/"${GITHUB_REPO}" ] || git clone --depth=1 "https://github.com/${GITHUB_REPOSITORY}.git" ~/"${GITHUB_REPO}" || \
 (sleep 2 && git clone --depth=1 "https://github.com/${GITHUB_REPOSITORY}.git" ~/"${GITHUB_REPO}")
cd ~/"${GITHUB_REPO}"

# 4. Confirm you are in the repository directory
git status

4. Konfigurowanie federacji tożsamości zadań Google Cloud za pomocą gcloud

W tym kroku użyjesz interfejsu wiersza poleceń gcloud w Google Cloud Shell, aby włączyć wymagane interfejsy API, utworzyć dedykowane konto usługi CI/CD, skonfigurować pulę tożsamości zadań i ustanowić zaufanie OIDC z repozytorium GitHub (${GITHUB_REPOSITORY}).

Krok 1. Ustaw zmienne środowiskowe Google Cloud

W terminalu Cloud Shell (w sklonowanym obszarze roboczym repozytorium) przechwyć aktywny identyfikator projektu Google Cloud, sprawdź zmienną repozytorium GitHub i zdefiniuj nazwy zasobów WIF:

# Capture active Google Cloud Project ID and verify GitHub repository
export PROJECT_ID=$(gcloud config get-value project)
export GITHUB_USER=$(gh api user -q ".login")
export GITHUB_REPO="${GITHUB_REPO:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*/##; s#\.git$##')}"
export GITHUB_REPO="${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_USER:+${GITHUB_USER}/${GITHUB_REPO}}"

# Define WIF and Service Account resource names
export WORKLOAD_IDENTITY_POOL="codemender-github-pool"
export WORKLOAD_IDENTITY_PROVIDER="codemender-github-provider"
export SERVICE_ACCOUNT_NAME="codemender-ci-runner"

if [ -z "${PROJECT_ID}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: PROJECT_ID ('${PROJECT_ID}') or GITHUB_REPOSITORY ('${GITHUB_REPOSITORY}') is empty. Check 'gcloud config get-value project' and 'gh auth status'."
else
 echo "Project ID:        ${PROJECT_ID}"
 echo "GitHub Repository: ${GITHUB_REPOSITORY}"
fi

Krok 2. Włącz wymagane interfejsy Google Cloud API

Włącz interfejsy IAM API, Security Token Service API, IAM Credentials API, Agent Platform API i Resource Manager API:

gcloud services enable \
 iam.googleapis.com \
 iamcredentials.googleapis.com \
 sts.googleapis.com \
 aiplatform.googleapis.com \
 cloudresourcemanager.googleapis.com \
 --project=${PROJECT_ID}

Krok 3. Utwórz dedykowane konto usługi CI/CD

Utwórz konto usługi Google Cloud o jak najmniejszych uprawnieniach, które będzie przeznaczone do wykonywania potoku CI/CD (bezpiecznie użyj go ponownie, jeśli już istnieje):

export SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"

gcloud iam service-accounts describe "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" >/dev/null 2>&1 || \
gcloud iam service-accounts create "${SERVICE_ACCOUNT_NAME}" \
 --display-name="CodeMender CI/CD Pipeline Runner" \
 --project="${PROJECT_ID}"

echo "Service Account Email: ${SERVICE_ACCOUNT_EMAIL}"

Krok 4. Przyznaj uprawnienia IAM platformy agentów

Przypisz do konta usługi rolę roles/aiplatform.user (użytkownik platformy agentów), aby mogło ono komunikować się z platformą Gemini Enterprise Agent Platform:

gcloud projects add-iam-policy-binding ${PROJECT_ID} \
 --member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
 --role="roles/aiplatform.user"

Krok 5. Utwórz pulę tożsamości zadań

Utwórz pulę tożsamości zadań, aby zarządzać asercjami tożsamości GitHub Actions (lub automatycznie przywróć i włącz ją, jeśli już istnieje w Twoim projekcie):

POOL_STATE=$(gcloud iam workload-identity-pools list \
 --location="global" \
 --show-deleted \
 --project="${PROJECT_ID}" \
 --filter="name ~ /${WORKLOAD_IDENTITY_POOL}$" \
 --format="value(state)")

if [ -z "${POOL_STATE}" ]; then
 gcloud iam workload-identity-pools create "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --display-name="CodeMender GitHub Pool" \
   --project="${PROJECT_ID}"
else
 [ "${POOL_STATE}" = "DELETED" ] && gcloud iam workload-identity-pools undelete "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --project="${PROJECT_ID}"
 gcloud iam workload-identity-pools update "${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --no-disabled \
   --project="${PROJECT_ID}"
fi

Krok 6. Utwórz dostawcę tożsamości do Workload Identity za pomocą GitHub OIDC

Utwórz (lub zaktualizuj) dostawcę OIDC w puli, powiąż adres URL wystawcy https://token.actions.githubusercontent.com i zmapuj asercje tokena GitHub na atrybuty Google STS:

PROVIDER_STATE=$(gcloud iam workload-identity-pools providers list \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --show-deleted \
 --project="${PROJECT_ID}" \
 --filter="name ~ /${WORKLOAD_IDENTITY_PROVIDER}$" \
 --format="value(state)")

if [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: GITHUB_REPOSITORY is empty. Re-run Step 1 before configuring the OIDC provider."
elif [ -z "${PROVIDER_STATE}" ]; then
 gcloud iam workload-identity-pools providers create-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --display-name="CodeMender GitHub Provider" \
   --issuer-uri="https://token.actions.githubusercontent.com" \
   --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
   --attribute-condition="assertion.repository == '${GITHUB_REPOSITORY}'" \
   --project="${PROJECT_ID}"
else
 [ "${PROVIDER_STATE}" = "DELETED" ] && gcloud iam workload-identity-pools providers undelete "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --project="${PROJECT_ID}"
 gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
   --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
   --location="global" \
   --issuer-uri="https://token.actions.githubusercontent.com" \
   --attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
   --attribute-condition="assertion.repository == '${GITHUB_REPOSITORY}'" \
   --no-disabled \
   --project="${PROJECT_ID}"
fi

Krok 7. Zezwól repozytorium GitHub na personifikowanie konta usługi

Powiąż rolę roles/iam.workloadIdentityUser, aby umożliwić tokenom pochodzącym z Twojego repozytorium podszywanie się pod konto usługi modułu uruchamiającego CI, i zweryfikuj powiązanie zasad:

# Retrieve the canonical Workload Identity Pool resource ID
export POOL_ID=$(gcloud iam workload-identity-pools describe "${WORKLOAD_IDENTITY_POOL}" \
 --project="${PROJECT_ID}" \
 --location="global" \
 --format="value(name)")

if [ -z "${POOL_ID}" ] || [ -z "${GITHUB_REPOSITORY}" ]; then
 echo "ERROR: POOL_ID ('${POOL_ID}') or GITHUB_REPOSITORY ('${GITHUB_REPOSITORY}') is empty. Re-run Step 1 and Step 5."
else
 # Bind Workload Identity User role to the principalSet of your repository
 gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_EMAIL}" \
   --project="${PROJECT_ID}" \
   --role="roles/iam.workloadIdentityUser" \
   --member="principalSet://iam.googleapis.com/${POOL_ID}/attribute.repository/${GITHUB_REPOSITORY}"

 # Verify the principalSet binding on the Service Account
 gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
   --project="${PROJECT_ID}"
fi

Krok 8. Pobierz wartości konfiguracji dla obiektów tajnych GitHuba

Pobierz pełną nazwę zasobu dostawcy tożsamości do Workload Identity i zapisz ją w zmiennej środowiskowej na potrzeby automatycznej rejestracji w następnym kroku:

# Retrieve full Workload Identity Provider name
export WORKLOAD_PROVIDER_NAME=$(gcloud iam workload-identity-pools providers describe ${WORKLOAD_IDENTITY_PROVIDER} \
 --workload-identity-pool=${WORKLOAD_IDENTITY_POOL} \
 --location="global" \
 --project=${PROJECT_ID} \
 --format="value(name)")

echo "=========================================================="
echo "WIF CONFIGURATION READY:"
echo "=========================================================="
echo "GCP_WORKLOAD_IDENTITY_PROVIDER: ${WORKLOAD_PROVIDER_NAME}"
echo "GCP_SERVICE_ACCOUNT:            ${SERVICE_ACCOUNT_EMAIL}"
echo "=========================================================="

5. Konfigurowanie obiektów tajnych repozytorium GitHub i uprawnień do przepływu pracy

Po udostępnieniu Google Cloud WIF skonfigurujesz obiekty tajne repozytorium GitHub i przyznasz niezbędne uprawnienia do przepływu pracy na potrzeby automatycznego skanowania zabezpieczeń i automatycznego naprawiania żądań pull.

Możesz skonfigurować te ustawienia bezpośrednio z Cloud Shell za pomocą interfejsu wiersza poleceń GitHuba (gh), co całkowicie eliminuje konieczność ręcznego kopiowania i wklejania długich nazw zasobów.

Krok 1. Ustaw obiekty tajne repozytorium za pomocą interfejsu wiersza poleceń GitHuba

W terminalu Cloud Shell uruchom te polecenia, aby bezpiecznie ustawić 2 wymagane obiekty tajne repozytorium za pomocą aktywnych zmiennych środowiskowych:

# 1. Set the Workload Identity Provider resource name
gh secret set GCP_WORKLOAD_IDENTITY_PROVIDER \
 --body "${WORKLOAD_PROVIDER_NAME}" \
 --repo "${GITHUB_REPOSITORY}"

# 2. Set the CI/CD Service Account email
gh secret set GCP_SERVICE_ACCOUNT \
 --body "${SERVICE_ACCOUNT_EMAIL}" \
 --repo "${GITHUB_REPOSITORY}"

# 3. Verify the secrets are registered
gh secret list --repo "${GITHUB_REPOSITORY}"

Krok 2. Przyznaj uprawnienia do przepływu pracy na potrzeby automatycznych PR

Domyślnie przepływy pracy GitHub Actions działają z uprawnieniami tylko do odczytu i nie mogą tworzyć żądań pull. W kroku 9 CodeMender samodzielnie wygeneruje i prześle zweryfikowane żądania pull dotyczące naprawy.

Przyznaj uprawnienia do zapisu i włącz tworzenie żądań pull bezpośrednio przez interfejs API GitHuba:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"

gh api \
 --method PUT \
 -H "Accept: application/vnd.github+json" \
 /repos/${GITHUB_REPOSITORY}/actions/permissions/workflow \
 -f default_workflow_permissions="write" \
 -F can_approve_pull_request_reviews=true

Krok 3. Wyłącz odziedziczone procesy Juice Shop

Rozwidlenie OWASP Juice Shop przenosi ponad 16 przepływów pracy CI (takich jak PR Compliance Check, CI/CD Pipeline i CodeQL Scan) wraz z szablonem PR współtwórcy, który automatycznie zamyka PR-y kierowane na master. Wyłącz wszystkie przepływy pracy inne niż CodeMender za pomocą interfejsu wiersza poleceń GitHub i usuń lokalnie pliki nadrzędne, aby rozwidlenie uruchamiało wyłącznie przepływy pracy CodeMender:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"

# 1. Disable all inherited non-CodeMender workflows in GitHub Actions (and CodeQL default setup if active)
for WF_ID in $(gh workflow list --all --limit 100 --repo "${GITHUB_REPOSITORY}" --json id,path \
 -q '.[] | select((.path | startswith(".github/workflows/")) and (.path | test("codemender-") | not)) | .id'); do
 gh workflow disable "${WF_ID}" --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
done
gh api -X PATCH "/repos/${GITHUB_REPOSITORY}/code-scanning/default-setup" \
 -f state=not-configured >/dev/null 2>&1 || true

# 2. Remove upstream workflow files and PR template from the local workspace
for f in .github/workflows/*; do
 case "$f" in *codemender-*) ;; *) rm -f "$f" ;; esac
done
rm -f .github/PULL_REQUEST_TEMPLATE.md

6. Tworzenie przepływu pracy automatycznego skanowania pod kątem luk w zabezpieczeniach za pomocą SARIF

W tym kroku utworzysz główny przepływ pracy ciągłego skanowania zabezpieczeń (.github/workflows/codemender-scan.yml), który uruchamia skanowanie bazowe w przypadku pushowania gałęzi, bramy różnicowe w przypadku żądań pull i eksporty SARIF do skanowania kodu w GitHubie.

Krok 1. Pobierz przepływ pracy skanowania CodeMender

Pobierz codemender-scan.yml z repozytorium początkowego do .github/workflows/:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
mkdir -p .github/workflows
curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-scan.yml \
 -o .github/workflows/codemender-scan.yml

Krok 2. Zatwierdź, wypchnij i uruchom skanowanie CI

Zatwierdź zmiany w przepływie pracy i wypchnij je bezpośrednio do gałęzi głównej repozytorium (master w przypadku Juice Shop lub main):

# Stage workflow changes, commit, and push to primary branch
git add -A .github
git commit -m "ci: add CodeMender SARIF security scanning workflow"
git push origin $(git branch --show-current)

W przeglądarce:

Przejdź do rozwidlonego repozytorium GitHub: https://github.com/YOUR_GITHUB_USER/juice-shop (np. https://github.com/octocat/juice-shop).

Na górnym pasku nawigacyjnym kliknij kartę Działania.

Na pasku bocznym po lewej stronie w sekcji Przepływy pracy wybierz Skanowanie zabezpieczeń CodeMender i eksportowanie SARIF.

Aktywuj lub wyświetl wykonanie przepływu pracy:

Automatyczne uruchamianie: jeśli na liście znajduje się automatyczne uruchomienie wywołane przez Twoje przesłanie, kliknij je bezpośrednio, aby monitorować wykonywanie na żywo.

Ręczne uruchamianie na żądanie (workflow_dispatch): jeśli nie rozpoczęto jeszcze żadnego uruchomienia, kliknij przycisk Uruchom przepływ pracy ▾ po prawej stronie, upewnij się, że wybrana jest gałąź Branch: master (pozostaw pole wyboru deep_scan niezaznaczone, aby uruchomić szybkie skanowanie bazowe --quick) i kliknij zielony przycisk Uruchom przepływ pracy.

Kliknij wykonywane uruchomienie i wybierz Autonomiczne skanowanie pod kątem luk w zabezpieczeniach kodu, aby obserwować uruchamianie przepływu pracy w czasie rzeczywistym.

Plik codemender-scan.yml: kierowanie skanowania na podstawie zdarzeń

Podczas gdy skanowanie bazowe --quick jest uruchamiane w chmurze (ok. 3–5 minut), sprawdź, jak codemender-scan.yml (linie 118–155) kieruje każde zdarzenie GitHuba do dedykowanego trybu skanowania w środowisku wykonawczym:

# Excerpt from .github/workflows/codemender-scan.yml
if [ "${{ github.event_name }}" = "pull_request" ]; then
 cm find . \
   --diff="origin/${{ github.base_ref }}" \
   --diff-workers=16 \
   --fail-on="CRITICAL,HIGH" \
   --sandbox=false --yes --bypass-warning || status=$?
elif [ "${{ github.event_name }}" = "schedule" ] || [ "${{ github.event.inputs.deep_scan }}" = "true" ]; then
 cm find . \
   --deep-workers=8 \
   --sandbox=false --yes --bypass-warning || status=$?
else
 cm find . \
   --quick \
   --sandbox=false --yes --bypass-warning || status=$?
fi

Konfiguracja wzmocnionego runnera ( wiersze 27–117): pomija niezaufane zewnętrzne forki i PR-y dependabot[bot], sprawdza za pomocą persist-credentials: false, zapisuje w pamięci podręcznej ~/.local/bin/cm i ~/.codemender/state.db oraz uruchamia cm health --strict przed wykorzystaniem modelu wykorzystania.

Headless Sandbox Boundaries (--sandbox=false --yes --bypass-warning): wyłącza izolację przestrzeni nazw użytkownika Linuksa (ograniczoną w kontenerach GitHub Actions bez uprawnień), zachowując wymuszanie granic ścieżki obszaru roboczego (project_paths) i command_policy.yaml.

Eksportowanie artefaktów i pliku SARIF chronionego kodem wyjścia ( wiersze 147–194): ustawia steps.scan.outputs.completed=true ściśle, gdy cm find kończy działanie z kodem 0 (czysto) lub 1 (osiągnięto próg --fail-on). Dzięki temu raporty SARIF (cm report -f sarif z ocenami ważności CVSS), tabele $GITHUB_STEP_SUMMARY (cm report -f md) i artefakty codemender-findings.json są nadal publikowane, gdy --fail-on blokuje PR. Eksportowanie jest pomijane w przypadku błędów konfiguracji lub pojemności (10–60), dzięki czemu puste pliki SARIF nigdy nie zamykają istniejących alertów.

7. Sprawdzanie alertów skanowania kodu i panelu zabezpieczeń na GitHubie

Po zakończeniu procesu pushowania punktu odniesienia GitHub przetwarza przesłany plik SARIF i wypełnia zarówno podsumowanie uruchomienia działań, jak i kartę Bezpieczeństwo repozytorium.

Krok 1. Sprawdź podsumowanie zadania natywnego w GitHub Actions

Każde uruchomienie przepływu pracy dołącza tabelę podsumowania w formacie Markdown (cm report -f md) bezpośrednio do podsumowania uruchomienia GitHub Actions:

W repozytorium GitHub kliknij kartę Actions (Działania).

Wybierz zakończone uruchomienie CodeMender Security Scan & SARIF Export (audyty push gałęzi bazowej kończą się zielonym znacznikiem wyboru ✅ po opublikowaniu wyników SARIF).

Przewiń w dół do sekcji 🛡️ CodeMender Security Scan Summary (Podsumowanie skanowania zabezpieczeń CodeMender), aby sprawdzić zestawienie wyników:

🔒 Raport CodeMender dotyczący bezpieczeństwa

Podsumowanie

Łączna liczba wyników: 28

Waga

Liczba

🔴 KRYTYCZNE

6

🟠 WYSOKI

16

🟡 ŚREDNI

6

Stan

Liczba

🔴 OTWÓRZ

28

Wyniki

Identyfikator

Waga

Poufność

Stan

Rozwiąż problem

Plik

Tytuł

c1b96b9a

🔴 KRYTYCZNE

100%

OTWÓRZ

–

routes/userProfile.ts

Zdalne wykonywanie kodu przez wstrzyknięcie kodu po stronie serwera w profilu użytkownika

cd47b38a

🔴 KRYTYCZNE

100%

OTWÓRZ

–

routes/login.ts

Wstrzyknięcie kodu SQL w ścieżce uwierzytelniania użytkownika

a47a9e45

🔴 KRYTYCZNE

100%

OTWÓRZ

–

routes/b2bOrder.ts

Zdalne wykonanie kodu przez ucieczkę z piaskownicy w procesie przetwarzania zamówień B2B

Krok 2. Zapoznaj się ze scentralizowanym panelem skanowania kodu

Na górnym pasku nawigacyjnym repozytorium GitHub kliknij kartę Security and quality (Bezpieczeństwo i jakość) lub Security (Bezpieczeństwo).

Na pasku bocznym po lewej stronie w sekcji Wyniki wybierz Skanowanie kodu.

Jeśli aktywnych jest kilka narzędzi, przefiltruj Narzędzie do CodeMender (is:open branch:master tool:CodeMender), aby sprawdzić alerty zmapowane z natywnymi plakietkami ważności CVSS:

Plakietka poziomu ważności

Vulnerability Headline

Wykryta lokalizacja

Branch

🔴 Krytyczny

Zdalne wykonywanie kodu przez wstrzyknięcie kodu po stronie serwera w profilu użytkownika

routes/userProfile.ts:58

master

🔴 Krytyczny

Wstrzyknięcie kodu SQL w ścieżce uwierzytelniania użytkownika

routes/login.ts:34

master

🔴 Krytyczny

Zdalne wykonanie kodu przez ucieczkę z piaskownicy w procesie przetwarzania zamówień B2B

routes/b2bOrder.ts:21

master

Kliknij Wstrzyknięcie kodu SQL w ścieżce uwierzytelniania użytkownika (routes/login.ts:34), aby sprawdzić przepływ skażonych danych i analizę głównych przyczyn wygenerowaną przez Gemini.

8. Blokowanie niebezpiecznego żądania pull za pomocą skanowania różnicowego

Skanowanie podstawowe wykryło 28 istniejących wcześniej luk w zabezpieczeniach w aplikacji OWASP Juice Shop. W przypadku tradycyjnych analizatorów statycznych te 28 starszych wyników powodowałoby niepowodzenie każdego przyszłego żądania pull, dopóki nie zostałby naprawiony cały backlog, co zmusiłoby zespoły do wyłączenia blokowania scalania.

Teraz przetestujesz bramkę AST różnic PR (--diff + --fail-on="CRITICAL,HIGH") CodeMender w działaniu: otworzysz żądanie pull, które wprowadza nową lukę w zabezpieczeniach, i zobaczysz, jak CodeMender izoluje delta, blokuje scalanie w ciągu ok. 15–25 sekund i dodaje adnotacje do dokładnie tych linii, które powodują błąd.

Krok 1. Otwórz żądanie pull, które wprowadza błąd wstrzykiwania poleceń

W Cloud Shell (w sklonowanym obszarze roboczym repozytorium) utwórz gałąź funkcji, dodaj nową trasę Express zawierającą lukę w zabezpieczeniach polegającą na wstrzykiwaniu poleceń systemu operacyjnego i otwórz żądanie Pull Request w rozwidleniu:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"
PRIMARY_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')

# Reset any previous demo PR/branch so this step can be re-run cleanly
gh pr close feat/diagnostics --repo "${GITHUB_REPOSITORY}" --delete-branch 2>/dev/null || true
git checkout "${PRIMARY_BRANCH}"
git checkout -B feat/diagnostics

# Introduce an Express endpoint vulnerable to OS Command Injection (CWE-78)
cat << 'EOF' > routes/diagnostics.ts
import { execSync } from 'node:child_process'
import { type Request, type Response } from 'express'

export function systemDiagnostics () {
 return (req: Request, res: Response) => {
   const host = String(req.query.host ?? '127.0.0.1')
   const output = execSync(`ping -c 1 ${host}`).toString()
   res.status(200).json({ status: 'ok', output })
 }
}
EOF

git add routes/diagnostics.ts
git commit -m "feat: add network diagnostics endpoint"
git push -f -u origin feat/diagnostics

gh pr create \
 --repo "${GITHUB_REPOSITORY}" \
 --base "${PRIMARY_BRANCH}" \
 --head feat/diagnostics \
 --title "feat: add network diagnostics endpoint" \
 --body "Adds a ping diagnostics handler."

Krok 2. Sprawdź bramkę scalania różnicowego i adnotację wbudowaną w żądaniu pull

Otwórz adres URL żądania pull wyświetlony na końcu danych wyjściowych terminala.

Przewiń do pola Checks (Sprawdzenia) u dołu strony rozmowy dotyczącej żądania pull i obserwuj Autonomous Code Vulnerability Scan (Autonomiczne skanowanie kodu pod kątem luk w zabezpieczeniach):

Szybkość Delta: zamiast skanować wszystkie ponad 680 plików w repozytorium (ok. 3–5 minut), cm find . --diff="origin/${PRIMARY_BRANCH}" ogranicza analizę wyłącznie do routes/diagnostics.ts (i wszystkich wywołujących w odległości 1 skoku), dzięki czemu skanowanie trwa ok. 15–25 sekund.

Izolacja starszego długu i blokowanie scalania: żadna z 28 niezmienionych starszych luk w zabezpieczeniach Juice Shop nie powoduje niepowodzenia testu – tylko nowo wprowadzona luka CRITICAL Command Injection wywołuje --fail-on="CRITICAL,HIGH", kończąc działanie z kodem stanu 1 (czerwony ❌), aby zablokować scalanie PR.

U góry żądania pull kliknij kartę Files changed (Zmienione pliki):

Ponieważ zabezpieczenie kodu wyjściowego przepływu pracy (steps.scan.outputs.completed == 'true') nadal eksportuje i przesyła results.sarif, gdy --fail-on kończy działanie z kodem 1, GitHub Code Scanning renderuje adnotację zabezpieczeń CodeMender – krytyczne bezpośrednio pod execSync w routes/diagnostics.ts.

Krok 3. Wyczyść testowe żądanie pull i wróć do gałęzi głównej

Zanim przejdziesz do samodzielnej naprawy, przełącz obszar roboczy Cloud Shell z powrotem na gałąź główną i zamknij niebezpieczne żądanie pull:

[ -d .git ] || cd ~/"${GITHUB_REPO:-juice-shop}"
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-$(git remote get-url origin 2>/dev/null | sed -E 's#^.*github\.com[:/]##; s#\.git$##')}"
PRIMARY_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD | sed 's@^origin/@@')
git checkout "${PRIMARY_BRANCH}"
gh pr close feat/diagnostics --repo "${GITHUB_REPOSITORY}" --delete-branch
git branch -D feat/diagnostics 2>/dev/null || true

9. Tworzenie przepływu pracy autonomicznej naprawy i automatycznego PR

Teraz, gdy bramka żądania pull zapobiega wprowadzaniu nowych luk w zabezpieczeniach do bazy kodu, wdrożysz Autonomous Remediation (.github/workflows/codemender-remediate.yml), aby aktywnie naprawiać istniejące luki w zabezpieczeniach i otwierać żądania pull gotowe do sprawdzenia.

Krok 1. Pobierz plik przepływu pracy działań naprawczych

CodeMender udostępnia 2 szablony naprawy w zależności od widoczności repozytorium:

Publiczne repozytoria / repozytoria open source (codemender-remediate.yml): tryb odpowiedzialnego ujawniania – linki do alertów SARIF skanowania kodu na GitHubie bez publicznego ujawniania nieprzetworzonych wektorów exploitów.

Repozytoria prywatne / firmowe (codemender-remediate-private-repo.yml): tryb dowodów audytu wewnętrznego – umieszcza artefakty weryfikacji (PLAN.md, REPORT.md, exploit.sh) w zwijanych sekcjach żądań pull, wykluczając je z zatwierdzeń Git.

Pobierz do repozytorium przepływ pracy naprawy bezpieczny dla publicznego dostępu:

mkdir -p .github/workflows
curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-remediate.yml \
 -o .github/workflows/codemender-remediate.yml

Krok 2. Zatwierdź i uruchom autonomiczny przepływ pracy naprawy

Zatwierdź i wypchnij przepływ pracy dotyczący działań naprawczych do gałęzi głównej:

git add .github/workflows/codemender-remediate.yml
git commit -m "ci: add CodeMender autonomous remediation workflow"
git push origin $(git branch --show-current)

W przeglądarce otwórz kartę Actions (Działania) w repozytorium GitHub.

Na pasku bocznym po lewej stronie w sekcji Przepływy pracy wybierz Autonomiczne usuwanie zagrożeń i automatyczne PR CodeMender.

Po prawej stronie kliknij zielone menu Uruchom przepływ pracy:

Use workflow from (Użyj przepływu pracy z): upewnij się, że wybrana jest gałąź domyślna (master).

Identyfikator konkretnego wyniku lub prefiks do naprawienia: wpisz 8-znakowy prefiks dla routes/login.ts zanotowany w kroku 7 (na przykład cd47b38a). Pozostawienie tego pola pustego spowoduje uruchomienie zbiorczej naprawy wszystkich otwartych wyników o priorytecie krytycznym i wysokim (~10–15 minut). Naprawa pojedynczego identyfikatora trwa ~45–60 sekund.

Kliknij zielony przycisk Uruchom przepływ pracy w wyskakującym okienku i otwórz uruchomiony proces.

Uruchom przepływ pracy CodeMender Autonomous Security Remediation za pomocą menu Uruchom przepływ pracy.

W pliku codemender-remediate.yml: autonomiczna synteza poprawek

Podczas gdy CodeMender syntetyzuje poprawkę w chmurze (ok. 30–45 sekund), sprawdź, jak codemender-remediate.yml (linie 111–184) koordynuje naprawę w środowisku wykonawczym:

Wznawianie bez skanowania (cm report import): pobiera artefakt codemender-findings.json z przepływu pracy skanowania i importuje go do obszaru roboczego (cm report import -f codemender-findings.json), wracając do cm find . --quick tylko wtedy, gdy nie ma wcześniejszego artefaktu.

Synteza poprawek bez interfejsu (cm fix): przypina project_paths do $GITHUB_WORKSPACE, przekazuje < /dev/null, aby zapobiec interaktywnym zawieszeniom, i przekazuje --no-reset podczas pętli wsadowych, aby skumulowane poprawki były zachowywane w różnych wynikach:

# Executed inside the GitHub Actions runner (codemender-remediate.yml)
cm fix "${SPECIFIC_TARGET}" --sandbox=false --yes --bypass-warning < /dev/null

Clean Production Commits ( wiersze 155–252): usuwa .cm_project, .exploit/ i pliki tymczasowe za pomocą .git/info/exclude, zanim peter-evans/create-pull-request@v8 otworzy gałąź (codemender/auto-remediation-${{ github.run_id }}), zatwierdzając wyłącznie zmiany w kodzie produkcyjnym:

--- a/routes/login.ts
+++ b/routes/login.ts
@@ -28,8 +28,8 @@ module.exports = function login () {
-    models.sequelize.query(`SELECT * FROM Users WHERE email = '${req.body.email || ''}' AND password = '${security.hash(req.body.password || '')}' AND deletedAt IS NULL`, { model: models.User })
+    models.sequelize.query('SELECT * FROM Users WHERE email = :email AND password = :password AND deletedAt IS NULL', {
+      replacements: { email: req.body.email || '', password: security.hash(req.body.password || '') },
+      model: models.User
+    })

Krok 3. Przejrzyj nowo otwarte żądanie pull na GitHubie

Otwórz kartę Pull requests (Żądania pull) w repozytorium i otwórz nowe żądanie pull (np. 🛡️ [CodeMender] Fix: SQL Injection in User Authentication Route).

Kliknij Files changed (Zmienione pliki), aby potwierdzić, że zmodyfikowano tylko plik routes/login.ts i że nie zawiera on żadnych wewnętrznych metadanych środowiska wykonawczego.

Sprawdź opis PR, który zawiera link bezpośrednio do alertu GitHub Code Scanning (SARIF), aby uzyskać zgodę opiekuna.

10. Rozwiązywanie problemów z przypadkami skrajnymi i repozytoriami prywatnymi

Prywatne repozytoria bez GitHub Advanced Security (GHAS)

Publiczne repozytoria GitHub otrzymują bezpłatne, nieograniczone przetwarzanie SARIF w ramach skanowania kodu w GitHubie. Jeśli jednak wdrożysz ten przepływ pracy w prywatnym repozytorium Enterprise, które nie ma aktywnej licencji GitHub Advanced Security (GHAS), krok upload-sarif zakończy się niepowodzeniem i wyświetli się komunikat:

HTTP 403: Advanced Security must be enabled for this repository to use code scanning.

Rozwiązanie: zastępczy samodzielny interaktywny raport HTML

Wbudowany w CodeMender generator raportów HTML (cm report -f html) tworzy samodzielny, interaktywny panel zabezpieczeń z kartami danych o poziomie ważności, fragmentami kodu z wyróżnioną składnią i numerami wierszy oraz wbudowaną przeglądarką różnic poprawek bez żadnych zewnętrznych zależności internetowych.

Aby obsługiwać prywatne repozytoria bez licencji GHAS, zaktualizuj .github/workflows/codemender-scan.yml, aby archiwizować artefakt raportu HTML zamiast przesyłać SARIF:

Wygeneruj samodzielny raport HTML: w kroku Export Security Reports & Publish Job Summary wyeksportuj panel HTML wraz z podsumowaniem w formacie Markdown za pomocą cm report -f html > codemender-audit-report.html.

Zarchiwizuj raport jako artefakt przepływu pracy: zastąp krok Upload SARIF Report to GitHub Code Scanning (github/codeql-action/upload-sarif@v4) krokiem actions/upload-artifact@v4 skonfigurowanym do przesyłania codemender-audit-report.html (na przykład pod nazwą artefaktu codemender-security-report).

Sprawdzanie lokalnie w dowolnej przeglądarce: pobierz plik codemender-security-report.zip bezpośrednio ze strony podsumowania uruchomienia przepływu pracy w GitHub Actions, wyodrębnij go i otwórz plik codemender-audit-report.html w dowolnej przeglądarce, aby przeprowadzić wizualną analizę.

Autonomiczne naprawianie prywatnego repozytorium z wbudowanymi dowodami kontroli

W prywatnych repozytoriach firmowych zespoły inżynierów i ds. bezpieczeństwa potrzebują pełnego wglądu w analizę głównej przyczyny, dowód koncepcji exploita i plan naprawczy bez konieczności korzystania z paneli narzędzi zewnętrznych. Jednak zatwierdzanie skryptów wykorzystujących luki w zabezpieczeniach (exploit.sh) lub wewnętrznych plików Markdown (PLAN.md, LOG.md) w gałęzi repozytorium zaśmieca historię Gita i może powodować fałszywe alerty z innych skanerów zabezpieczeń.

Aby rozwiązać ten problem, wdróż specjalny przepływ pracy naprawy prywatnego repozytorium (codemender-remediate-private-repo.yml):

curl -fsSL https://raw.githubusercontent.com/edwardc-gcp/codemender-github-actions/main/.github/workflows/codemender-remediate-private-repo.yml \
 -o .github/workflows/codemender-remediate.yml
git add .github/workflows/codemender-remediate.yml
git commit -m "ci: switch to private repository remediation workflow with embedded audit evidence"
git push origin $(git branch --show-current)

Jak działa naprawa prywatnego repozytorium

Dynamiczna weryfikacja PoC (cm verify): syntetyzuje i testuje działający exploit przed wygenerowaniem poprawki, aby potwierdzić możliwość wykorzystania luki w zabezpieczeniach. Automatycznie pomija cm fix, jeśli weryfikacja oznaczy wynik jako DISMISSED.

Wbudowane zwijane bloki kontroli żądania pull: wyodrębnia REPORT.md, PLAN.md i exploit.sh do /tmp/codemender-evidence/ i formatuje je bezpośrednio w opisie żądania pull wewnątrz <details open> zwijanych bloków, aby umożliwić weryfikatorowi sprawdzenie jednym kliknięciem.

Archiwizacja artefaktów: archiwizuje cały folder dowodów za pomocą actions/upload-artifact@v4.

Pristine Git Commits: usuwa wszystkie metadane środowiska wykonawczego i katalogi .exploit, dzięki czemu zatwierdzenie gita żądania pull zawiera wyłącznie zmiany w kodzie produkcyjnym.

Lista kontrolna rozwiązywania problemów z federacją tożsamości zadań (WIF)

Domyślnie google-github-actions/auth@v2 zapisuje lokalny plik konfiguracji sfederowanych danych uwierzytelniających podczas konfiguracji, a rzeczywista wymiana tokenów OAuth 2.0 następuje po uruchomieniu cm health --strict lub cm find. Aby zdiagnozować błędy uwierzytelniania HTTP 400 lub HTTP 403, skorzystaj z poniższej listy kontrolnej:

Objaw błędu

Typowa główna przyczyna

Weryfikacja i naprawa

HTTP 403 (odmowa dostępu do iam.serviceAccounts.getAccessToken)

Brak powiązania roles/iam.workloadIdentityUser na koncie usługi, nieprawidłowy obiekt tajny GCP_SERVICE_ACCOUNT lub usługa iamcredentials.googleapis.com nie jest włączona.

Sprawdź, czy GCP_SERVICE_ACCOUNT pasuje do codemender-ci-runner@.iam.gserviceaccount.com, i uruchom poniżej sprawdzanie zasad uprawnień, aby zweryfikować powiązanie principalSet.

HTTP 400 (unauthorized_client lub odrzucony warunek atrybutu)

Nazwa (lub wielkość liter) repozytorium OIDC –attribute-condition nie pasuje do repozytorium GitHub, które aktywuje przepływ pracy, lub dostawca WIF jest wyłączony.

Ponownie wykonaj krok 4 (kroki 1 i 6), upewniając się, że ${GITHUB_REPOSITORY} dokładnie odpowiada wielkości liter w owner/repo na GitHubie i że zastosowano –no-disabled.

HTTP 400 (invalid_grant podczas wymiany tokenów)

Nieprawidłowo sformatowane mapowanie –issuer-uri lub brak mapowania attribute.repository=assertion.repository u dostawcy OIDC.

Sprawdź, czy parametr –issuer-uri jest ustawiony dokładnie na https://token.actions.githubusercontent.com (bez ukośnika na końcu).

Przejściowy błąd HTTP 403 natychmiast po konfiguracji

Rozpowszechnianie globalnych uprawnień uprawnień i federacji tożsamości zadań w nowo utworzonych powiązaniach może potrwać 1–5 minut.

Zaczekaj 1–2 minuty i kliknij Re-run failed jobs (Uruchom ponownie nieudane zadania) w GitHub Actions.

Aby sprawdzić aktywne powiązanie Workload Identity na koncie usługi CI/CD w Cloud Shell, uruchom:

gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" \
 --flatten="bindings[].members" \
 --filter="bindings.role=roles/iam.workloadIdentityUser"

Sprawdź, czy dane wyjściowe wiążą roles/iam.workloadIdentityUser z principalSet://iam.googleapis.com/<POOL_ID>/attribute.repository/<GITHUB_USER>/<GITHUB_REPO>:

---
bindings:
 members: principalSet://iam.googleapis.com/.../attribute.repository/<OWNER>/<REPO>
 role: roles/iam.workloadIdentityUser

Rozwiązywanie problemów z kodem wyjścia interfejsu wiersza poleceń i kontrolą wstępną CI/CD

Polecenia CodeMender (cm health --strict, cm find, cm verify i cm fix) zwracają deterministyczne kody wyjścia, dzięki czemu potoki CI/CD mogą natychmiast odróżnić wyniki dotyczące bezpieczeństwa od błędów konfiguracji lub usługi:

Kod wyjścia

Kategoria

Typowe główne przyczyny i sposoby ich usunięcia

0

Sukces

Kontrole stanu zakończyły się pomyślnie lub skanowanie zakończyło się bez wyników blokujących.

1

Wyniki / Ogólne

–fail-on wykrył luki w zabezpieczeniach CRITICAL lub HIGH blokujące PR (oczekiwany błąd bramki scalania).

10

credentials

Nie udało się wymienić tokena OAuth/ADC w ramach federacji tożsamości zadań (400/401). Sprawdź GCP_WORKLOAD_IDENTITY_PROVIDER, GCP_SERVICE_ACCOUNT i powiązanie roles/iam.workloadIdentityUser powyżej.

20

config

Nieprawidłowa składnia .codemender/config.yaml lub ~/.codemender/config.yaml.

30

reachability

Runner nie może połączyć się z aiplatform.googleapis.com (DNS, serwer proxy, przerwa w działaniu usługi lub ustawienia usługi VPC).

40

authorization

Konto usługi nie ma uprawnień roles/aiplatform.user w projekcie docelowym lub usługa cloudresourcemanager.googleapis.com / aiplatform.googleapis.com jest wyłączona.

50

timeout

Kontrola wstępna cm health przekroczyła 30-sekundowy limit czasu.

60

capacity

Agent osiągnął limit równoczesnych aktywnych zadań. Uruchom ponownie przepływ pracy po krótkiej przerwie.

Informacje o dodatkowych błędach środowiska wykonawczego, takich jak błąd rozpoznawania gałęzi podstawowej Git diff (fetch-depth: 0), opóźnienia propagacji zasobów czy uprawnienia do tworzenia żądań pull w GitHub Actions, znajdziesz w oficjalnym przewodniku po rozwiązywaniu problemów z CI/CD w CodeMender.

11. Czyszczenie zasobów

Aby zapobiec dalszemu zużywaniu zasobów lub wyczyścić konfiguracje testowe w środowiskach Google Cloud i GitHub, wykonaj te czynności.

Krok 1. Usuń obiekty tajne repozytorium GitHub i wyłącz przepływy pracy za pomocą interfejsu wiersza poleceń gh

Użyj interfejsu wiersza poleceń GitHuba (gh), aby usunąć obiekty tajne działań w repozytorium i wyłączyć przepływy pracy CodeMender:

# Delete the repository Actions secrets
gh secret delete GCP_WORKLOAD_IDENTITY_PROVIDER --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh secret delete GCP_SERVICE_ACCOUNT --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true

# Disable the CodeMender workflows to prevent unwanted automatic triggers
gh workflow disable codemender-scan.yml --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true
gh workflow disable codemender-remediate.yml --repo "${GITHUB_REPOSITORY}" 2>/dev/null || true

Krok 2. Wyłącz lub usuń zasoby federacji tożsamości zadań Google Cloud

Pule tożsamości zadań, dostawcy i konta usługi nie generują żadnych kosztów w stanie bezczynności, gdy nie wymieniają tokenów. Wybierz tryb czyszczenia, który pasuje do Twojego przepływu pracy:

Opcja A – wstrzymanie dostępu (zalecane, jeśli planujesz ponowne uruchomienie w tym projekcie): natychmiast wyłącza wymianę tokenów OIDC bez wywoływania 30-dniowego okresu przechowywania po usunięciu nietrwałym w Google Cloud IAM ani opóźnień propagacji konta usługi uniqueId:

gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --disabled \
 --project="${PROJECT_ID}"

Opcja B – pełne usunięcie: usuwa dostawcę WIF, pulę (zachowaną w stanie DELETED przez 30 dni) i dedykowane konto usługi:

# Delete Workload Identity Provider
gcloud iam workload-identity-pools providers delete "${WORKLOAD_IDENTITY_PROVIDER}" \
 --workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --project="${PROJECT_ID}" \
 --quiet

# Delete Workload Identity Pool
gcloud iam workload-identity-pools delete "${WORKLOAD_IDENTITY_POOL}" \
 --location="global" \
 --project="${PROJECT_ID}" \
 --quiet

# Delete CI/CD Service Account
gcloud iam service-accounts delete "${SERVICE_ACCOUNT_EMAIL}" \
 --project="${PROJECT_ID}" \
 --quiet

12. Gratulacje

Gratulacje! Udało Ci się ukończyć ćwiczenie z programowania Zabezpieczanie potoku CI/CD za pomocą CodeMender.

Udało Ci się zaprojektować, utworzyć i zautomatyzować potok DevSecOps klasy produkcyjnej w modelu „zero zaufania” przy użyciu federacji tożsamości zadań Google Cloud, CodeMender i GitHub Actions.

Omówione zagadnienia

Uwierzytelnianie bez kluczy w modelu Zero Trust: wyeliminowaliśmy ryzykowne, długotrwałe klucze JSON kont usługi, wiążąc efemeryczne tokeny OIDC GitHuba z uprawnieniami Google Cloud za pomocą federacji tożsamości zadań (WIF).

Skanowanie AST różnicowe PR i eliminowanie starszego szumu: ciągłe skanowanie w zakresie zmodyfikowanych plików i zależności (--diff="origin/$BASE_REF"), izolowanie starszego długu technicznego ([LEGACY / UNTOUCHED]) w celu utrzymania pętli informacji zwrotnych od deweloperów poniżej 15 sekund.

Raporty w wielu formatach i natywne podsumowania zadań: połączony format OASIS SARIF v2.1.0 do scentralizowanego skanowania kodu w GitHubie z natywnym formatem Markdown (cm report -f md >> $GITHUB_STEP_SUMMARY) zapewniającym natychmiastową widoczność dla kadry kierowniczej bezpośrednio na stronach uruchamiania przepływu pracy CI.

Autonomiczne naprawianie z udziałem człowieka: przeszliśmy od pasywnych powiadomień o alertach do aktywnych potoków naprawczych, które autonomicznie syntetyzują proponowane poprawki kodu, weryfikują je pod kątem zestawów testów regresyjnych i otwierają żądania pull request z artefaktami kontrolnymi do zatwierdzenia przez inżyniera.

Automatyczne bramki jakości: wprowadziliśmy rygorystyczną ochronę gałęzi i bramki scalania (--fail-on), aby zapobiec przedostawaniu się niebezpiecznych luk w zabezpieczeniach do środowiska produkcyjnego.

Przenoszenie stanu oparte na artefaktach i izolacja obszaru roboczego: wyniki były bezproblemowo przenoszone między zadaniami CI za pomocą cm report import, a .git/info/exclude służyło do zachowania nienaruszonej historii Git i zapobiegania wyciekom danych logowania.

Zmiana sposobu myślenia deweloperów

Tradycyjna praktyka DevSecOps

Autonomiczny potok CI/CD CodeMender

Pasywne zrzucanie alertów: skanery wyświetlają nieprzetworzone logi terminala lub statyczne listy błędów, przenosząc cały ciężar analizy na deweloperów.

Aktywny współtwórca: syntetyzuje zweryfikowane poprawki kodu i otwiera gotowe do scalenia żądania pull, które inżynier może zatwierdzić.

Wysoki odsetek wyników fałszywie pozytywnych: heurystyka statycznego testowania AST wykrywa tysiące teoretycznych luk w zabezpieczeniach bez dowodu na możliwość ich wykorzystania.

2-poziomowa weryfikacja exploitów: dynamiczne generowanie testów w piaskownicy (cm verify) potwierdza rzeczywistą lukę w zabezpieczeniach, eliminując fałszywe alarmy.

Ryzykowne przechowywanie obiektów tajnych: długotrwałe klucze JSON kont usługi przechowywane w obiektach tajnych CI mogą zostać przypadkowo ujawnione i rozprzestrzenione.

Zero-Trust WIF: uwierzytelnianie bez kluczy za pomocą tymczasowych tokenów OIDC wymienianych na żądanie z Google Cloud STS.

Monolityczne ponowne skanowanie: każde zatwierdzenie powoduje pełną kontrolę repozytorium, co opóźnia przepływy pracy CI i marnuje drogie tokeny.

Kierowanie AST na podstawie zdarzeń: żądania pull wykonują 15-sekundowe różnicowe skanowania AST (–diff), a zadania cron przeprowadzają szczegółowe audyty.

Zanieczyszczona historia repozytorium: tymczasowe skrypty wykorzystujące luki w zabezpieczeniach i logi ataków zatwierdzone bezpośrednio w gałęziach repozytorium.

Higiena obszaru roboczego w firmie: dowody ataku są umieszczane w opisach PR i artefaktach przepływu pracy, co pozwala zachować czystość zatwierdzeń kodu.

Dalsze kroki

🚀 Kontynuuj naukę o CodeMender:

Część 1. Zabezpieczanie aplikacji za pomocą CodeMender – dowiedz się, jak samodzielnie wykrywać luki w zabezpieczeniach repozytorium, weryfikować exploity PoC i syntetyzować lokalne poprawki.

Shift Left Locally & Serverless Cloud Native CI/CD: zapoznaj się z przykładowymi implementacjami w oficjalnym przewodniku po CI/CD dla Google Cloud Build (cloudbuild.yaml) i Local Git Pre-commit Hooks (cm find . --diff --staged).

📖 Zapoznaj się z dokumentacją i materiałami:

Oficjalny przewodnik po integracji CodeMender z CI/CD w Google Cloud

Oficjalna dokumentacja Google Cloud CodeMender

Repozytorium szablonów startowych działań na GitHubie CodeMender

Dokumentacja federacji tożsamości zadań w Google Cloud

💡 Zastosuj do własnych repozytoriów:

Utwórz rozwidlenie początkowego przepływu pracy i zabezpiecz repozytoria Pythona, Go, Javy, Rusta i Node.js w swojej organizacji za pomocą CodeMender.