1. Подготовка
Добро пожаловать на практическую работу Защита конвейера CI/CD с помощью CodeMender.
В современной разработке ПО инструменты статического анализа, такие как CodeQL, необходимы для выявления известных синтаксических шаблонов. Однако они часто пропускают уязвимости, скрытые глубоко в бизнес-логике, и генерируют множество непроверенных оповещений.
CodeMender (исполняемый файл CLI: cm) улучшает конвейер CI/CD, работая вместе с существующими инструментами SAST. Он развертывает агенты логического анализа безопасности на базе Gemini от Google, чтобы:
Обнаружение сложных ошибок в бизнес-логике. Анализ контекста приложения и архитектурных потоков данных, выходящий за рамки жестких статических правил шаблонов.
Значительное сокращение ложных срабатываний за счет проверки на уязвимости. Динамически доказывайте возможность использования уязвимостей в изолированных средах, прежде чем оповещать разработчиков.
Автономно устранять подтвержденные проблемы. Создавать исправления кода, проверять их с помощью наборов тестов, чтобы предотвратить регрессии, и отправлять готовые к проверке pull-запросы.
В этой практической работе вы интегрируете CodeMender в хранилище OWASP Juice Shop с помощью GitHub Actions и федерации Workload Identity Google Cloud (WIF) без ключей.
Требования
- Рекомендуется: базовое понимание принципов работы CodeMender (рассматривается в курсе Защита приложений с помощью CodeMender).
- Базовое понимание рабочих процессов, триггеров и синтаксиса YAML в GitHub Actions.
- Базовые знания о командах Git и рабочих процессах проверки pull-запросов.
- Базовые знания о концепциях Google Cloud IAM (сервисные аккаунты, роли и API).
- Знание распространенных уязвимостей веб-приложений (например, внедрение SQL-кода и XSS).
Что вы узнаете
- Как настроить аутентификацию без ключа с нулевым доверием между GitHub Actions и Google Cloud с помощью Workload Identity Federation (WIF)
- Как создать автоматизированный рабочий процесс поиска уязвимостей с помощью CodeMender и
gemini-3.8-flash - Как публиковать отчеты о безопасности, на основе которых можно принимать меры, используя OASIS SARIF v2.1.0 и встроенные сводки заданий GitHub Actions.
- Как создать автономный рабочий процесс исправления, который генерирует проверенные тестами исправления кода и открывает Pull-запросы для проверки специалистом.
- Как применять автоматизированные жесткие ограничения качества (
--fail-on) и кеширование конвейера для высокоскоростной непрерывной безопасности
Что вам понадобится
- Проект Google Cloud с включенными платежными функциями и разрешениями владельца или редактора проекта.
- Аккаунт GitHub с разрешениями на создание репозиториев, настройку Секретов и управление действиями (на шаге 3 вы создадите ответвление репозитория OWASP Juice Shop GitHub с помощью GitHub CLI).
2. Архитектура непрерывной интеграции и развертывания CodeMender
В современных корпоративных DevSecOps безопасность на основе искусственного интеллекта не может быть просто ручным инструментом для настольных компьютеров. Он должен работать как автоматизированный привратник (блокировать небезопасные pull-запросы) и автономный соразработчик (предлагать проверенные исправления непосредственно в Git).
Для этого вы реализуете архитектуру с двумя рабочими процессами на основе федерации Workload Identity Google Cloud (WIF) и моделей рассуждения Gemini Enterprise.
Архитектура с двумя рабочими процессами

