GitHub Actions 权限控制 #

权限控制是GitHub Actions安全的核心。本节介绍如何配置和管理权限。

权限概述 #

什么是权限? #

权限定义了GITHUB_TOKEN可以执行的操作:

  • 读取仓库内容
  • 写入PR评论
  • 创建Release
  • 部署到环境

权限级别 #

级别 作用域
组织级 所有仓库默认权限
仓库级 当前仓库默认权限
工作流级 单个工作流权限
作业级 单个作业权限

配置权限 #

工作流级权限 #

yaml
name: My Workflow

permissions:
  contents: read
  pull-requests: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

作业级权限 #

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
      - uses: actions/checkout@v4

读写权限 #

yaml
permissions:
  contents: read      # 读取仓库内容
  issues: write       # 写入Issue
  pull-requests: write # 写入PR
  packages: write     # 写入包
  deployments: write  # 写入部署
  checks: write       # 写入检查
  statuses: write     # 写入状态
  pages: write        # 写入Pages
  actions: read       # 读取Actions
  security-events: write # 写入安全事件

只读权限 #

yaml
permissions:
  contents: read
  actions: read

无权限 #

yaml
permissions: {}

所有权限 #

yaml
permissions: write-all

仓库设置 #

配置默认权限 #

  1. 进入仓库设置
  2. 点击 “Actions” → “General”
  3. 在 “Workflow permissions” 中配置

权限选项 #

选项 描述
Read repository contents 只读权限
Read and write permissions 读写权限

限制Actions #

可以限制哪些Actions可以运行:

  • Allow all actions
  • Allow local actions only
  • Allow selected actions

GITHUB_TOKEN权限 #

默认权限 #

权限 Fork PR 同仓库PR
contents read read
issues none write
pull-requests none write

使用GITHUB_TOKEN #

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
      
      - uses: actions/github-script@v7
        with:
          script: |
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: 'Build completed!'
            })

OpenID Connect #

什么是OIDC? #

OpenID Connect (OIDC) 允许工作流使用短期令牌访问云服务:

  • 无需存储长期凭证
  • 自动轮换令牌
  • 细粒度权限控制

配置OIDC #

yaml
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/myRole
          aws-region: us-east-1

AWS配置 #

  1. 创建IAM角色
  2. 配置信任策略:
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
        },
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:owner/repo:*"
        }
      }
    }
  ]
}

Azure配置 #

yaml
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

GCP配置 #

yaml
permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: projects/123456789/locations/global/workloadIdentityPools/my-pool/providers/my-provider
          service_account: my-sa@my-project.iam.gserviceaccount.com

环境保护 #

配置环境保护 #

  1. 进入仓库设置
  2. 点击 “Environments”
  3. 创建或编辑环境

保护规则 #

规则 描述
Required reviewers 需要审批
Wait timer 等待时间
Deployment branches 限制分支

使用环境 #

yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://example.com
    steps:
      - run: ./deploy.sh

环境密钥 #

环境可以有自己的密钥:

yaml
jobs:
  deploy:
    environment: production
    steps:
      - env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Fork PR安全 #

默认行为 #

来自Fork的PR:

  • 无法访问密钥
  • GITHUB_TOKEN权限受限
  • 需要维护者批准

使用pull_request_target #

yaml
on:
  pull_request_target:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          repository: ${{ github.event.pull_request.head.repo.full_name }}
          ref: ${{ github.event.pull_request.head.sha }}

⚠️ 注意:pull_request_target可以访问密钥,需要谨慎使用。

最佳实践 #

1. 使用最小权限 #

yaml
permissions:
  contents: read

2. 使用OIDC代替密钥 #

yaml
permissions:
  id-token: write
  contents: read

3. 使用环境保护 #

yaml
environment: production

4. 限制Actions来源 #

在仓库设置中限制可用的Actions。

5. 审查第三方Actions #

使用前检查Actions的源代码和权限需求。

下一步学习 #

小结 #

  • 使用最小权限原则
  • 配置工作流和作业级权限
  • 使用OIDC代替长期凭证
  • 使用环境保护敏感操作
  • 谨慎处理Fork PR
  • 审查第三方Actions
最后更新:2026-03-28