使用 Gemini CLI 安全扩展程序进行 GitHub 拉取请求审核

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 扩展程序。如果您想了解扩展程序的工作原理,请参阅 Codelab:Gemini CLI 扩展程序使用入门

在此 Codelab 中,您将学习如何在 GitHub 代码库中设置 Gemini CLI 安全扩展程序。我们不会建议您针对代码库打开 PR 来触发安全漏洞发现。

2. 准备工作

创建或选择项目

  1. Google Cloud 控制台的项目选择器页面上,选择或创建一个 Google Cloud 项目
  2. 确保您的 Cloud 项目已启用结算功能。了解如何验证结算信息
  3. 打开 Cloud Shell,它是在 Google Cloud 中运行的命令行环境。点击 Google Cloud 控制台顶部的激活 Cloud Shell

“激活 Cloud Shell”按钮图片

  1. 连接到 Cloud Shell 后,使用以下命令检查您是否已通过身份验证,以及项目是否已设置为您的项目 ID:
gcloud auth list
  1. 运行以下命令,确认 gcloud 命令已配置为使用您的项目。
gcloud config list project
  1. 如果项目未设置,请使用以下命令进行设置:
gcloud config set project ${GOOGLE_CLOUD_PROJECT}

3. 设置从 GitHub 到 Google Cloud 的身份验证

运作方式

GitHub Actions 工作流

建议使用工作负载身份联合GitHub Actions 向 Google Cloud 进行身份验证。

  1. 对于每个 GitHub Actions 工作流 运行作业GitHub 作为外部身份提供方会颁发已签名的 JWT(JSON Web 令牌)。此令牌包含 repositoryworkflowjob_workflow_ref 等“声明”,可作为相应跑者的数字身份证。在此实验中,您将创建一个 GitHub Actions 工作流,其中包含一个使用 google-github-actions/run-gemini-cli 操作的任务,该任务将从 GitHub 请求 JWT 并将此令牌发送到 Google Cloud 中的 Security Token Service (STS)
  2. 您将在 Google Cloud 中配置工作负载身份池提供方,方法是将发布者网址设置为官方 GitHub 令牌服务网址 https://token.actions.githubusercontent.com,并定义您的“属性映射”,这些映射通常包括代码库和分支名称。Google Cloud STS 会根据工作负载身份池规则验证 JWT。如果一切(包括属性映射)都通过检查,STS 会将 GitHub 令牌换成有效期较短的 Google Cloud 联合访问令牌
  3. 现在,GitHub Actions 工作流中的 google-github-actions/run-gemini-cli 操作可以使用短期 Google Cloud 联合访问令牌来“模拟”连接到工作负载身份池的服务账号。关联的服务账号需要具有必要的 IAM 角色和权限才能访问任何 Google Cloud 资源和服务。

与 Gemini API 密钥相比,使用工作负载身份联合的优势

可以使用 Gemini API 密钥对源自 GitHub Actions 的 Gemini CLI 调用进行身份验证,这需要创建一个名为 GEMINI_API_KEY 的新 GitHub Actions Secret,并使用相应的密钥值。不过,出于以下安全考虑,我们不建议这样做:

  • Gemini API 密钥可以从各自的 IAM 角色绑定中获得广泛的权限。一旦遭到入侵,它们就会开放对各种 Google Cloud 资源和服务的访问权限。工作负载身份联合使用服务账号和短期有效的访问令牌,可显著增强身份验证的安全性。
  • Gemini API 密钥在大规模使用时也难以管理。确定哪些工作流正在使用泄露的密钥需要时间。手动轮替密钥也需要时间。另一方面,您可以通过 Cloud 控制台轻松查找、修改和删除与您的代码库关联的工作负载身份池和提供方。
  • 使用 Gemini API 密钥时,您必须始终仔细检查,确保不会在任何访问或调试日志中意外暴露它们。借助工作负载身份联合,您无需存储任何 GitHub Actions 工作流 Secret,只需存储变量,而变量的敏感性本来就较低。

配置 GitHub Actions 和 Google Cloud

  1. 在 Cloud Shell 中,登录您的 GitHub 账号。
gh auth login
  1. 创建一个新文件 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! 🚀"
  1. 将脚本转换为可执行文件。
chmod +x setup_workload_identity.sh
  1. 运行脚本。
./setup_workload_identity.sh --repo {OWNER/REPO} --project {GOOGLE_CLOUD_PROJECT}

4. 创建 GitHub Actions 工作流

  1. 签出您拥有的 GitHub 代码库。
git clone {YOUR_REPO}
cd {YOUR REPO}
  1. 通过从 /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
  1. 将 GitHub Actions 工作流推送到 GitHub 上的远程源。
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 安全扩展程序会按严重程度类别(从“严重”“高”“中”到“低”)标记其发现的任何安全问题。

以下是针对新 PR 的安全审核的示例,以及针对现有 PR 的安全审核的示例

6. 进一步探索

我们建议您探索不断增加的自定义命令列表,其中包含 Gemini CLI 安全扩展程序中的新安全功能,并开始在工作流程中使用这些命令。例如:

  • /security:scan-deps 会将项目的依赖项与 OSV.dev 进行交叉引用。

您还可以查看版本说明,了解最新功能和 bug 修复。

7. 恭喜

恭喜!您已成功配置 GitHub 代码库,以使用 Gemini CLI 安全扩展程序分析 PR 中的安全风险和漏洞。