GithubActionsでjsonファイルをSecretsから展開する(Base64)

  • 2021年10月11日
  • 2021年10月15日
  • AWS, IT
AWS

こんにちはますのです。
先日よりPythonのタスクサーバの移行をしております。

その時に必要となった要件がこちら。

今までサーバ内にファイル保存していた
Credential情報をGithub上に平文で保存しない

AWSのアクセスキーもPablic公開して流出とかありましたからね。
このあたりはCI/CDツール使うにあたって必要になると思いました。

環境

  • EC2で起動しているタスクサーバ(Python)をECS on Fargateに移行
  • タスクサーバ内にお抱え状態なクレデンシャル情報をセキュアに管理したい
  • デプロイはCI/CDツールとしてGithubActionsを利用する
  • コード管理はGithub上で担当者が行う

Github Secretsには構造化データの使用禁止

Secretsにそのままjsonファイル保存して展開すればええやんと思っていました。
GithubDocs読んでいたら「シークレットの値として構造化データは使用禁止」と明記されていて撃沈です。

GitHub がログのシークレットを確実に削除するよう、シークレットの値として構造化データを使用しないでください。 たとえば、JSONやエンコードされたGit blobを含むシークレットは作成しないでください。
引用:暗号化されたシークレット

あてが外れた…。

ちなみに保存出来るのか検証したところ、データ保存自体は出来ている様子。
改行はされないものの一応機能はしているようです。

ECSへ展開時にシェルで「cat ./credential.json」を実行した結果ログ

Githubがシークレットを確実に削除出来ない可能性はあるので、後片付け部分で保障出来ないですよということにも見えます。

解決方法:Base64のデコードとエンコードを利用してjsonファイルを作成する

ではどうやってjsonファイルを作成しようか?
悩んだ末に見つけた答えはこちらの記事

「Base64」でのエンコード・デコードを実施する

  • jsonファイルをBase64ファイルでエンコード
  • GithubのSecretsにエンコードした値を登録
  • ymlファイル上でBase64でデコードしたjsonファイルを再作成

インフラさんとしてやってきて恥ずかしながら、初めてBase64を触ることとなりました…。

Name
Base64はエンコードした文字列がばれてしまうとデコードも出来てしまうので単体だとセキュリティ的に担保されない様子。
今回は「構造化ファイルを変更する」という点なので問題無し。
登録先はGithubのSecrets情報なので保存先からの漏洩は心配しなくて良い。ということで採用です。

1. jsonファイルをBase64でエンコードする

まずはjsonファイルのエンコードを実施。
一番簡単なのはbase64のエンコード/デコードツールの利用です。
Web上からサクッとできます。

ただしWebツールという外部リソースに対して、漏洩NGな資格情報を入力するのは如何なものか…。
わたしはAWSのプライベートVPCにCloud9(AmazonLinux2)を使って実行しました。

Cloud9にインスタンス情報などを設定。
jsonファイルを格納したらあとはコマンド実行です。

base64 credential.json > encode-credential.txt

これでエンコードされたテキストデータが「encode-credential.txt」に保存されます。

デコードで念のため確認

base64 -d encode-credential.txt

元のjsonデータが表示されればbase64のエンコード/デコードが完了です。

2. Github Secretsにエンコードしたテキストデータを保存

続いてGithub:Settings>Secretsより先ほどエンコードしたテキストデータを保存します。

Secretsに登録する際は「改行」が無い状態で登録しましょう。
「base64: invalid input」とエラーが出てデプロイに失敗します。
参考:Linuxのbase64コマンドでハマったのでメモ

Secretsに格納した時点で改行コードがスペースとなるのかデコードに失敗。
オプション:-nをつけてもダメなのでSecrets登録時に注意。

3. GithubActionsのymlファイルにBase64デコード処理を加える

Secretsに保存したデータを変数に登録
変数をechoで呼び出し→decode→指定した箇所にファイル保存

- name: Translate secrets of base64 into json
  env:
    JSON_DECODE: ${{ secrets.JSON_CREDENTIAL }}

  run: |
    echo-n $JSON_DECODE | base64 --decode > ./config/credential.json

envとrunの間に1行開けないとなぜかエラーが出たのです。
別途試した時は改行無くても成功したので摩訶不思議。

結果を見てみる

同じくECSデプロイ後にjsonデータをcatするシェルのログを確認。

先ほどは「1行内に全て格納」されてました。
デコード後は「改行コード含めて格納」されているようです。

※CloudWatchLogsで複数行に値が出力されている

参考サイト

https://docs.github.com/ja/actions/security-guides/encrypted-secrets

https://zenn.dev/m_t_tion1/articles/c860265533b0717869f9

https://hydrocul.github.io/wiki/commands/base64.html

最新情報をチェックしよう!