GithubActionsでの機密情報を使用する際は扱いをちゃんと考えようという話

Github Actions について一から入門してみようと調べています。

Github Actions は Public レポジトリでの実行は無料、と言われていますが 例えば Github Actions で他のAPIへアクセスする ( 例えば、AWS の ECS へのデプロイ等)ような要件が出てきた時、 AWS Access Key はどのように管理するのが安全か? という所で調べてみました。

機密情報を管理するGithubの仕組み

help.github.com

secrets という仕組みがあり Key - Value の仕組みで機密情報を管理出来ます。

f:id:ikkitang1211:20200531091838p:plain

既に作成された Secrets の参照

一度設定してしまえば、Github の settings のページからは更新 or 削除 するしか出来ません。 Github では暗号化されて保存されている、との事でした。

f:id:ikkitang1211:20200531092100p:plain

Github Actions での Secrets の参照

${{ secrets.ACCESS_KEY }} と書く事で参照することが出来ます。

Github Actions のセットアップ

サンプルのレポジトリについて Actions タブをクリックすると、管理しているレポジトリの言語等に応じてテンプレートがサジェストされます。

f:id:ikkitang1211:20200531093323p:plain

今回は set up a workflow yourself をクリックして、自分で一から書いてみる事としますm( )m

f:id:ikkitang1211:20200531093238p:plain

こんな感じにしてみました。

on: push

name: Sample load secrets

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Debug
      run: |
        echo "key = ${{ secrets.ACCESS_KEY }}"
  • on: push 「全てのPushのイベントをトリガーとして」
  • ubuntu-latest という Docker imageで
  • uses: actions/checkout@v2 Pushされた コミットにチェックアウトをして
  • echo "key = ${{ secrets.ACCESS_KEY }}" ACCESS_KEY の機密情報を表示する

という Actionsを規定した yml ファイルです。(後で説明しますが、セキュリティ上のインシデントがあります)

これを実行するとこんな感じになります。

f:id:ikkitang1211:20200531094201p:plain

想像どおり、普通に Secrets が表示されてしまいました(そりゃそう)

Github では機密情報についてはこのように記述されています。

警告: GitHubは、ログに出力されたシークレットを自動的に削除しますが、シークレットをログに出力することは意識的に避けなくてはなりません。

Run echo "key = ***" となっているので ログからは 機密情報は見えないようにはなっていますが、出力の結果では表示されます。

という事で、設定された機密情報は 見ようとコーディングすれば割と簡単に見れる という事が分かりました。

Secrets の守り方に思いをはせる

echo で Secrets を表示しないように注意する

これをするとActionsの所でログに表示されてしまいます。ログについては過去の履歴もたどる事が出来るので、もしデバッグでどうしても確認したい時はその後はAPI の AccessKey は再発行するなどしてそれを変更する必要があるかと思います。

悪意ある攻撃を防ぐ

各個人ユーザーが持つ Public レポジトリは基本的には自分以外のユーザーは リードオンリー権限です。

help.github.com

コラボレーターを追加する場合はその方が信用に足るかどうかを判断する必要があると思います。

on: push のトリガー

これは全てのPushをトリガーにActionsが実行されます。

例えば、master以外のブランチを作って、そこで echo "key = ${{ secrets.ACCESS_KEY }}" を作っても実行される、という事です。

Github Actions で Secrets を使う時は on push 単体でのトリガーはなるべく避けた方が良さそうです。

使う場合は こんな感じで master に Pushされた場合のみに限定した方が良さそうです。

on:
  push:
    branches:
      - master

また、masterへのPushへのルールも設定し、masterブランチも合わせて守る必要があるでしょう。

dev.classmethod.jp

逆にどうしても on:push とかで使う場合は main.yml とかは省くみたいな設定はした方が良さそうですね。

on:
  push:
    paths: 
        '!./.github/workflows/*.yml'

Forkしたプロジェクトでの参照

自分のプロジェクトでは割と扱いに注意していく必要がある事が伝わっていれば幸いかと思います。

では、逆に他のユーザーの手にレポジトリが渡ってそれが悪用されるみたいなパターンは無いのでしょうか。

手始めに fork したプロジェクトで secrets まで共有されたりするのでしょうか?

github.community

試してはない んですけど、まさに困っている人がいるので、secrets までは共有されなさそうですね。

Template Repository とかにも設定して見たのですが、Secrets も共有されなかったです。

多分大丈夫そう?

結論

Github の secrets は正しく管理する事でより便利に使う事の出来る仕組みだと思います。

とはいえ、雑に使うと簡単に漏洩とかありそうなのでその危険性は十分に理解してから使うべきだな、って思いました。

AWSのSecret Manager 的なのと連携出来たりするのかなぁ・・?

という事で以上です。