Skip to main content
We publish frequent updates to our documentation, and translation of this page may still be in progress. For the most current information, please visit the English documentation.

加密机密

加密密码可让您将敏感信息存储在您的组织、仓库或者仓库环境 中。

关于加密密码

机密是在组织、存储库或存储库环境中创建的加密变量。 您创建的机密可用于 GitHub Actions 工作流程。 在机密到达 GitHub 之前,GitHub 使用 libsodium 密封盒帮助确保对机密加密,并且在你于工作流中使用它们之前一直保持加密状态。

对于存储在组织级别的密码,可以使用访问策略来控制哪些仓库可以使用组织密码。 组织级密码允许在多个仓库之间共享密码,从而减少创建重复密码的需要。 在一个位置更新组织密码还可确保更改在使用该密码的所有仓库工作流程中生效。

对于存储在环境级别的机密,您可以启用所需的审查者来控制对机密的访问。 在必要的审查者授予批准之前,工作流程作业无法访问环境机密。

注意:如果 GitHub Actions 工作流需要访问支持 OpenID Connect (OIDC) 的云提供商提供的资源,则可以将工作流配置为直接向云提供商进行身份验证。 这样就可以停止将这些凭据存储为长期存在的机密,并提供其他安全优势。 有关详细信息,请参阅“关于使用 OpenID Connect 进行安全强化

命名您的密码

以下规则适用于密码名称:

  • 名称只能包含字母数字字符([a-z][A-Z][0-9])或下划线 (_)。 不允许空格。

  • 名称不能以 GITHUB_ 前缀开头。

  • 名称不能以数字开头。

  • 名称不区分大小写。

  • 名称在所创建的级别上必须是唯一的。

    例如,在环境级别创建的机密必须在环境中具有唯一的名称,在仓库级别创建的机密必须在该仓库中具有唯一的名称,而在组织级别创建的机密必须在该级别具有独特的名称。

    如果具有相同名称的机密存在于多个级别,则级别最低的机密优先。 例如,如果组织级别密码的名称与仓库级别的密码相同,则仓库级别的密码优先。 同样,如果组织、存储库和环境都具有同名的机密,则环境级机密优先。

为帮助确保 GitHub 在日志中编写密码,请勿将结构化数据用作密码的值。 例如,避免创建包含 JSON 或编码 Git blob 的密码。

访问您的密码

为使密码用于操作,必须将密码设置为工作流程文件中的输入或环境变量。 查看操作的自述文件以了解操作预期的输入和环境变量。 有关详细信息,请参阅“GitHub Actions 的工作流语法”。

如果您拥有编辑文件的权限,便可在工作流程文件中使用和读取加密密码。 有关详细信息,请参阅“对 GitHub 的访问权限”。

警告:GitHub 自动将密码编写到日志,但应避免有意将密码打印到日志。

当工作流程运行排队时读取组织和仓库机密,在引用环境的作业开始时读取环境机密。

您还可以使用 REST API 管理密码。 有关详细信息,请参阅“机密”。

限制凭据权限

生成凭据时,建议尽可能授予最低的权限。 例如,请改为使用部署密钥或服务帐户,而不是使用个人凭据。 请考虑授予只读权限(如果这是所需的全部权限)并尽可能限制访问。 生成 personal access token (classic) 时,请选择所需的最少范围。生成 fine-grained personal access token 时,请选择所需的最小存储库访问权限。

注意:可以使用 REST API 来管理机密。 有关详细信息,请参阅“GitHub Actions 机密 API”。

为仓库创建加密密码

要为个人帐户存储库创建机密或变量,你必须是存储库所有者。 要为组织存储库创建机密或变量,你必须拥有 admin 访问权限。

  1. 在 GitHub.com 上,导航到存储库的主页。 1. 在存储库名称下,单击 “设置”。 “存储库设置”按钮 1. 在边栏的“安全性”部分中,选择“ 机密和变量”、然后单击“操作” 。 1. 单击“机密”选项卡。“存储库机密”选项卡
  2. 单击“新建存储库机密”。
  3. 在“名称”输入框中键入机密名称。
  4. 输入密码的值。
  5. 单击“添加机密”。

如果您的存储库具有环境机密或可以访问上级组织的机密,则这些机密也会在此页面上列出。

