こんにちはますのです。
先日より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を触ることとなりました…。
今回は「構造化ファイルを変更する」という点なので問題無し。
登録先は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より先ほどエンコードしたテキストデータを保存します。
「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
別途試した時は改行無くても成功したので摩訶不思議。
結果を見てみる
同じくECSデプロイ後にjsonデータをcatするシェルのログを確認。
先ほどは「1行内に全て格納」されてました。
デコード後は「改行コード含めて格納」されているようです。
※CloudWatchLogsで複数行に値が出力されている
参考サイト
https://docs.github.com/ja/actions/security-guides/encrypted-secrets