『入る学科間違えた高専生』の日記

プログラミングのコードを書いたりする予定です。あとは日記等。あといつまで高専生やねん

GitHub Actions で生成したシークレットをジョブ間を outputs で共有する

はじめに

GitHub Actions のジョブ内で生成したシークレットと判定されるものは共有することができません。

上記のように、 outputs に指定したシークレットが自動で共有からスキップされていることがわかります。
以下の図のように、はじめにアクセストークンを発行し、 matrix で動かすジョブで生成したアクセストークンを共有して使用することを前提とします。

結論

単純な回答としては、 outputs で共有する前に暗号化して使用する前に復号することで使用することができます。
また暗号化・復号できるということは漏洩した際のリスクもあるのでアクセストークン等であれば使用後は直ちに取り消しを行ったり安全措置を行うなどの検討が必要になります。

具体例

暗号化・復号のステップとして以下を使用しました。

github.com

以下は、上記のアクションを使用した例です。

name: Sample

on: [push]

jobs:
  generate-access-token:
    runs-on: ubuntu-latest

    outputs:
      access_token: ${{ steps.encrypt-secret.outputs.out }}

    steps:
    - name: Generate access token
      id: generate-access-token
      run: |
        token = generate_access_token
        echo "token=${token}" >> "${GITHUB_OUTPUT}"

    - uses: cloudposse/github-action-secret-outputs@main
      id: encrypt-secret
      with:
        in: ${{ steps.generate-access-token.outputs.token }}
        on: encode
        secret: ${{ secrets.PASSPHRASE }}

  use-access-token:
    runs-on: ubuntu-latest
    needs:
    - generate-access-token

    strategy:
      matrix:
        python-version: ["3.10", "3.11"]

    steps:
    - uses: cloudposse/github-action-secret-outputs@main
      id: decrypt-secret
      with:
        in: ${{ needs.generate-access-token.outputs.access_token }}
        on: decode
        secret: ${{ secrets.PASSPHRASE }}

    - name: Use access_token
      env:
        TOKEN: ${{ steps.decrypt-secret.outputs.out }}
      run: echo "Token: ${TOKEN}"

  revoke:
    runs-on: ubuntu-latest
    needs:
    - generate-access-token
    - use-access-token
    if: always()

    steps:
    - uses: cloudposse/github-action-secret-outputs@main
      id: decrypt-secret
      with:
        in: ${{ needs.generate-access-token.outputs.access_token }}
        on: decode
        secret: ${{ secrets.PASSPHRASE }}

    - name: Revoke access_token
      env:
        TOKEN: ${{ steps.decrypt-secret.outputs.out }}
      run: revoke_access_token "${TOKEN}"

説明

  1. generate-access-token ステップでアクセストークンを何らかの方法を使用して取得する
  2. cloudposse/github-action-secret-outputs を使用して暗号化を行う
    • リポジトリ等のシークレットに PASSPHRASE を追加済み
  3. generate-access-token ジョブの outputs として 2. の出力を指定する
  4. use-access-token ジョブは generate-access-token の完了を必要とするように設定する
  5. cloudposse/github-action-secret-outputs を使用して generate-access-token ジョブの出力から復号を行う
  6. 使用
  7. revoke ジョブで 5. と同様に復号を行い最後に何らかの方法でアクセストークンの取り消しを行う

最後に

確かに以下のように、使うたびにアクセストークン等のシークレットを発行するのでもいいが、アクセストークンを発行するためにもレートリミットがあったりする場合は今回のように前のジョブで予め発行して共有することもあると思うので備忘録としてこの記事を書いた。

というもの、最近は個人でも GitHub Personal Access Token を使用することも極力やめ GitHub App のアクセストークンを発行し使用することを心がけているからです。
GitHub App のアクセストークンを発行するものは以下の CLI を作っているので使用することにしています。(シークレットに秘密鍵を書き込んだりしないといけないが...)

github.com

また、 @shogo82148 さんが提供している以下のアクションを使用すると、自分で GitHub App を管理しなくてもアクセストークンを取得することができるようになる。

github.com

ただ、 GitHub Actions 限定のものなので他の CI 上で動かしたいというときは別の手段を取る必要があります。