在 Github 工作流程中的作业之间传递机密作为输出

问题描述 投票:0回答:3

我试图在作业之间传递 JWT 令牌,但有些东西阻止它正确传递。根据文档,如果我想在作业之间传递变量,我需要使用

outputs
,如here所述。我正在做的事情如下:

name: CI
on:
  pull_request:
    branches:
      - main
jobs:
  get-service-url:
    ...does something not interesting to us...
  get-auth-token:
    runs-on: ubuntu-latest
    outputs:
      API_TOKEN: ${{ steps.getauthtoken.outputs.API_TOKEN }}
    steps:
      - name: Get Token
        id: getauthtoken
        run: |
          API_TOKEN:<there is a full JWT token here>
          echo -n "API_TOKEN=$API_TOKEN" >> $GITHUB_OUTPUT
  use-token:
    runs-on: ubuntu-latest
    needs: [get-service-url,get-auth-token]
    name: Run Tests
    steps:
      - uses: actions/checkout@v3
      - name: Run tests
        run: |
          newman run ${{ github.workspace }}/tests/collections/my_collection.json --env-var "service_url=${{needs.get-service-url.outputs.service_URL}}" --env-var "auth_token=${{needs.get-auth-token.outputs.API_TOKEN}}"

因此,在运行期间,在我的输出中我看到:

Run newman run /home/runner/work/my-repo/my-repo/tests/collections/my_collection.json  --env-var "service_url=https://test.net" --env-var "auth_token="

起初我以为在作业之间传递令牌本身有问题。因此我尝试了 放置一个虚拟令牌并将其导出到输出中。在我的

get-auth-token
工作中,对输出的调用变成了:

echo -n "API_TOKEN=test" >> $GITHUB_OUTPUT

我在日志中看到了它:

--env-var "auth_token=test"

所以我在工作中传递它的方式很好。此外,令牌存在并且是正确的,因为我硬编码了一个令牌以简化我的测试。事实上,如果在我的

get-auth-token
工作中我尝试
echo $API_TOKEN
我在日志中看到
***
这让我明白 Github 正确地混淆了它。 然后我试着不要在工作之间传递它。因此,我在
newman run
命令之前创建了相同的硬编码令牌,并直接在
newman run
中引用它,tada!现在的日志是:

Run newman run /home/runner/work/my-repo/my-repo/tests/collections/my_collection.json  --env-var "service_url=https://test.net" --env-var "auth_token=***"

所以令牌就在那里!但我需要它来自另一份工作。有一些东西阻止令牌在作业之间传递,我不知道如何实现这一点。

bash github jwt github-actions
3个回答
5
投票

找到了实现这一目标的技巧。包括暂时“混淆”Github 眼中的秘密。

在检索秘密的工作中,我对其进行编码并将其导出到

GITHUB_OUTPUT

API_TOKEN_BASE64=`echo -n <my_secret> | base64 -w 0`
echo -n "API_TOKEN=$API_TOKEN_BASE64" >> $GITHUB_OUTPUT

在我需要秘密的工作中,我对其进行解码(并在需要的地方使用):

API_TOKEN=`echo -n ${{needs.get-auth-token.outputs.API_TOKEN}} | base64 --decode`

3
投票

为了确保我们不泄露秘密,可以使用加密。

我找到并成功使用的最简单方法是使用

gpg
base64
:

  1. 创建一个 GPG 密码并设置为名为

    PASSPHRASE
    的秘密(确保其强度强)。

  2. 创建加密和编码的输出(请忽略旧的输出语法),例如:

jobs:
  build:
    name: Build Docker image
    ...
    outputs:
      IMAGE_PATH: ${{ steps.out.outputs.IMAGE_PATH }}
    steps:
      - name: Process env vars
        run: |
          echo "IMAGE_PATH=/tmp/my-image.tar" >> "$GITHUB_ENV"

      - name: Create outputs
        id: out
        run: |
          echo "::set-output name=IMAGE_PATH::$(echo -n '${{ env.IMAGE_PATH }}' | gpg --symmetric --quiet --batch --passphrase ${{ secrets.PASSPHRASE }} --output - | base64 -w0)"

  1. 读取、解码和解密输出,例如:
  release-to-dev:
    needs: build
    ...
    steps:
      - name: Process outputs
        run: |
          echo "IMAGE_PATH=$(echo -n '${{ needs.build.outputs.IMAGE_PATH }}' | base64 -d | gpg --decrypt --quiet --batch --passphrase ${NOT_A_PASSPHRASE} --output -)" >> $GITHUB_ENV

原始

IMAGE_PATH
值现在将在其他作业中以环境变量中的明文形式提供,如
${IMAGE_PATH}
${{ env.IMAGE_PATH }}


0
投票

根据 GitHub Actions 文档,推荐的方法是使用秘密存储:

如果您想在作业或工作流程之间传递隐藏的机密,则应将机密存储在存储中,然后在后续作业或工作流程中检索它。

设置:

  1. 设置一个秘密存储来存储您将在工作流程中生成的秘密。例如,Vault。
  2. 生成用于读取和写入该秘密存储的密钥。将密钥存储为存储库机密。在以下示例工作流程中, 秘密名称是 SECRET_STORE_CREDENTIALS。有关更多信息,请参阅 “在 GitHub Actions 中使用机密。”
© www.soinside.com 2019 - 2024. All rights reserved.