为什么该操作无法访问机密?

9

我正在尝试创建一个工作流,使用Github Actions将Nuget包部署到Github Package Repository。

在这种情况下:

  • 该存储库位于一个组织内
  • 我是该组织的所有者
  • 我对存储库具有管理员访问权限
  • 该存储库列出了secrets
  • 提交是我的
  • 提交是对分支的直接提交

但该操作无法访问secrets。

echo

下面是我要执行的工作流程:

name: Build and Publish
on:
push:
  branches:
    - gh-packages
jobs:
build_and_publish:
env:
  ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }}
name: Publish Packages to NuGet
runs-on: ubuntu-latest
steps:
  - uses: actions/checkout@v2
  - uses: actions/setup-dotnet@v1
    with:
      dotnet-version: "3.0.100"
  - name: Dump Github Context
    env:
      CONTEXT: ${{ toJson(github) }}
      SECRETS: ${{ toJson(secrets) }}
      TOK: ${{ secrets.ACCESS_TOKEN }}
      TEST: ${{ secrets.TEST }
    run: |
      echo $ACCESS_TOKEN
      echo $TOK
      echo $TEST
      echo $GITHUB_TOKEN
      echo "$SECRETS"
      echo "$CONTEXT"
  - name: Setup Config
    run: sed "s/ACCESS_TOKEN/$ACCESS_TOKEN/g" .nuget.config > nuget.config
  - run: cat nuget.config
  - name: Build
    run: dotnet build -c Release
  - name: Publish
    run: chmod +x ./push.sh && ./push.sh

GITHUB_TOKEN 和 ACCESS_TOKEN 等自定义密钥均无法使用。

补充 01:

即使将环境变量名称设置为 GITHUB_TOKEN,也似乎无法使用。

name: Build and Publish
env:
   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
...

GITHUB_TOKEN


3
任何秘密值(以及某些编码,例如Base64的秘密值)都会从输出中清除,并在日志中用星号替换,这是最佳安全实践。无论如何呈现它们,这都是正确的:如果日志文本匹配了一个秘密,它就会被清除。它们仍然可以被您的脚本和工作流访问,但不能被查看。 - bk2204
这是一个相当酷的功能,在文档中不是非常清晰,但绝对是Github团队的良好安全措施。我猜你可以在每个字符后面打印带有空格的秘密...我再次更新我的答案。 - Ben Winding
4个回答

9
假设您已将密码传递到操作中:
env: 
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

enter image description here

那么 ***隐藏文本是Github Actions的预期行为

正如您所看到的,我可以获取(并使用)环境变量的值,但不会暴露密码。

这是因为它们是机密信息。Actions输出明确清除了机密信息,并且不会显示它们。

文件内容仍包含机密内容。

打印出密码是可能的,但这是一种非常糟糕的做法-请使用以下命令,该命令规避了Github的安全措施,以防止机密信息泄露到日志中。

run: echo MYSECRET | sed -e 's/\(.\)/\1 /g'
# this will print "M Y S E C R E T"

只需用你要打印的秘密替换MYSECRET,例如$GITHUB_TOKEN

有关秘密详细说明,请参阅GitHub文档(链接)


尝试通过设置环境变量来访问值也不起作用。请检查问题的最新更新。 - Shanaka Rusith
我已经做了完全相同的事情。请检查代码片段。 - Shanaka Rusith
尝试逐个传递每个秘密,而不使用 toJson 函数。同时只需使用 ${{ secrets.GITHUB_TOKEN }},无需将其重命名为 ACCESS_TOKEN。此外,显然 这个问题 表明,如果在命令中不包含引号,则可以 echo 每个秘密。 - Ben Winding
我再次编辑了我的答案,在页面底部有一个官方方法(在我的答案底部的链接中),希望能帮到你。 - Ben Winding

5
这个问题是由于我的一个误解引起的,我认为如果正确传递了秘密值,它们应该在日志中显示出来。
我结合了Ben Windingbk2204的答案来澄清一下。 行动日志中删除了秘密值。不要期望在行动日志中看到实际值。获取已删除的文本表示该值已传递给操作。你可以在脚本内使用该值,但无法在日志中看到它们。查看Ben's Answer以了解如何查看值,但不建议这样做。

3
如果您想记录某些内容以指示该秘密存在,请尝试以下操作:
auth_token="${{ inputs.auth_token }}"
echo "auth_token length: ${#auth_token}"

${#auth_token} 将会返回这个密钥的长度。你可以在日志中找到以下信息:

auth_token length: 72

这让你知道 auth_token 存在并且有多长,但不会降低令牌的安全性。


-2
阅读了github文档访问您的秘密的所有内容,最后我看到了这个,它在秘密的最佳实践和标准用例方面给了我很多启示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接