若要详细了解 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 访问权限。

  1. 在 GitHub.com 上,导航到存储库的主页。 1. 在存储库名称下,单击 “设置”。 “存储库设置”按钮 1. 在左侧边栏中,单击“环境”。
  2. 单击要向其添加机密的环境。
  3. 在“环境机密”下,单击“添加机密” 。
  4. 在“名称”输入框中键入机密名称。
  5. 输入密码的值。
  6. 单击“添加机密”。

若要为环境添加机密,请使用 gh secret set 子命令与 --env-e 标志,后接环境名称。

gh secret set --env ENV_NAME SECRET_NAME

若要列出环境的所有机密,请使用 gh secret list 子命令与 --env-e 标志,后接环境名称。

gh secret list --env ENV_NAME

为组织创建加密密码

在组织中创建机密或变量时,可以使用策略来限制存储库的访问。 例如,您可以将访问权限授予所有仓库,也可以限制仅私有仓库或指定的仓库列表拥有访问权限。

要在组织级别创建机密或变量,必须拥有 admin 访问权限。

  1. 在 GitHub.com 上,导航到组织的主页。 1. 在组织名称下,单击“设置”。 组织设置按钮 1. 在边栏的“安全性”部分中,选择“ 机密和变量”、然后单击“操作” 。 1. 单击“机密”选项卡。“组织机密”选项卡
  2. 单击“新建组织机密”。
  3. 在“名称”输入框中键入机密名称。
  4. 输入“机密”的值。
  5. 从“存储库访问”下拉列表中,选择访问策略。
  6. 单击“添加机密”。

注意:默认情况下,GitHub CLI 使用 reporead: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

审查对组织级别密码的访问权限

您可以检查哪些访问策略正被应用于组织中的密码。

  1. 在 GitHub.com 上,导航到组织的主页。 1. 在组织名称下,单击“设置”。 组织设置按钮 1. 在边栏的“安全性”部分中,选择“ 机密和变量”、然后单击“操作” 。
  2. 密码列表包括任何已配置的权限和策略。 例如:机密列表
  3. 若要详细了解已为每个机密配置的权限,请单击“更新”。

在工作流中使用加密的机密

注意:

  • 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 上将解密短语存储为机密。 例如,在将加密文件签入 GitHub 上的存储库之前,可在本地使用 gpg 加密包含机密的文件。 有关详细信息,请参阅“gpg 手册页”。

警告:请注意,工作流运行时不会打印你的机密。 使用此解决方法时,GitHub 不会编写日志中印出的密码。

  1. 从终端运行以下命令,使用 gpg 和 AES256 密码算法加密包含机密的文件。 在本例中,my_secret.json 是包含机密的文件。

    gpg --symmetric --cipher-algo AES256 my_secret.json
    
  2. 将会提示您输入密码短语。 请记住该密码短语,因为需要在使用该密码短语作为值的 GitHub 上创建新密码。

  3. 创建包含密码短语的新密码。 例如,使用名称 LARGE_SECRET_PASSPHRASE 创建新机密,并将机密的值设置为在上述步骤中使用的通行短语。

  4. 将加密的文件复制到存储库并提交。 在此示例中,加密的文件为 my_secret.json.gpg

    警告:请务必复制以 .gpg 文件扩展名结尾的 my_secret.json.gpg 加密文件,而不是未加密的 my_secret.json 文件。

    git add my_secret.json.gpg
    git commit -m "Add new encrypted secret JSON file"
    
  5. 在存储库中创建 shell 脚本来解密机密文件。 在本例中,机密命名为 decrypt_secret.sh

    #!/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
    
  6. 确保 shell 脚本在检入仓库之前可执行。

    chmod +x decrypt_secret.sh
    git add decrypt_secret.sh
    git commit -m "Add new decryption script"
    git push
    
  7. 在 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@v3
          - 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 存储为机密。 然后,您可以在工作流程中引用该机密,并对其进行解码以在运行器上使用。 有关大小限制,请参阅“机密限制”

注意:Base64 仅将二进制转换为文本,并不能替代实际加密。

  1. 使用 base64 将文件编码为 Base64 字符串。 例如:

    $ base64 -i cert.der -o cert.base64
    
  2. 创建包含 Base64 字符串的机密。 例如:

    $ gh secret set CERTIFICATE_BASE64 < cert.base64
    ✓ Set secret CERTIFICATE_BASE64 for octocat/octorepo
    
  3. 要从运行器访问 Base64 字符串,请将机密传送到 base64 --decode。 例如:

    name: Retrieve Base64 secret
    on:
      push:
        branches: [ octo-branch ]
    jobs:
      decode-secret:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v3
          - 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