目次:
GitHub ActionsのSecretsにはJSON形式で登録してはいけない
GitHub Actionsでは外部に露出しない環境変数として、Secrets変数を設定できます。実質的・内部的にはGitHub Actionsデフォルト環境変数の一つであると言えます。
GitHub ActionsにおけるSecrets変数は構造などをもたない1行のトークンなどが想定されており、jsonのような構造をもった形式で保存することは想定されていません。
たとえば、GCPにおけるGoogle Sheets APIの利用キーなどはjson形式で発行されます。
また、GitHub公式もjsonなどの構造化データをSecretsに登録することは非推奨としています。
To help ensure that GitHub redacts your secret in logs, avoid using structured data as the values of secrets. For example, avoid creating secrets that contain JSON or encoded Git blobs.
Using secrets in GitHub Actions - GitHub Docs
GitHubマーケットプレイスのcreate-jsonを利用するなどをして、そのままJSON形式でSecretsに保存することを紹介している記事が散見されますが、非推奨の方法です。
そこで、GitHub の Secrets に JSON などの構造化データを登録してはいけない の記事を参考にさせていただき、base64を利用してJSONファイルの内容を安全にSecretsに保管、呼び出す方法を試しましたのでご紹介いたします。
全体の流れ
- base64を用いてJSONデータをフラット化
- フラット化したデータをSecretsに登録
- GitHub Actions実行時のステップ内で以下の挙動をさせるようにyamlファイルを記述
- デコード
- jsonファイル生成
- jsonファイルの内容を環境変数として登録
- 生成したjsonファイルから値を読み込むようにプログラムの記述を変更
- ワークフローとして運用
実際にbase64を用いてSecrets環境変数を利用したワークフローを作成
以下、GitHub公式のStoring Base64 binary blobs as secretsに記載の方法に従って実施していきます。Macでの実施例となります。
base64を用いてJSONデータをフラット化
まずはbase64を用いてJSONデータをフラット化させます。
base64 -i gsheet-api-key.json -o gsheet-api-key-flat
gsheet-api-key.jsonのjsonファイルから、base64によってエンコードされたテキストをgsheet-api-key-flatへと生成します。
フラット化したデータをSecretsに登録
$ gh secret set GSHEET-API-KEY < gsheet-api-key-flat
上記のようにGitHub-CLIを利用してコマンドラインからSecretsを登録できますが、ブラウザからSecretsを登録してもOKです。
ブラウザからSecretsを登録する場合、リポジトリの設定 > Secrets and variables > Actions > New repository secret から登録が可能です。
GitHub Actions実行時のステップ内でデコード&jsonファイル生成をさせるようにyamlファイルを記述
公式Docs記載のyamlファイルに、 GitHub Actionsのyamlファイルに必須で書くべき3項目 の内容を反映させて記述します。
name: Retrieve Base64 secret
on:
push:
branches: [ octo-branch ]
defaults:
run:
shell: bash # デフォルトシェルの設定
jobs:
decode-secret:
runs-on: ubuntu-latest
timeout-minutes: 10 # タイムアウトの設定
steps:
- uses: actions/checkout@v4
- name: Retrieve the secret and decode it to a file # name属性の設定
env:
GSHEET-API-KEY_BASE64: ${{ secrets.GSHEET-API-KEY }} # Secretsに登録された内容をステップ内環境変数として設定
# base64を利用してJSON形式へデコード。環境変数は参照時にダブルクォートで囲む
run: |
echo "{$GSHEET-API-KEY_BASE64}" | base64 --decode > gsheet-api-key.json
- name: Display the json contents
run: |
head gsheet-api-key.json
環境変数は参照時にダブルクォートで囲むようにしましょう。予期しないトークン分割やパス名展開を防ぐことができます。
生成したjsonファイルから値を読み込むようにプログラムの記述を変更
ワークフローによって生成されるjsonファイルから値を読み込むようにプログラムの記述を変更します。
下記はpythonでの利用例です。
# Create a Google Sheets API client with a selected credentials file
# 認証用ファイル名はgsheet_api_key.json: GitHub ActionsによってSecrets内の暗号をjsonへ復号する形でファイル生成される
gc = gspread.service_account(filename="./gsheet_api_key.json")
実際に運用するワークフローに組み込んで完成
以上でセットアップは完了。実際に運用するワークフローに組み込むなどして完了です。
name: Schedule Python Exe with base64 Secrets
on:
schedule:
- cron: "0 17 * * *" # 毎日、定時刻(UTC: PM17:00 → JST: AM2:00)にワークフロー実行
workflow_dispatch: # ブラウザでの手動実行を許可
defaults:
run:
shell: bash
jobs:
execute-python-with-base64-secrets:
runs-on: ubuntu-latest
timeout-minutes: 60
env: # 別の環境変数をjobレベルで読み込み
SOMEHING_API_TOKEN: ${{ secrets.SOMETHING_API_TOKEN }}
steps:
- name: Fetch Repository
uses: actions/checkout@v4
- name: Retrieve the GSHEET Secret and Decode it to a file
env:
GSHEET_API_KEY: ${{ secrets.GSHEET_API_KEY }}
run: |
echo "{$GSHEET_API_KEY}" | base64 --decode > gsheet_api_key.json
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Execute python script
run: python app.py
この記事の気になる箇所を読み返す:
Category: インフラ・サーバー
Tags: