1. 소개
Gemini CLI 보안 확장 프로그램은 Google에서 빌드한 오픈소스 Gemini CLI 확장 프로그램으로, 코드에서 보안 위험과 취약점을 분석합니다. 다른 Gemini CLI 확장 프로그램과 마찬가지로 Gemini CLI와 함께 보안 확장 프로그램을 사용하여 로컬에서 보안 문제를 식별할 수 있습니다. GitHub에서 풀 요청을 검토하기 위해 호출할 수도 있습니다. 이 Codelab에서는 GitHub 저장소에서 보안 확장 프로그램을 사용하는 방법을 알아봅니다.
실습할 내용
- GitHub에서 Google Cloud로의 보안 인증 구성
- Gemini CLI 보안 확장 프로그램을 호출하는 GitHub Actions 워크플로 만들기
- GitHub Actions를 사용하여 신규 또는 기존 PR에 대한 보안 검토 실행
학습할 내용
- GitHub Actions에서 Google Cloud로의 보안 인증을 위해 워크로드 아이덴티티 제휴를 사용하는 방법
- 인증을 위해 Gemini API 키 대신 워크로드 아이덴티티 풀 및 워크로드 아이덴티티 공급자를 사용할 때의 이점 알아보기
- PR로 보안 검토를 실행하는 방법
- 보안 확장 프로그램에서 반환된 보안 검토를 해석하는 방법
필요한 항목
- 웹브라우저
- GitHub 계정 및 저장소
- Google Cloud 프로젝트
이 Codelab은 GitHub의 CI/CD 워크플로에 익숙한 개발자를 대상으로 합니다. Gemini CLI 또는 Gemini CLI 확장 프로그램에 익숙하지 않아도 됩니다. 확장 프로그램의 작동 방식을 알아보려면 Gemini CLI 확장 프로그램 시작하기 Codelab을 확인하세요.
이 Codelab에서는 GitHub 저장소에서 Gemini CLI 보안 확장 프로그램을 설정하는 방법을 알아봅니다. 보안 취약점 발견을 트리거하기 위해 저장소에 대해 PR을 열도록 코드를 제안하지 않습니다.
2. 시작하기 전에
프로젝트 생성 또는 선택
- Google Cloud 콘솔의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.
- Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 결제를 확인하는 방법을 알아보세요.
- Google Cloud에서 실행되는 명령줄 환경인 Cloud Shell을 엽니다. Google Cloud 콘솔 상단에서 Cloud Shell 활성화를 클릭합니다.

- Cloud Shell에 연결되면 다음 명령어를 사용하여 인증되었는지, 프로젝트가 프로젝트 ID로 설정되었는지 확인합니다.
gcloud auth list
- 다음 명령어를 실행하여
gcloud명령어가 프로젝트를 사용하도록 구성되었는지 확인합니다.
gcloud config list project
- 프로젝트가 설정되지 않은 경우 다음 명령어를 사용하여 설정합니다.
gcloud config set project ${GOOGLE_CLOUD_PROJECT}
3. GitHub에서 Google Cloud로 인증 설정
작동 방식