Вместо того чтобы объединять обнаружение и устранение в один монолитный скрипт, конвейер разделяет безопасность на два отдельных специализированных рабочих процесса:
Рабочий процесс | Основной триггер | Основные обязанности | Строгие требования к качеству |
1. Сканер уязвимостей( | Pull-запросы, основные пуши, еженедельный cron, отправка вручную | • Быстрое дифференциальное сканирование AST в запросах на извлечение (около 15 секунд), быстрое базовое сканирование при отправке ( | Блокирует слияние запросов на извлечение, если обнаружены новые уязвимости высокого или критического уровня ( |
2. Автономный инструмент устранения неполадок( | Запуск вручную ( | • Возобновляет работу с артефактами сканирования ( | Обеспечивает чистые различия в рабочей среде перед открытием PR. |
Три основных принципа проектирования корпоративных систем
При создании этих рабочих процессов в следующих разделах помните о трех основных принципах архитектуры:
🔑 Аутентификация без ключа с нулевым доверием и предварительная проверка
В GitHub Secrets не хранятся долгосрочные JSON-ключи сервисного аккаунта Google Cloud. Исполнитель генерирует кратковременный токен OIDC, который обменивается через Google Cloud STS на временные учетные данные, действующие в течение часа, устанавливает persist-credentials: false для извлечений Git и запускает cm health --strict, чтобы проверить учетные данные, сетевую доступность и разрешения IAM, прежде чем использовать квоту модели.
⚡ Адаптивная маршрутизация сканирования и устаревшее шумоподавление
Вместо того чтобы выполнять медленные полные проверки репозитория для каждого pull-запроса, CodeMender направляет каждое событие непрерывной интеграции в оптимальный режим сканирования. Pull-запросы запускают дифференциальный анализ AST (--diff="origin/$BASE_REF") измененных файлов и вызывающих объектов за один шаг менее чем за 15 секунд. При отправке в основную ветку выполняются быстрые базовые сканирования за один сеанс (--quick). По еженедельному расписанию запускаются параллельные глубокие проверки каждого файла (по умолчанию cm find .). Существующие уязвимости базы кода, не затронутые pull-запросом, помечаются как [LEGACY / UNTOUCHED]. Они отображаются в отчетах SARIF, но не блокируют слияние pull-запроса и не запускают автоматическое исправление.
🛡️ Надежная неблокирующая наблюдаемость безопасности
Даже если --fail-on завершает работу с кодом 1, чтобы заблокировать небезопасный запрос на извлечение, защита экспорта отчетов и загрузки SARIF с помощью steps.scan.outputs.completed == 'true' и hashFiles('results.sarif') != '' гарантирует, что оповещения OASIS SARIF и сводки заданий по-прежнему будут публиковаться. При этом экспорт и загрузка будут пропущены, если выполнение отменено или прервано из-за ошибки настройки или емкости (10–60).
3. Выполните аутентификацию и подготовьте целевое хранилище в Cloud Shell
Чтобы настроить аутентификацию без ключа и запустить автоматизированные конвейеры безопасности, вам нужен доступный целевой репозиторий GitHub, которым вы владеете. В этой практической работе вы будете использовать OWASP Juice Shop – веб-приложение Node.js, в котором намеренно оставлены уязвимости, – в качестве готовой среды для тестирования безопасности.
Вы будете использовать интерфейс командной строки GitHub (gh), предустановленный в Google Cloud Shell, чтобы выполнить аутентификацию в GitHub, автоматически получить сведения о пользователе и подготовить хранилище в рамках одного оптимизированного процесса.
Шаг 1. Откройте Cloud Shell и выполните аутентификацию GitHub CLI
Откройте консоль Google Cloud и активируйте Cloud Shell (значок >_ на верхней панели навигации).
Выполните аутентификацию GitHub CLI (gh), чтобы настроить управление учетными данными Git:
gh auth login --hostname github.com --git-protocol https --web
Следуйте инструкциям на экране:
Скопируйте восьмизначный одноразовый код, который появится в Cloud Shell (например, 1234-ABCD).
Нажмите Ввод, чтобы открыть https://github.com/login/device в браузере.
Вставьте код и нажмите Authorize github (Авторизовать GitHub).
Шаг 2. Динамически экспортируйте переменные и создайте форк OWASP Juice Shop
Чтобы автоматически получить имя пользователя GitHub и подготовить репозиторий, выполните в Cloud Shell следующие команды:
# 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. Как настроить интеграцию идентификационных данных рабочих нагрузок Google Cloud с помощью gcloud
На этом шаге вы будете использовать CLI gcloud в Google Cloud Shell, чтобы включить необходимые API, создать специальный сервисный аккаунт CI/CD, настроить пул Workload Identity и установить доверие OIDC с вашим репозиторием GitHub (${GITHUB_REPOSITORY}).
Шаг 1. Настройте переменные среды Google Cloud
В терминале Cloud Shell (в рабочей области клонированного хранилища) получите идентификатор активного проекта Google Cloud, проверьте переменную хранилища GitHub и определите названия ресурсов 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
Шаг 2. Включите необходимые API Google Cloud
Включите IAM API, Security Token Service API, IAM Credentials API, Agent Platform API и Resource Manager API.
gcloud services enable \
iam.googleapis.com \
iamcredentials.googleapis.com \
sts.googleapis.com \
aiplatform.googleapis.com \
cloudresourcemanager.googleapis.com \
--project=${PROJECT_ID}
Шаг 3. Создайте специальный сервисный аккаунт CI/CD
Создайте сервисный аккаунт Google Cloud с минимальными привилегиями, предназначенный для выполнения конвейера CI/CD (или используйте существующий):
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}"
Шаг 4. Предоставьте разрешения IAM для Agent Platform
Предоставьте сервисному аккаунту роль roles/aiplatform.user (пользователь платформы агентов), чтобы он мог взаимодействовать с Gemini Enterprise Agent Platform.
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--role="roles/aiplatform.user"
Шаг 5. Создайте пул Workload Identity
Создайте пул Workload Identity, чтобы управлять утверждениями идентификационных данных GitHub Actions (или автоматически восстановите и включите его, если он уже существует в вашем проекте):
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
Шаг 6. Создайте поставщика Workload Identity с помощью GitHub OIDC
Создайте или обновите поставщика OIDC в пуле, связав URL издателя https://token.actions.githubusercontent.com и сопоставив утверждения токена GitHub с атрибутами 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
Шаг 7. Разрешите хранилищу GitHub выдавать себя за сервисный аккаунт
Привяжите роль roles/iam.workloadIdentityUser, чтобы разрешить токенам из вашего хранилища выдавать себя за сервисный аккаунт исполнителя непрерывной интеграции, и проверьте привязку политики:
# 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
Шаг 8. Получите значения конфигурации для секретов GitHub
Получите полное название ресурса поставщика Workload Identity и сохраните его в переменной среды для автоматической регистрации на следующем шаге:
# 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. Как настроить секреты репозитория GitHub и разрешения рабочего процесса
Теперь, когда федерация идентификационной информации Google Cloud настроена, вы настроите секреты репозитория GitHub и предоставите необходимые разрешения рабочего процесса для автоматического сканирования безопасности и автоматического исправления pull-запросов.
Вы можете задать эти настройки прямо в Cloud Shell с помощью GitHub CLI (gh), чтобы не копировать и не вставлять вручную длинные названия ресурсов.
Шаг 1. Настройте секреты хранилища с помощью GitHub CLI
В терминале Cloud Shell выполните следующие команды, чтобы безопасно задать два необходимых секрета хранилища с помощью активных переменных среды:
# 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}"
Шаг 2. Предоставьте разрешения на рабочие процессы для автоматических запросов на извлечение
По умолчанию рабочие процессы GitHub Actions выполняются с разрешениями только на чтение и не могут создавать pull-запросы. На шаге 9 CodeMender автоматически создаст и отправит проверенные pull-запросы на исправление.
Предоставьте разрешения на запись и разрешите создание pull-запросов напрямую через GitHub API:
[ -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
Шаг 3. Отключите унаследованные рабочие процессы Juice Shop
При создании форка OWASP Juice Shop переносятся 16 рабочих процессов непрерывной интеграции (например, PR Compliance Check, CI/CD Pipeline и CodeQL Scan), а также шаблон запроса на извлечение от стороннего разработчика, который автоматически закрывает запросы на извлечение, нацеленные на master. Отключите все рабочие процессы, кроме CodeMender, с помощью GitHub CLI и удалите вышестоящие файлы локально, чтобы в вашем форке выполнялись только рабочие процессы 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. Как создать автоматизированный рабочий процесс поиска уязвимостей с помощью SARIF
На этом шаге вы создадите основной рабочий процесс непрерывного сканирования безопасности (.github/workflows/codemender-scan.yml), который выполняет базовое сканирование при отправке ветвей, дифференциальные проверки в pull-запросах и экспорт SARIF в GitHub Code Scanning.
Шаг 1. Скачайте рабочий процесс сканирования CodeMender
Скачайте codemender-scan.yml из репозитория starter в .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
Шаг 2. Зафиксируйте и отправьте изменения, а также запустите сканирование непрерывной интеграции
Зафиксируйте изменения рабочего процесса и отправьте их непосредственно в основную ветвь репозитория (master для Juice Shop или 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)
В браузере:
Перейдите в свое хранилище GitHub: https://github.com/YOUR_GITHUB_USER/juice-shop (например, https://github.com/octocat/juice-shop).
Нажмите на вкладку Действия на верхней панели навигации.
На боковой панели слева в разделе Workflows (Рабочие процессы) выберите CodeMender Security Scan & SARIF Export (Сканирование безопасности CodeMender и экспорт SARIF).
Запустите или посмотрите выполнение рабочего процесса:
Автоматический триггер. Если в списке есть автоматический запуск, активированный вашим push-уведомлением, нажмите на него, чтобы отслеживать выполнение в реальном времени.
Запуск по запросу (workflow_dispatch). Если запуск ещё не начался, нажмите кнопку Run workflow (Запустить рабочий процесс) ▾ справа, убедитесь, что выбрана ветка Branch: master (не устанавливайте флажок deep_scan, чтобы запустить быстрое базовое сканирование --quick), и нажмите зеленую кнопку Run workflow (Запустить рабочий процесс).
Нажмите на выполняемый запуск и выберите Autonomous Code Vulnerability Scan (Автономный поиск уязвимостей в коде), чтобы посмотреть, как рабочий процесс запускается в реальном времени.
Файл codemender-scan.yml: маршрутизация сканирования на основе событий
Пока базовое сканирование --quick выполняется в облаке (около 3–5 минут), посмотрите, как codemender-scan.yml (строки 118–155) направляет каждое событие GitHub в соответствующий режим сканирования в средстве запуска:
# 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
Hardened Runner Setup ( строки 27–117): пропускает ненадежные внешние форки и запросы на извлечение dependabot[bot], извлекает с помощью persist-credentials: false, кеширует ~/.local/bin/cm и ~/.codemender/state.db и запускает cm health --strict перед использованием квоты модели.
Границы изолированной среды без графического интерфейса (--sandbox=false --yes --bypass-warning). Отключает изоляцию пространства имен пользователей Linux (ограничено в непривилегированных контейнерах GitHub Actions), сохраняя границы путей рабочей области (project_paths) и command_policy.yaml.
Экспорт SARIF и артефактов с защитой по коду выхода ( строки 147–194). Задает steps.scan.outputs.completed=true, только если cm find завершается с кодом 0 (чисто) или 1 (достигнут порог --fail-on). Это гарантирует, что отчеты SARIF (cm report -f sarif с оценками серьезности CVSS), таблицы $GITHUB_STEP_SUMMARY (cm report -f md) и артефакты codemender-findings.json по-прежнему публикуются, когда --fail-on блокирует запрос на извлечение, а экспорт пропускается при ошибках настройки или емкости (10–60), поэтому пустые файлы SARIF никогда не закрывают существующие оповещения.
7. Как проверять оповещения о сканировании кода GitHub и панель управления безопасностью
После завершения рабочего процесса отправки базового плана GitHub обрабатывает загруженный файл SARIF и заполняет сводку выполнения действий и вкладку "Безопасность" репозитория.
Шаг 1. Проверьте сводку по задаче в GitHub Actions
При каждом запуске рабочего процесса сводная таблица Markdown (cm report -f md) добавляется непосредственно в обзор запуска GitHub Actions:
В репозитории GitHub откройте вкладку Actions (Действия).
Выберите завершенный запуск CodeMender Security Scan & SARIF Export (проверки базовой ветви завершаются зеленой галочкой ✅ после публикации результатов SARIF).
Прокрутите вниз до раздела 🛡️ CodeMender Security Scan Summary (Сводка по сканированию безопасности CodeMender), чтобы посмотреть подробные результаты.
🔒 Отчет о безопасности CodeMender
Общие сведения
Всего результатов: 28
Уровень | Счетчик |
🔴 КРИТИЧЕСКИЙ | 6 |
🟠 ВЫСОКИЙ | 16 |
🟡 СРЕДНИЙ | 6 |
Статус | Счетчик |
🔴 ОТКРЫТО | 28 |
Результаты
Идентификатор | Уровень | Уверенность | Статус | Исправить | Файл | Название |
| 🔴 КРИТИЧЕСКИЙ | 100% | ОТКРЫТЬ | — |
| Удаленное выполнение кода через внедрение кода на стороне сервера в профиле пользователя |
| 🔴 КРИТИЧЕСКИЙ | 100% | ОТКРЫТЬ | — |
| Внедрение SQL-кода в маршрут аутентификации пользователя |
| 🔴 КРИТИЧЕСКИЙ | 100% | ОТКРЫТЬ | — |
| Удаленное выполнение кода через выход из изолированной среды при обработке заказов B2B |
Шаг 2. Изучите централизованную панель управления сканированием кода
На верхней панели навигации в репозитории GitHub нажмите на вкладку Security and quality (Безопасность и качество) или Security (Безопасность).
На боковой панели слева в разделе Findings (Результаты) выберите Code scanning (Сканирование кода).
Если активно несколько инструментов, отфильтруйте Инструмент по CodeMender (is:open branch:master tool:CodeMender), чтобы проверить оповещения, сопоставленные со значками серьезности CVSS:
Значок уровня серьезности | Заголовок уязвимости | Определенное местоположение | Branch |
🔴 Критическая | Удаленное выполнение кода через внедрение кода на стороне сервера в профиле пользователя |
|
|
🔴 Критическая | Внедрение SQL-кода в маршрут аутентификации пользователя |
|
|
🔴 Критическая | Удаленное выполнение кода через выход из изолированной среды при обработке заказов B2B |
|
|
Нажмите SQL Injection in User Authentication Route (SQL-инъекция в маршруте аутентификации пользователя) (routes/login.ts:34), чтобы посмотреть поток зараженных данных и анализ основной причины, выполненный Gemini.
8. Как заблокировать небезопасный pull-запрос с помощью дифференциального сканирования
Базовое сканирование выявило 28 уязвимостей в OWASP Juice Shop. При использовании традиционных статических анализаторов эти 28 устаревших результатов приводили бы к сбою каждого последующего pull-запроса, пока не был бы исправлен весь бэклог, что вынуждало бы команды отключать блокировку слияния.
Теперь вы протестируете PR Differential AST Gate (--diff + --fail-on="CRITICAL,HIGH") в CodeMender. Вы откроете pull-запрос, который создает новую уязвимость, и посмотрите, как CodeMender изолирует дельту, блокирует слияние примерно за 15–25 секунд и аннотирует строки, в которых есть уязвимость.
Шаг 1. Создайте pull-запрос, который добавляет уязвимость к внедрению команд
В Cloud Shell (в рабочей области клонированного репозитория) создайте ветку функции, добавьте новый маршрут Express, содержащий уязвимость внедрения команд ОС, и откройте 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/@@')
# 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."
Шаг 2. Проверьте шлюз слияния дифференциальных изменений и встроенную аннотацию запроса на извлечение
Откройте URL pull-запроса, указанный в конце выходных данных терминала.
Прокрутите страницу обсуждения pull-запроса вниз до раздела Checks (Проверки) и найдите Autonomous Code Vulnerability Scan (Автономный поиск уязвимостей в коде).
Скорость дельта-сканирования. Вместо сканирования всех 680+ файлов в репозитории (около 3–5 минут) cm find . --diff="origin/${PRIMARY_BRANCH}" анализирует только routes/diagnostics.ts (и все вызывающие объекты в пределах одного перехода), завершая сканирование за 15–25 секунд.
Изоляция устаревших уязвимостей и блокировка слияния. Ни одна из 28 нетронутых устаревших уязвимостей Juice Shop не приводит к сбою проверки. Только новая уязвимость CRITICAL (внедрение команд) активирует --fail-on="CRITICAL,HIGH" и завершает работу с кодом статуса 1 (красный крестик ❌), блокируя слияние запроса на извлечение.
В верхней части страницы pull-запроса нажмите на вкладку Files changed (Измененные файлы).
Поскольку защита кода выхода рабочего процесса (steps.scan.outputs.completed == 'true') по-прежнему экспортирует и загружает results.sarif, когда --fail-on завершает работу с кодом 1, GitHub Code Scanning отображает встроенную аннотацию безопасности CodeMender – критическая непосредственно под execSync в routes/diagnostics.ts.
Шаг 3. Удалите тестовый запрос на извлечение и вернитесь к основной ветке
Прежде чем переходить к автономному исправлению, переключите рабочую область Cloud Shell обратно на основную ветвь и закройте небезопасный тестовый 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. Создайте рабочий процесс для автономного устранения уязвимостей и автоматического создания запросов на извлечение
Теперь, когда шлюз pull-запросов предотвращает появление новых уязвимостей в базе кода, вы развернете автономное устранение уязвимостей (.github/workflows/codemender-remediate.yml), чтобы активно исправлять существующие уязвимости и открывать готовые к проверке pull-запросы.
Шаг 1. Скачайте файл рабочего процесса устранения неполадок
CodeMender предоставляет два шаблона исправления в зависимости от видимости хранилища:
Общедоступные хранилища и хранилища с открытым исходным кодом (codemender-remediate.yml). Режим ответственного раскрытия информации – ссылки на оповещения SARIF о сканировании кода GitHub без публичного раскрытия необработанных векторов эксплойтов.
Частные и корпоративные репозитории (codemender-remediate-private-repo.yml). Режим доказательств внутреннего аудита – встраивает артефакты проверки (PLAN.md, REPORT.md, exploit.sh) в сворачиваемые разделы запросов на извлечение, исключая их из коммитов Git.
Скачайте в репозиторий рабочий процесс исправления, безопасный для общедоступных репозиториев:
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
Шаг 2. Запустите рабочий процесс автономного устранения неполадок
Зафиксируйте и отправьте рабочий процесс исправления в основную ветку:
git add .github/workflows/codemender-remediate.yml
git commit -m "ci: add CodeMender autonomous remediation workflow"
git push origin $(git branch --show-current)
В браузере перейдите на вкладку Actions (Действия) хранилища GitHub.
На боковой панели слева в разделе Workflows (Рабочие процессы) выберите CodeMender Autonomous Security Remediation & Auto-PR (Автономное устранение уязвимостей и автоматическое создание запросов на извлечение с помощью CodeMender).
Справа нажмите на зеленый раскрывающийся список Run workflow (Запустить рабочий процесс).
Use workflow from (Использовать рабочий процесс из): убедитесь, что выбрана ветвь по умолчанию (master).
Specific Finding ID or prefix to fix (Идентификатор или префикс конкретной проблемы, которую нужно устранить). Введите восьмизначный префикс для routes/login.ts, записанный на шаге 7 (например, cd47b38a). Если оставить это поле пустым, будет запущено пакетное устранение всех открытых проблем с критическим и высоким уровнем серьезности (это займет около 10–15 минут). Устранение одной проблемы занимает около 45–60 секунд.
Нажмите зеленую кнопку Run workflow (Запустить рабочий процесс) во всплывающем окне и откройте выполняемый запуск.

Файл codemender-remediate.yml: автономный синтез исправлений
Пока CodeMender синтезирует исправление в облаке (это занимает около 30–45 секунд), посмотрите, как codemender-remediate.yml (строки 111–184) управляет исправлением в средстве запуска:
Возобновление без сканирования (cm report import). Скачивает артефакт codemender-findings.json из рабочего процесса сканирования и импортирует его в рабочую область (cm report import -f codemender-findings.json). Возврат к cm find . --quick происходит, только если предыдущий артефакт отсутствует.
Headless Patch Synthesis (cm fix): закрепляет project_paths в $GITHUB_WORKSPACE, передает < /dev/null, чтобы предотвратить зависания, и передает --no-reset во время пакетных циклов, чтобы исправления сохранялись в результатах:
# Executed inside the GitHub Actions runner (codemender-remediate.yml)
cm fix "${SPECIFIC_TARGET}" --sandbox=false --yes --bypass-warning < /dev/null
Очистка рабочих коммитов ( строки 155–252). Удаляет .cm_project, .exploit/ и временные файлы с помощью .git/info/exclude, прежде чем peter-evans/create-pull-request@v8 откроет ветку (codemender/auto-remediation-${{ github.run_id }}), фиксируя только изменения рабочего кода:
--- 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
+ })
Шаг 3. Проверьте новый pull-запрос на GitHub
Перейдите на вкладку Pull requests (Pull-запросы) в репозитории и откройте новый pull-запрос (например, 🛡️ [CodeMender] Fix: SQL Injection in User Authentication Route).
Нажмите Files changed (Измененные файлы) и убедитесь, что изменен только файл routes/login.ts, а все внутренние метаданные среды выполнения исключены.
Проверьте описание запроса на извлечение, которое ссылается непосредственно на оповещение GitHub Code Scanning (SARIF), чтобы получить одобрение от мейнтейнера.
10. Устранение неполадок в пограничных случаях и частных репозиториях
Частные хранилища без GitHub Advanced Security (GHAS)
Общедоступные хранилища GitHub получают бесплатную неограниченную загрузку SARIF-файлов из GitHub Code Scanning. Однако если вы развернете этот рабочий процесс в частном корпоративном репозитории, у которого нет активной лицензии GitHub Advanced Security (GHAS), шаг upload-sarif завершится ошибкой:
HTTP 403: Advanced Security must be enabled for this repository to use code scanning.
Решение: резервный интерактивный HTML-отчет
Встроенный генератор отчетов HTML (cm report -f html) в CodeMender создает отдельную интерактивную панель безопасности с карточками показателей серьезности, фрагментами кода с подсветкой синтаксиса и номерами строк, а также встроенным средством просмотра различий в исправлениях без внешних веб-зависимостей.
Чтобы поддерживать частные репозитории без лицензии GHAS, обновите .github/workflows/codemender-scan.yml, чтобы архивировать артефакт отчета HTML вместо загрузки SARIF:
Создайте отдельный отчет в формате HTML. На этапе Export Security Reports & Publish Job Summary экспортируйте сводку в формате HTML вместе со сводкой в формате Markdown, используя cm report -f html > codemender-audit-report.html.
Архивируйте отчет как артефакт рабочего процесса. Замените шаг Upload SARIF Report to GitHub Code Scanning (github/codeql-action/upload-sarif@v4) на actions/upload-artifact@v4, настроенный для загрузки codemender-audit-report.html (например, под названием артефакта codemender-security-report).
Проверьте локально в любом браузере. Скачайте codemender-security-report.zip со страницы сводки по запуску рабочего процесса GitHub Actions, распакуйте его и откройте codemender-audit-report.html в любом браузере для визуальной сортировки.
Автономное устранение уязвимостей в частных репозиториях со встроенными доказательствами аудита
В частных корпоративных репозиториях командам разработчиков и специалистов по безопасности нужна полная видимость анализа основных причин, проверки концепции эксплойта и плана устранения уязвимостей без необходимости использовать панели инструментов внешних инструментов. Однако добавление скриптов эксплойтов (exploit.sh) или внутренних файлов Markdown (PLAN.md, LOG.md) в ветку репозитория засоряет историю Git и может вызывать ложные срабатывания других сканеров безопасности.
Чтобы устранить эту проблему, разверните специальный рабочий процесс исправления частного хранилища (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)
Как работает устранение уязвимостей в частных репозиториях
Динамическая проверка PoC (cm verify). Синтезирует и тестирует работающий эксплойт перед созданием исправления, чтобы подтвердить возможность эксплуатации. Если проверка помечает неэксплуатируемую уязвимость как DISMISSED, cm fix автоматически пропускается.
Сворачиваемые блоки аудита pull-запросов. Извлекает REPORT.md, PLAN.md и exploit.sh в /tmp/codemender-evidence/ и форматирует их непосредственно в описании pull-запроса внутри сворачиваемых блоков <details open> для проверки рецензентом в один клик.
Архивирование артефактов. Архивация всей папки с доказательствами с помощью actions/upload-artifact@v4.
Pristine Git Commits. Удаляет все метаданные среды выполнения и каталоги .exploit, чтобы коммит Git в pull-запросе содержал только изменения в рабочем коде.
Контрольный список для устранения неполадок с Workload Identity Federation (WIF)
По умолчанию google-github-actions/auth@v2 записывает локальный файл конфигурации федеративных учетных данных во время настройки, а фактический обмен токенами OAuth 2.0 происходит при запуске cm health --strict или cm find. Чтобы диагностировать ошибки аутентификации HTTP 400 или HTTP 403, воспользуйтесь контрольным списком ниже.
Признак ошибки | Распространенная основная причина | Проверка и исправление |
HTTP 403 ( | Отсутствует привязка | Убедитесь, что |
HTTP 400 ( | Название (или регистр) хранилища OIDC | Повторно выполните шаг 4 (шаги 1 и 6), убедившись, что регистр |
HTTP 400 ( | Неверный формат | Убедитесь, что для параметра |
Временная ошибка HTTP 403 сразу после настройки | Распространение глобальных настроек IAM и Workload Identity Federation для новых привязок может занять от 1 до 5 минут. | Подождите 1–2 минуты и нажмите Re-run failed jobs (Повторно запустить невыполненные задания) в GitHub Actions. |
Чтобы проверить привязку Workload Identity в сервисном аккаунте CI/CD в Cloud Shell, выполните следующую команду:
gcloud iam service-accounts get-iam-policy "${SERVICE_ACCOUNT_EMAIL}" \
--project="${PROJECT_ID}" \
--flatten="bindings[].members" \
--filter="bindings.role=roles/iam.workloadIdentityUser"
Убедитесь, что в выходных данных roles/iam.workloadIdentityUser привязано к 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
Устранение неполадок с предварительной проверкой CI/CD и кодом выхода CLI
Команды CodeMender (cm health --strict, cm find, cm verify и cm fix) возвращают детерминированные коды выхода, поэтому конвейеры CI/CD могут сразу отличить результаты проверки безопасности от ошибок настройки или сервиса:
Код выхода | Категория | Распространенные основные причины и способы устранения |
| Выполнено | Проверки работоспособности пройдены или сканирование завершено без обнаружения блокирующих проблем. |
| Фурнитура/Общее | Обнаружено |
|
| Не удалось обменять токен WIF OAuth/ADC ( |
|
| Недопустимый синтаксис |
|
| Исполнитель не может подключиться к |
|
| В целевом проекте у сервисного аккаунта нет роли |
|
| Предварительная проверка |
|
| Агент достиг лимита на количество одновременно выполняемых активных задач. Повторно запустите рабочий процесс через некоторое время. |
Информацию о других ошибках выполнения, например о разрешении базовой ветви Git diff (fetch-depth: 0), задержках распространения ресурсов или разрешениях на создание pull-запросов GitHub Actions, можно найти в официальном руководстве по устранению неполадок CodeMender CI/CD.
11. Очистка ресурсов
Чтобы предотвратить дальнейшее потребление ресурсов или очистить тестовые конфигурации в средах Google Cloud и GitHub, выполните следующие действия по очистке.
Шаг 1. Удалите секреты хранилища GitHub и отключите рабочие процессы с помощью gh CLI
Используйте GitHub CLI (gh), чтобы удалить секреты Actions из хранилища и отключить рабочие процессы 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
Шаг 2. Отключите или удалите ресурсы Workload Identity Federation в Google Cloud
Пулы Workload Identity, поставщики и сервисные аккаунты не требуют затрат, когда не обмениваются токенами. Выберите режим очистки, который соответствует вашему рабочему процессу:
Вариант А. Приостановка доступа (рекомендуется, если вы планируете повторно запустить проект). Немедленно отключает обмен токенами OIDC, не запуская 30-дневное хранение удаленных данных Google Cloud IAM или задержки распространения uniqueId сервисного аккаунта.
gcloud iam workload-identity-pools providers update-oidc "${WORKLOAD_IDENTITY_PROVIDER}" \
--workload-identity-pool="${WORKLOAD_IDENTITY_POOL}" \
--location="global" \
--disabled \
--project="${PROJECT_ID}"
Вариант Б. Полное удаление. Удаление поставщика федеративной идентификации рабочей нагрузки, пула (сохраняется в состоянии DELETED в течение 30 дней) и выделенного сервисного аккаунта.
# 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. Поздравляю!
Поздравляем! Вы завершили практическую работу Как защитить конвейер CI/CD с помощью CodeMender.
Вы успешно спроектировали, создали и автоматизировали конвейер DevSecOps с нулевым доверием производственного уровня, используя федерацию Workload Identity Google Cloud, CodeMender и GitHub Actions.
Что вы узнали
Аутентификация без ключей с нулевым доверием. Мы отказались от использования небезопасных долгосрочных JSON-ключей сервисных аккаунтов, связав временные токены OIDC GitHub с Google Cloud IAM через Workload Identity Federation (WIF).
Дифференциальное AST-сканирование PR и шумоподавление устаревшего шума. Ограниченное непрерывное сканирование измененных файлов и зависимостей (--diff="origin/$BASE_REF"), изолирующее устаревший технический долг ([LEGACY / UNTOUCHED]), чтобы циклы обратной связи с разработчиками не превышали 15 секунд.
Многоформатные отчеты и сводки по заданиям. Мы объединили OASIS SARIF версии 2.1.0 для централизованного сканирования кода GitHub с нативным Markdown (cm report -f md >> $GITHUB_STEP_SUMMARY), чтобы руководители могли мгновенно получать информацию прямо на страницах выполнения рабочих процессов непрерывной интеграции.
Автономное устранение уязвимостей с участием человека в контуре. Мы перешли от пассивных уведомлений к активным конвейерам устранения уязвимостей, которые автономно синтезируют предлагаемые исправления кода, проверяют их с помощью наборов регрессионных тестов и открывают pull-запросы на проверку с артефактами аудита для утверждения инженером.
Автоматизированные строгие проверки качества. Внедрена строгая защита ветвей и контроль слияния (--fail-on), чтобы опасные уязвимости не попадали в рабочую среду.
Передача состояния на основе артефактов и изоляция рабочей области. Результаты сканирования передаются между заданиями непрерывной интеграции с помощью cm report import, а .git/info/exclude используется для сохранения исходной истории Git и предотвращения утечки учетных данных.
Изменение мышления разработчиков
Традиционная практика DevSecOps | Автономный конвейер непрерывной интеграции и непрерывной поставки CodeMender |
Пассивный сброс оповещений. Сканеры выводят необработанные журналы терминала или статические списки ошибок, полностью перекладывая бремя сортировки на разработчиков. | Активный помощник в разработке. Синтезирует проверенные исправления кода и открывает готовые к слиянию запросы на включение изменений, которые инженеры могут одобрить. |
Высокий уровень ложных срабатываний. Эвристические алгоритмы статического тестирования безопасности приложений отмечают тысячи теоретических уязвимостей, не доказывая, что их можно использовать. | Двухуровневая проверка эксплойтов. Динамическое создание тестов в изолированной среде ( |
Рискованное хранение секретов. JSON-ключи сервисных аккаунтов с длительным сроком действия, хранящиеся в секретах CI, могут быть случайно раскрыты или утеряны. | Федеративная идентификация рабочих нагрузок с нулевым доверием. Аутентификация без ключа с помощью временных токенов OIDC, которыми можно обмениваться с Google Cloud STS по запросу. |
Монолитные повторные сканирования. Каждая фиксация запускает полный аудит репозитория, задерживая рабочие процессы непрерывной интеграции и тратя дорогостоящие токены. | Маршрутизация AST с учетом событий. Pull-запросы выполняют 15-секундные дифференциальные сканирования AST ( |
Загрязнение истории репозитория. Временные скрипты эксплойтов и журналы атак, зафиксированные непосредственно в ветках репозитория. | Чистота рабочей среды. Доказательства атаки встраиваются в описания запросов на перенос и артефакты рабочих процессов, не затрагивая фиксации кода. |
Дальнейшие действия
🚀 Продолжайте изучать CodeMender
Часть 1. Защита приложения с помощью CodeMender. Научитесь автономно обнаруживать уязвимости в хранилище, проверять эксплойты PoC и синтезировать локальные исправления.
Shift Left Locally & Serverless Cloud Native CI/CD. Ознакомьтесь с примерами реализации в официальном руководстве по CI/CD для Google Cloud Build (cloudbuild.yaml) и локальных хуков Git pre-commit (cm find . --diff --staged).
📖 Документация и ресурсы
Официальное руководство по интеграции CodeMender с CI/CD в Google Cloud
Официальная документация по Google Cloud CodeMender
Репозиторий шаблонов CodeMender GitHub Actions Starter
Документация по Workload Identity Federation в Google Cloud
💡 Примените к своим хранилищам
Создайте форк начального рабочего процесса и защитите репозитории Python, Go, Java, Rust и Node.js вашей организации с помощью CodeMender.