关于密钥
密钥是在组织、仓库或仓库环境中创建的变量。您创建的密钥可在 GitHub Actions 工作流中使用。只有当您在工作流中显式包含密钥时,GitHub Actions 才能读取该密钥。
对于存储在组织级别的密钥,您可以使用访问策略来控制哪些仓库可以使用组织密钥。组织级密钥允许您在多个仓库之间共享密钥,从而减少创建重复密钥的需求。在一个位置更新组织密钥还可以确保更改在所有使用该密钥的仓库工作流中生效。
对于存储在环境级别的密钥,您可以启用必需的审阅者来控制对密钥的访问。在获得必需的审批者批准之前,工作流作业无法访问环境密钥。
注意
如果您的 GitHub Actions 工作流需要访问支持 OpenID Connect (OIDC) 的云提供商的资源,您可以配置您的工作流以直接验证到云提供商。这将允许您停止将这些凭据存储为长期密钥,并提供其他安全优势。有关更多信息,请参阅“关于使用 OpenID Connect 加强安全性”
密钥命名
以下规则适用于密钥名称
-
名称只能包含字母数字字符 (
[a-z]
,[A-Z]
,[0-9]
) 或下划线 (_
)。不允许使用空格。 -
名称不能以
GITHUB_
前缀开头。 -
名称不能以数字开头。
-
名称不区分大小写。
-
名称在其创建级别必须唯一。
例如,在环境级别创建的密钥必须在该环境中具有唯一名称,在仓库级别创建的密钥必须在该仓库中具有唯一名称,在组织级别创建的密钥必须在该级别具有唯一名称。
如果在多个级别存在具有相同名称的密钥,则最低级别的密钥优先。例如,如果组织级密钥与仓库级密钥具有相同的名称,则仓库级密钥优先。类似地,如果组织、仓库和环境都具有相同名称的密钥,则环境级密钥优先。
为了帮助确保 GitHub 在日志中删除您的密钥,请避免使用结构化数据作为密钥的值。例如,避免创建包含 JSON 或编码 Git Blob 的密钥。
访问您的密钥
要使某个密钥可用于某个操作,您必须在工作流程文件中将其设置为输入或环境变量。请查看操作的 README 文件,了解操作期望的输入和环境变量。更多信息,请参阅“GitHub Actions 的工作流程语法”。
如果您有权编辑工作流程文件,则可以在工作流程文件中使用和读取密钥。更多信息,请参阅“GitHub 的访问权限”。
警告
如果作业中使用了密钥,GitHub 会自动删除打印到日志中的密钥。您应该避免故意将密钥打印到日志中。
组织和仓库密钥在工作流程运行排队时读取,环境密钥在引用环境的作业开始时读取。
您还可以使用 REST API 管理密钥。更多信息,请参阅“GitHub Actions 密钥的 REST API 端点”。
限制凭据权限
生成凭据时,我们建议您授予尽可能少的权限。例如,不要使用个人凭据,而应使用部署密钥或服务帐户。如果只需要只读权限,请考虑授予只读权限,并尽可能限制访问。
生成个人访问令牌(经典版)时,请选择最少的必要范围。生成细粒度个人访问令牌时,请选择所需的最低权限和仓库访问权限。
请考虑使用 GitHub App 代替个人访问令牌,GitHub App 使用细粒度权限和短期令牌,类似于细粒度个人访问令牌。与个人访问令牌不同,GitHub App 不与用户绑定,因此即使安装该 App 的用户离开您的组织,工作流程也能继续运行。更多信息,请参阅“在 GitHub Actions 工作流程中使用 GitHub App 进行身份验证的 API 请求”。
注意
具有仓库协作者访问权限的用户可以使用 REST API 管理该仓库的密钥,而具有组织管理员访问权限的用户可以使用 REST API 管理该组织的密钥。更多信息,请参阅“GitHub Actions 密钥的 REST API 端点”。
创建仓库密钥
要为个人帐户仓库在 GitHub 上创建密钥或变量,您必须是仓库所有者。要为组织仓库在 GitHub 上创建密钥或变量,您必须具有admin
访问权限。最后,要通过 REST API 为个人帐户仓库或组织仓库创建密钥或变量,您必须具有协作者访问权限。
-
在 GitHub 上,导航到仓库的主页。
-
在您的仓库名称下,单击 设置。如果您看不到“设置”选项卡,请选择下拉菜单,然后单击设置。
-
在侧边栏的“安全”部分,选择 密钥和变量,然后单击操作。
-
单击密钥选项卡。
-
单击新建仓库密钥。
-
在名称字段中,键入密钥的名称。
-
在密钥字段中,输入密钥的值。
-
单击添加密钥。
如果您的仓库具有环境密钥或可以访问父组织中的密钥,则这些密钥也会在此页面上列出。
要了解有关 GitHub CLI 的更多信息,请参阅“关于 GitHub CLI”。
要添加仓库密钥,请使用gh secret set
子命令。将secret-name
替换为密钥的名称。
gh secret set SECRET_NAME
CLI 将提示您输入密钥值。或者,您可以从文件中读取密钥的值。
gh secret set SECRET_NAME < secret.txt
要列出仓库的所有密钥,请使用gh secret list
子命令。
创建环境密钥
要为个人帐户仓库中的环境创建密钥或变量,您必须是仓库所有者。要为组织仓库中的环境创建密钥或变量,您必须具有admin
访问权限。有关环境的更多信息,请参阅“管理部署环境”。
-
在 GitHub 上,导航到仓库的主页。
-
在您的仓库名称下,单击 设置。如果您看不到“设置”选项卡,请选择下拉菜单,然后单击设置。
-
在左侧侧边栏中,单击环境。
-
单击要向其中添加密钥的环境。
-
在环境密钥下,单击添加密钥。
-
在名称输入框中键入密钥的名称。
-
输入密钥的值。
-
单击添加密钥。
要添加环境密钥,请使用gh secret set
子命令,后跟--env
或-e
标志,然后是环境名称。
gh secret set --env ENV_NAME SECRET_NAME
要列出环境的所有密钥,请使用gh secret list
子命令,后跟--env
或-e
标志,然后是环境名称。
gh secret list --env ENV_NAME
创建组织密钥
注意
对于 GitHub Free,私有仓库无法访问组织级别的密钥和变量。有关升级 GitHub 订阅的更多信息,请参阅“升级您的帐户套餐”。
在组织中创建密钥或变量时,您可以使用策略来限制仓库的访问权限。例如,您可以授予所有仓库的访问权限,或仅限于私有仓库或指定的仓库列表。
组织所有者可以在组织级别创建密钥或变量。
-
在 GitHub 上,导航到组织的主页。
-
在您的组织名称下,单击 设置。如果您看不到“设置”选项卡,请选择下拉菜单,然后单击设置。
-
在侧边栏的“安全”部分,选择 密钥和变量,然后单击操作。
-
单击密钥选项卡。
-
单击新建组织密钥。
-
在名称输入框中键入密钥的名称。
-
输入密钥的值。
-
从仓库访问权限下拉列表中选择访问策略。
-
单击添加密钥。
注意
默认情况下,GitHub CLI 使用repo
和read:org
范围进行身份验证。要管理组织密钥,您还必须授权admin:org
范围。
gh auth login --scopes "admin:org"
要添加组织密钥,请使用gh secret set
子命令,后跟--org
或-o
标志,然后是组织名称。
gh secret set --org ORG_NAME SECRET_NAME
默认情况下,密钥仅对私有仓库可用。要指定密钥应对组织内的所有仓库可用,请使用--visibility
或-v
标志。
gh secret set --org ORG_NAME SECRET_NAME --visibility all
要指定密钥应对组织内的选定仓库可用,请使用--repos
或-r
标志。
gh secret set --org ORG_NAME SECRET_NAME --repos REPO-NAME-1, REPO-NAME-2
要列出组织的所有密钥,请使用gh secret list
子命令,后跟--org
或-o
标志,然后是组织名称。
gh secret list --org ORG_NAME
查看对组织级别密钥的访问权限
您可以检查正在应用于组织中密钥的哪些访问策略。
-
在 GitHub 上,导航到组织的主页。
-
在您的组织名称下,单击 设置。如果您看不到“设置”选项卡,请选择下拉菜单,然后单击设置。
-
在侧边栏的“安全”部分,选择 密钥和变量,然后单击操作。
-
密钥列表包含任何已配置的权限和策略。有关每个密钥的已配置权限的更多详细信息,请单击更新。
在工作流程中使用密钥
注意
- 除
GITHUB_TOKEN
外,从派生仓库触发工作流程时,不会将密钥传递给运行器。 - 密钥不会自动传递给可重用的工作流程。更多信息,请参阅“重用工作流程”。
要向操作提供密钥作为输入或环境变量,您可以使用secrets
上下文访问您在仓库中创建的密钥。更多信息,请参阅“访问有关工作流程运行的上下文信息”和“GitHub Actions 的工作流程语法”。
steps:
- name: Hello world action
with: # Set the secret as an input
super_secret: ${{ secrets.SuperSecret }}
env: # Or as an environment variable
super_secret: ${{ secrets.SuperSecret }}
无法在if:
条件语句中直接引用密钥。请考虑将密钥设置为作业级环境变量,然后引用环境变量以有条件地运行作业中的步骤。更多信息,请参阅“访问有关工作流程运行的上下文信息”和jobs.<job_id>.steps[*].if
。
如果未设置密钥,则引用密钥的表达式的返回值(例如示例中的${{ secrets.SuperSecret }}
)将为空字符串。
尽可能避免从命令行在进程之间传递密钥。命令行进程可能对其他用户可见(使用ps
命令)或被安全审核事件捕获。为了帮助保护密钥,请考虑使用环境变量、STDIN
或目标进程支持的其他机制。
如果必须在命令行中传递密钥,则将其括在正确的引用规则中。密钥通常包含特殊字符,这些字符可能会无意中影响您的 shell。要转义这些特殊字符,请使用环境变量的引用。例如
使用 Bash 的示例
steps:
- shell: bash
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "$SUPER_SECRET"
使用 PowerShell 的示例
steps:
- shell: pwsh
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "$env:SUPER_SECRET"
使用 Cmd.exe 的示例
steps:
- shell: cmd
env:
SUPER_SECRET: ${{ secrets.SuperSecret }}
run: |
example-command "%SUPER_SECRET%"
密钥限制
您可以存储最多 1,000 个组织密钥、100 个仓库密钥和 100 个环境密钥。
在仓库中创建的工作流程可以访问以下数量的密钥
- 所有 100 个仓库密钥。
- 如果仓库被分配访问超过 100 个组织机密,则工作流程只能使用前 100 个组织机密(按机密名称字母顺序排序)。
- 所有 100 个环境机密。
机密大小限制为 48 KB。要存储更大的机密,请参阅下面的“存储大型机密”解决方法。
存储大型机密
要使用大于 48 KB 的机密,您可以使用一种变通方法将机密存储在您的仓库中,并将解密密码保存为 GitHub 上的机密。例如,您可以使用gpg
在将加密文件检入 GitHub 上的仓库之前,在本地加密包含机密的文件。有关更多信息,请参阅“gpg 手册页”。
警告
请注意,您的机密在工作流程运行时不会被打印出来。使用此解决方法时,GitHub 不会删除日志中打印的机密。
-
从您的终端运行以下命令,使用
gpg
和 AES256 密码算法加密包含您机密的文件。在此示例中,my_secret.json
是包含机密的文件。gpg --symmetric --cipher-algo AES256 my_secret.json
-
系统将提示您输入密码。请记住此密码,因为您需要在 GitHub 上创建一个使用此密码作为值的新机密。
-
创建一个包含密码的新机密。例如,创建一个名为
LARGE_SECRET_PASSPHRASE
的新机密,并将机密的 value 设置为您在上一步中使用的密码。 -
将您的加密文件复制到仓库中的路径并提交它。在此示例中,加密文件为
my_secret.json.gpg
。警告
确保复制以
.gpg
文件扩展名结尾的加密my_secret.json.gpg
文件,而**不是**未加密的my_secret.json
文件。git add my_secret.json.gpg git commit -m "Add new secret JSON file"
-
在您的仓库中创建一个 shell 脚本以解密机密文件。在此示例中,脚本名为
decrypt_secret.sh
。Shell #!/bin/sh # Decrypt the file mkdir $HOME/secrets # --batch to prevent interactive command # --yes to assume "yes" for questions gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \ --output $HOME/secrets/my_secret.json my_secret.json.gpg
#!/bin/sh # Decrypt the file mkdir $HOME/secrets # --batch to prevent interactive command # --yes to assume "yes" for questions gpg --quiet --batch --yes --decrypt --passphrase="$LARGE_SECRET_PASSPHRASE" \ --output $HOME/secrets/my_secret.json my_secret.json.gpg
-
在将其检入您的仓库之前,请确保您的 shell 脚本是可执行的。
chmod +x decrypt_secret.sh git add decrypt_secret.sh git commit -m "Add new decryption script" git push
-
在您的 GitHub Actions 工作流程中,使用
step
调用 shell 脚本并解密机密。要在工作流程运行的环境中拥有您的仓库副本,您需要使用actions/checkout
操作。使用相对于仓库根目录的run
命令引用您的 shell 脚本。name: Workflows with large secrets on: push jobs: my-job: name: My Job runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Decrypt large secret run: ./decrypt_secret.sh env: LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }} # This command is just an example to show your secret being printed # Ensure you remove any print statements of your secrets. GitHub does # not hide secrets that use this workaround. - name: Test printing your secret (Remove this step in production) run: cat $HOME/secrets/my_secret.json
将 Base64 二进制 Blob 存储为机密
您可以使用 Base64 编码将小的二进制 Blob 存储为机密。然后,您可以在工作流程中引用机密,并对其进行解码以便在运行程序上使用。有关大小限制,请参阅“在 GitHub Actions 中使用机密”。
注意
请注意,Base64 仅将二进制数据转换为文本,不能替代实际的加密。
-
使用
base64
将您的文件编码为 Base64 字符串。例如在 macOS 上,您可以运行
base64 -i cert.der -o cert.base64
在 Linux 上,您可以运行
base64 -w 0 cert.der > cert.base64
-
创建一个包含 Base64 字符串的机密。例如
$ gh secret set CERTIFICATE_BASE64 < cert.base64 ✓ Set secret CERTIFICATE_BASE64 for octocat/octorepo
-
要从您的运行程序访问 Base64 字符串,请将机密传递到
base64 --decode
。例如name: Retrieve Base64 secret on: push: branches: [ octo-branch ] jobs: decode-secret: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Retrieve the secret and decode it to a file env: CERTIFICATE_BASE64: ${{ secrets.CERTIFICATE_BASE64 }} run: | echo $CERTIFICATE_BASE64 | base64 --decode > cert.der - name: Show certificate information run: | openssl x509 -in cert.der -inform DER -text -noout
注意
使用其他 shell 可能需要不同的命令才能将机密解码为文件。在 Windows 运行程序上,我们建议使用带有shell: bash
的 bash shell来使用上面run
步骤中的命令。
从工作流程运行日志中删除机密
GitHub Actions 会自动删除打印到工作流程日志中的所有 GitHub 机密的內容。
GitHub Actions 还删除被识别为敏感信息但未存储为机密的信息。目前 GitHub 支持以下内容:
- 32 字节和 64 字节的 Azure 密钥
- Azure AD 客户端应用密码
- Azure 缓存密钥
- Azure 容器注册表密钥
- Azure 函数主机密钥
- Azure 搜索密钥
- 数据库连接字符串
- HTTP Bearer 令牌标头
- JWT
- NPM 作者令牌
- NuGet API 密钥
- v1 GitHub 安装令牌
- v2 GitHub 安装令牌(
ghp
、gho
、ghu
、ghs
、ghr
) - v2 GitHub PAT
注意
如果您希望自动删除其他类型的敏感信息,请在我们的社区讨论中与我们联系。
作为最佳实践习惯,您应该使用::add-mask::VALUE
屏蔽所有不是 GitHub 机密的敏感信息。这会导致该值被视为机密并从日志中删除。有关屏蔽数据的更多信息,请参阅“GitHub Actions 的工作流程命令”。
机密的删除由您的工作流程运行程序执行。这意味着只有在作业中使用了机密并且运行程序可以访问该机密时,才会删除该机密。如果未删除的机密被发送到工作流程运行日志,则应删除日志并轮换机密。有关删除日志的信息,请参阅“使用工作流程运行日志”。