워크로드 아이덴티티 제휴는 GitHub Actions에서 Google Cloud로 인증하는 데 권장되는 방법입니다.
- 모든 GitHub Actions 워크플로 실행 작업에 대해 외부 ID 공급업체로서의 GitHub는 서명된 JWT (JSON 웹 토큰)를 발급합니다. 이 토큰에는
repository,workflow,job_workflow_ref와 같은 '클레임'이 포함되어 있으며, 이는 특정 러너의 디지털 신분증 역할을 합니다. 이 실습에서는 GitHub에서 JWT를 요청하고 이 토큰을 Google Cloud의 보안 토큰 서비스 (STS)에 전송하는google-github-actions/run-gemini-cli작업을 사용하는 GitHub Actions 워크플로를 만듭니다. - 발급자 URL을 공식 GitHub 토큰 서비스 URL
https://token.actions.githubusercontent.com로 설정하고 일반적으로 저장소 및 브랜치 이름을 포함하는 '속성 매핑'을 정의하여 Google Cloud에서 워크로드 아이덴티티 풀 및 공급자를 구성합니다. Google Cloud STS는 워크로드 아이덴티티 풀 규칙에 대해 JWT를 검증합니다. 속성 매핑을 비롯한 모든 항목이 확인되면 STS는 GitHub 토큰을 수명이 짧은 Google Cloud 페더레이티드 액세스 토큰으로 교환합니다. - 이제 GitHub Actions 워크플로의
google-github-actions/run-gemini-cli작업이 단기 Google Cloud 제휴 액세스 토큰을 사용하여 연결된 서비스 계정을 워크로드 아이덴티티 풀로 '가장'할 수 있습니다. 연결된 서비스 계정에는 Google Cloud 리소스 및 서비스에 액세스하는 데 필요한 IAM 역할과 권한이 있어야 합니다.
Gemini API 키 대신 워크로드 아이덴티티 제휴를 사용하는 경우의 이점
적절한 키 값으로 GEMINI_API_KEY라는 새 GitHub Actions 보안 비밀을 만들어 GitHub Actions에서 시작된 Gemini CLI 호출을 Gemini API 키를 사용하여 인증할 수 있습니다. 하지만 다음과 같은 보안상의 이유로 권장하지 않습니다.
- Gemini API 키는 각 IAM 역할 바인딩에서 광범위한 권한을 가질 수 있습니다. 계정이 도용되면 광범위한 Google Cloud 리소스 및 서비스에 대한 액세스 권한이 열립니다. 워크로드 아이덴티티 제휴는 서비스 계정과 단기 액세스 토큰을 사용하여 인증을 크게 강화합니다.
- 또한 Gemini API 키는 대규모로 관리하기 어렵습니다. 노출된 키를 사용하는 워크플로를 식별하는 데 시간이 걸립니다. 키를 수동으로 순환하는 데도 시간이 걸립니다. 반면 Cloud Console에서 저장소와 연결된 워크로드 아이덴티티 풀과 제공업체를 쉽게 조회, 수정, 삭제할 수 있습니다.
- Gemini API 키를 사용하면 액세스 또는 디버그 로그에 실수로 노출되지 않는지 항상 다시 확인해야 합니다. 워크로드 아이덴티티 제휴를 사용하면 GitHub Actions 워크플로 보안 비밀이 아닌 변수를 저장하므로 보안에 덜 민감합니다.
GitHub Actions 및 Google Cloud 구성
- Cloud Shell에서 GitHub 계정에 로그인합니다.
gh auth login
- 새 파일
setup_workload_identity.sh를 만들고 아래 코드를 복사하여 붙여넣습니다.
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Helper functions
print_info() {
echo -e "${BLUE}ℹ️ $1${NC}"
}
print_success() {
echo -e "${GREEN}✅ $1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_error() {
echo -e "${RED}❌ $1${NC}"
}
print_header() {
echo -e "${BLUE}🚀 $1${NC}"
}
# Default values
GOOGLE_CLOUD_PROJECT=""
GOOGLE_CLOUD_LOCATION="global"
GITHUB_REPO=""
POOL_NAME=""
PROVIDER_NAME=""
# Show help
show_help() {
cat << EOF
Universal Direct Workload Identity Federation Setup for GitHub Actions
USAGE:
$0 --repo OWNER/REPO [OPTIONS]
REQUIRED:
-r, --repo OWNER/REPO GitHub repository (e.g., google/my-repo)
-p, --project GOOGLE_CLOUD_PROJECT Google Cloud project ID
OPTIONS:
--pool-name NAME Custom workload identity pool name (default: auto-generated)
--provider-name NAME Custom workload identity provider name (default: auto-generated)
-h, --help Show this help
EXAMPLES:
# Basic setup for a repository
$0 --repo google/my-repo --project my-gcp-project
# Custom pool name
$0 --repo google/my-repo --project my-gcp-project --pool-name my-pool
# Custom pool and provider names
$0 --repo google/my-repo --project my-gcp-project --pool-name my-pool --provider-name my-provider
ABOUT DIRECT WORKLOAD IDENTITY FEDERATION:
This script sets up Direct Workload Identity Federation (preferred method).
- No intermediate service accounts required
- Direct authentication from GitHub Actions to GCP resources
- Maximum token lifetime of 10 minutes
- You grant permissions directly to the Workload Identity Pool on GCP resources
EOF
}
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-r|--repo)
GITHUB_REPO="$2"
shift 2
;;
-p|--project)
GOOGLE_CLOUD_PROJECT="$2"
shift 2
;;
--pool-name)
POOL_NAME="$2"
shift 2
;;
--provider-name)
PROVIDER_NAME="$2"
shift 2
;;
-l|--location)
GOOGLE_CLOUD_LOCATION="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
print_error "Unknown option: $1"
echo "Use --help for usage information."
exit 1
;;
esac
done
# Validate required arguments
if [[ -z "${GITHUB_REPO}" ]]; then
print_error "Repository is required. Use --repo OWNER/REPO"
echo ""
echo "💡 To find your repository name:"
echo " 1. Go to your GitHub repository"
echo " 2. The URL shows: https://github.com/OWNER/REPOSITORY"
echo " 3. Use: OWNER/REPOSITORY (e.g., google/golang)"
echo ""
echo "Use --help for usage information."
exit 1
fi
if [[ -z "${GOOGLE_CLOUD_PROJECT}" ]]; then
print_error "GCP project is required. Use --project GOOGLE_CLOUD_PROJECT"
echo ""
echo "💡 To find your project ID:"
echo " 1. Go to your Google Cloud console"
echo " 2. The URL displays: https://console.cloud.google.com/welcome?project=GOOGLE_CLOUD_PROJECT"
echo ""
echo "Use --help for usage information."
exit 1
fi
# Validate repository format
if [[ ! "${GITHUB_REPO}" =~ ^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$ ]]; then
print_error "Invalid repository format '${GITHUB_REPO}'"
echo "Expected format: owner/repo (e.g., google/my-repo)"
exit 1
fi
# Extract repository components
REPO_OWNER=$(echo "${GITHUB_REPO}" | cut -d'/' -f1)
# Generate unique names based on repository
REPO_HASH_INPUT=$(echo -n "${GITHUB_REPO}")
REPO_HASH_SHA=$(echo "${REPO_HASH_INPUT}" | shasum -a 256)
REPO_HASH=$(echo "${REPO_HASH_SHA}" | cut -c1-8)
# Use custom pool name if provided, otherwise generate one
if [[ -z "${POOL_NAME}" ]]; then
POOL_NAME="github-${REPO_HASH}"
fi
# Use custom provider name if provided, otherwise generate one
if [[ -z "${PROVIDER_NAME}" ]]; then
PROVIDER_NAME="gh-${REPO_HASH}"
fi
print_header "Starting Direct Workload Identity Federation setup"
echo "📦 Repository: ${GITHUB_REPO}"
echo "☁️ Project: ${GOOGLE_CLOUD_PROJECT}"
echo "🏊 Pool: ${POOL_NAME}"
echo "🆔 Provider: ${PROVIDER_NAME}"
echo ""
# Verify gcloud authentication
print_info "Verifying gcloud authentication..."
GCLOUD_AUTH_LIST_RAW=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
GCLOUD_AUTH_LIST=$(echo "${GCLOUD_AUTH_LIST_RAW}" | head -1)
if [[ -z "${GCLOUD_AUTH_LIST}" ]]; then
print_error "No active gcloud authentication found"
echo "Please run: gcloud auth login"
exit 1
fi
# Test project access
if ! gcloud projects describe "${GOOGLE_CLOUD_PROJECT}" > /dev/null 2>&1; then
print_error "Cannot access project '${GOOGLE_CLOUD_PROJECT}'"
echo "Please verify:"
echo " 1. Project ID is correct"
echo " 2. You have permissions on this project"
echo " 3. Project exists and is not deleted"
exit 1
fi
print_success "Authentication and project access verified"
# Step 1: Enable required APIs
print_header "Step 1: Enabling required Google Cloud APIs"
required_apis=(
"aiplatform.googleapis.com"
"cloudaicompanion.googleapis.com"
"cloudresourcemanager.googleapis.com"
"cloudtrace.googleapis.com"
"iam.googleapis.com"
"iamcredentials.googleapis.com"
"logging.googleapis.com"
"monitoring.googleapis.com"
"sts.googleapis.com"
)
gcloud services enable "${required_apis[@]}" --project="${GOOGLE_CLOUD_PROJECT}"
print_success "APIs enabled successfully."
# Step 2: Create Workload Identity Pool
print_header "Step 2: Creating Workload Identity Pool"
if ! gcloud iam workload-identity-pools describe "${POOL_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" &> /dev/null; then
print_info "Creating Workload Identity Pool: ${POOL_NAME}"
gcloud iam workload-identity-pools create "${POOL_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--display-name="GitHub Actions Pool"
print_success "Workload Identity Pool created"
else
print_info "Workload Identity Pool '${POOL_NAME}' exists. Verifying state..."
# Fetch the current state of the existing pool.
POOL_STATE=$(gcloud iam workload-identity-pools describe "${POOL_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--format="value(state)")
if [[ "${POOL_STATE}" == "ACTIVE" ]]; then
# Pool exists and is in the correct state.
print_success "Workload Identity Pool already exists and is ACTIVE."
else
if [[ "${POOL_STATE}" == "DELETED" ]]; then
# Pool exists but is DELETED. Undelete the pool.
print_warning "Workload Identity Pool already exists but is in a DELETED state. Running 'undelete'."
gcloud iam workload-identity-pools undelete "${POOL_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}"
else
# Pool exists but is in an unexpected state.
print_error "Pool '${POOL_NAME}' is in an unexpected state: '${POOL_STATE}'. Expected states are: {'ACTIVE', 'DELETED'}. Exiting"
exit 1
fi
fi
fi
# Get the pool ID
WIF_POOL_ID=$(gcloud iam workload-identity-pools describe "${POOL_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--format="value(name)")
# Step 3: Create Workload Identity Provider
print_header "Step 3: Creating Workload Identity Provider"
ATTRIBUTE_CONDITION="assertion.repository_owner == '${REPO_OWNER}'"
if ! gcloud iam workload-identity-pools providers describe "${PROVIDER_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--workload-identity-pool="${POOL_NAME}" &> /dev/null; then
print_info "Creating Workload Identity Provider: ${PROVIDER_NAME}"
gcloud iam workload-identity-pools providers create-oidc "${PROVIDER_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--workload-identity-pool="${POOL_NAME}" \
--display-name="${PROVIDER_NAME}" \
--attribute-mapping="google.subject=assertion.sub,attribute.actor=assertion.actor,attribute.repository=assertion.repository,attribute.repository_owner=assertion.repository_owner" \
--attribute-condition="${ATTRIBUTE_CONDITION}" \
--issuer-uri="https://token.actions.githubusercontent.com"
print_success "Workload Identity Provider created"
else
print_info "Workload Identity Provider '${PROVIDER_NAME}' exists. Verifying state..."
# Fetch the current state of the existing provider.
PROVIDER_STATE=$(gcloud iam workload-identity-pools providers describe "${PROVIDER_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--workload-identity-pool="${POOL_NAME}" \
--format="value(state)")
if [[ "${PROVIDER_STATE}" == "ACTIVE" ]]; then
# Provider exists and is in the correct state.
print_success "Workload Identity Provider already exists and is ACTIVE."
else
if [[ "${PROVIDER_STATE}" == "DELETED" ]]; then
# Provider exists but is DELETED. Undelete the provider.
print_warning "Workload Identity Provider already exists but is in a DELETED state. Running 'undelete'."
gcloud iam workload-identity-pools providers undelete "${PROVIDER_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--workload-identity-pool="${POOL_NAME}"
else
# Provider exists but is in an unexpected state.
print_error "Provider '${PROVIDER_NAME}' is in an unexpected state: '${PROVIDER_STATE}'. Expected states are: {'ACTIVE', 'DELETED'}. Exiting"
exit 1
fi
fi
fi
# Step 4: Grant required permissions to the Workload Identity Pool
print_header "Step 4: Granting required permissions to Workload Identity Pool"
PRINCIPAL_SET="principalSet://iam.googleapis.com/${WIF_POOL_ID}/attribute.repository/${GITHUB_REPO}"
print_info "Skipped: Granting required permissions directly to the Workload Identity Pool..."
# Step 5: Create and Configure Service Account for Gemini CLI
print_header "Step 5: Create and Configure Service Account for Gemini CLI"
SERVICE_ACCOUNT_NAME="gemini-cli-${REPO_HASH}"
SERVICE_ACCOUNT_EMAIL="${SERVICE_ACCOUNT_NAME}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"
# Create service account if it doesn't exist
if ! gcloud iam service-accounts describe "${SERVICE_ACCOUNT_EMAIL}" --project="${GOOGLE_CLOUD_PROJECT}" &> /dev/null; then
print_info "Creating Service Account: ${SERVICE_ACCOUNT_NAME}"
gcloud iam service-accounts create "${SERVICE_ACCOUNT_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--display-name="Gemini CLI Service Account"
print_success "Service Account created: ${SERVICE_ACCOUNT_EMAIL}"
else
print_success "Service Account already exists: ${SERVICE_ACCOUNT_EMAIL}"
fi
# Grant permissions to the service account on the project
print_info "Granting 'Cloud AI Companion User' role to Service Account..."
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
--role="roles/cloudaicompanion.user" \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--condition=None
# Allow the service account to generate an access tokens
print_info "Granting 'Service Account Token Creator' role to Service Account..."
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
--role="roles/iam.serviceAccountTokenCreator" \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--condition=None
# Grant logging permissions to the service account
print_info "Granting 'Logging Writer' role to Service Account..."
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
--role="roles/logging.logWriter" \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--condition=None
# Grant monitoring permissions to the service account
print_info "Granting 'Monitoring Editor' role to Service Account..."
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
--role="roles/monitoring.editor" \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--condition=None
# Grant tracing permissions to the service account
print_info "Granting 'Cloud Trace Agent' role to Service Account..."
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
--role="roles/cloudtrace.agent" \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--condition=None
# Grant Vertex AI permissions to the service account
print_info "Granting 'Vertex AI User' role to Service Account..."
gcloud projects add-iam-policy-binding "${GOOGLE_CLOUD_PROJECT}" \
--role="roles/aiplatform.user" \
--member="serviceAccount:${SERVICE_ACCOUNT_EMAIL}" \
--condition=None
# Allow the Workload Identity Pool to impersonate the Service Account
print_info "Allowing GitHub Actions from '${GITHUB_REPO}' to impersonate the Service Account..."
gcloud iam service-accounts add-iam-policy-binding "${SERVICE_ACCOUNT_EMAIL}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--role="roles/iam.workloadIdentityUser" \
--member="${PRINCIPAL_SET}"
print_success "GitHub Actions can now impersonate ${SERVICE_ACCOUNT_NAME}"
# Get the full provider name for output
WIF_PROVIDER_FULL=$(gcloud iam workload-identity-pools providers describe "${PROVIDER_NAME}" \
--project="${GOOGLE_CLOUD_PROJECT}" \
--location="${GOOGLE_CLOUD_LOCATION}" \
--workload-identity-pool="${POOL_NAME}" \
--format="value(name)")
# Step 6: Output configuration
print_header "🎉 Setup Complete!"
echo ""
print_success "Direct Workload Identity Federation has been configured for your repository!"
echo ""
print_header "Permissions Granted"
echo ""
print_success "The following permissions have been automatically granted to your repository:"
echo "• roles/logging.logWriter - Write logs to Cloud Logging"
echo "• roles/monitoring.editor - Create and update metrics in Cloud Monitoring"
echo "• roles/cloudtrace.agent - Send traces to Cloud Trace"
echo "• roles/aiplatform.user - Use Vertex AI for model inference"
echo ""
print_success "A Service Account (${SERVICE_ACCOUNT_EMAIL}) was created with the following roles:"
echo "• roles/cloudaicompanion.user - Use Code Assist for model inference"
echo "• roles/iam.serviceAccountTokenCreator"
echo ""
# Check for `gh` CLI and set variables automatically if available
if command -v gh &> /dev/null; then
print_info "The 'gh' CLI is installed. Setting variables automatically..."
gh variable set GCP_WIF_PROVIDER --body "${WIF_PROVIDER_FULL}" --repo "${GITHUB_REPO}"
gh variable set GOOGLE_CLOUD_PROJECT --body "${GOOGLE_CLOUD_PROJECT}" --repo "${GITHUB_REPO}"
gh variable set GOOGLE_CLOUD_LOCATION --body "${GOOGLE_CLOUD_LOCATION}" --repo "${GITHUB_REPO}"
gh variable set SERVICE_ACCOUNT_EMAIL --body "${SERVICE_ACCOUNT_EMAIL}" --repo "${GITHUB_REPO}"
gh variable set GOOGLE_GENAI_USE_VERTEXAI --body "true" --repo "${GITHUB_REPO}"
print_success "GitHub variables have been set automatically!"
else
print_warning "The 'gh' CLI was not found. Either install it and rerun this script OR set the below variables manually."
echo " For manual setup, go to https://github.com/${GITHUB_REPO}/settings/variables/actions and add the following repository variables:"
echo ""
echo "🔑 Variable Name: GCP_WIF_PROVIDER"
echo " Variable Value: ${WIF_PROVIDER_FULL}"
echo ""
echo "☁️ Variable Name: GOOGLE_CLOUD_PROJECT"
echo " Variable Value: ${GOOGLE_CLOUD_PROJECT}"
echo ""
echo "☁️ Variable Name: GOOGLE_CLOUD_LOCATION"
echo " Variable Value: ${GOOGLE_CLOUD_LOCATION}"
echo ""
echo "☁️ Variable Name: SERVICE_ACCOUNT_EMAIL"
echo " Variable Value: ${SERVICE_ACCOUNT_EMAIL}"
echo ""
fi
print_success "Setup completed successfully! 🚀"
- 스크립트를 실행 파일로 만듭니다.
chmod +x setup_workload_identity.sh
- 스크립트를 실행합니다.
./setup_workload_identity.sh --repo {OWNER/REPO} --project {GOOGLE_CLOUD_PROJECT}
4. GitHub Actions 워크플로 만들기
- 소유한 GitHub 저장소를 체크아웃합니다.
git clone {YOUR_REPO}
cd {YOUR REPO}
/gemini-cli-extensions/security저장소에서 예시 워크플로yml스크립트를 복사하여 슬래시 명령어/security:analyze-github-pr를 호출하는 GitHub Actions 워크플로를 만듭니다.
git checkout -b workflow
mkdir .github/ && cd .github/
mkdir workflows/ && cd workflows/
curl -L https://raw.githubusercontent.com/gemini-cli-extensions/security/refs/heads/main/.github/workflows/gemini-review.yml -o gemini-review.yml
- GitHub의 원격 origin에 GitHub Actions 워크플로를 푸시합니다.
git add .github/workflows/gemini-review.yml
git commit -m "add new gha workflow"
git push --set-upstream origin workflow
5. 신규 및 기존 PR에서 보안 분석 워크플로 실행
GitHub 저장소에서 새 PR을 시작하거나 저장소 소유자 또는 참여자로 새 댓글 '@gemini-cli /review'를 게시합니다. 그러면 PR에 대한 보안 검토가 시작됩니다. 저장소에 커밋한 GitHub Actions 워크플로의 Gemini CLI 보안 확장 프로그램은 발견된 보안 문제를 심각도 카테고리('심각', '높음', '보통', '낮음')별로 태그합니다.
6. 추가 탐색
Gemini CLI 보안 확장 프로그램의 새로운 보안 기능이 포함된 맞춤 명령어 목록을 살펴보고 워크플로에서 사용해 보세요. 예를 들면 다음과 같습니다.
/security:scan-deps는 프로젝트의 종속 항목을 OSV.dev와 상호 참조합니다.
출시 노트에서 최신 기능과 버그 수정도 확인하세요.
7. 축하합니다
축하합니다. Gemini CLI 보안 확장 프로그램을 사용하여 PR의 보안 위험과 취약점을 분석하도록 GitHub 저장소를 구성했습니다.