GitHub ActionsはGitHubに組み込まれた継続的インテグレーション/継続的デリバリー(CI/CD)プラットフォームで、ビルド、テスト、デプロイメントのパイプラインを含むワークフローの自動化を可能にします。
GitHub Actionsは便利ですが、デメリットもあります。その一つがログが公開され、必要な権限さえあれば誰でもアクセスできてしまうことです。
GitHub Actionsのログから機密データが漏れるのを防ぐには、暗号化した環境変数を使ってデータを安全に保存する必要があります。この環境変数の暗号化を行う上でのキーワードとなるのが、GitHub Actionsのシークレットです。
この記事では、GitHub Actionsのシークレットを使ってGitHub Actionsログに機密情報が表示されないようにする方法をご紹介します。
前提条件
この説明を読み進める上での前提条件は以下の通りです。
- GitHubアカウントを持っていること
- 既存のGitHubリポジトリがあること(デモリポジトリを複製可)
- デモリポジトリの複製はこちら
GitHub Actionsのログを安全に保つには
GitHub Actionsを使ってワークフローを構築すると、リポジトリにアクセスした人は誰でもログを見ることができます。とはいえ、トークンやパスワードなどの機密情報を削除するわけにはいきません。
その解決策として、::add-mask::
ワークフローコマンドで非表示にすることができます。このコマンドにより、対象の機密データがアスタリスク(*)に変換されます。
次のセクションでは、ログをマスクする方法をご紹介します。
ログをマスクする方法
まず、複製したリポジトリをテキストエディタで開きます。
リポジトリのルートに.github/workflows/ディレクトリを作成し、ワークフローのファイルをそこに保存します。次に、.github/workflowsディレクトリにhide-secrets.ymlという名前のファイルを新規作成し、以下のコードを追加します。
name: Hide Sensitive Information
on: push
jobs:
print-secret-token:
runs-on: ubuntu-latest
steps:
- name: echo a secret
run: echo "your secret token is verySecretToken"
変更内容をコミットしてGitHubリポジトリにプッシュします。変更後のGitHub Actionsワークフローが有効になり、変更を加えそれをプッシュするたびにトリガーされるようになります。
GitHubでリポジトリを開き、「Actions」タブを選択してログを確認します。以下のようなワークフローが表示されるはずです。
ワークフローのログを見ると、verySecretToken
という文字列が表示されています。ワークフローをクリックし、タスク名(print-secret-token)をクリックすると、ログが表示されます。以下のようになります。
非表示にするには、::add-mask::
コマンドを使ってhide-secrets.ymlファイルを編集し、print-secret-token
ジョブに新しいステップを追加します。
name: Hide Sensitive Information
on: push
jobs:
print-secret-token:
runs-on: ubuntu-latest
steps:
- name: Add Mask
run: echo "::add-mask::verySecretToken"
- name: echo a secret
run: echo "your secret token is verySecretToken"
マスキングは::add-mask::
の実行後にしか適用されないので、Add Mask
のステップを一番上に追加しましょう。Add Mask
のステップの前にシークレットverySecretToken
を置くと、マスクなしで表示されます。したがって、値が確実にマスクされるようにするには、できるだけ早い段階で::add-mask::
を使用します。
変更内容をコミットしてGitHubリポジトリに公開すると、verySecretToken
文字列がログに表示されるすべての場所でアスタリスク(*)に置き換えられます。
これでマスキングの問題は解決しましたが、新たな問題が発生します。verySecretToken
がワークフローファイルに残っているので、ソースコードにアクセスできる人なら誰でもこれを見ることができます。
プレーンテキストをマスキングするもう1つの欠点として、単語の一部をマスキングすると、その単語のすべてのインスタンスが隠れてしまいます。たとえば、「Programming is great, but my most productive days are those when I do not write a program.(プログラミングは素晴らしいが、私が最も生産的なのはプログラムを書いていないときである)」という文章を考えてみましょう。もし「program」という単語をマスクすると、文末の単語「program」だけでなく、「programming」のように、それを含む全ての単語がマスクされてしまいます。
プレーンテキストをマスクしようとすると、このようになります。
GitHub Actionsのログに含まれる機密データを隠すには、GitHub Actionsのシークレットを使うことができます。
GitHub Actionsのシークレットの使い方
GitHub Actionsのシークレットを使って、GitHub Actionsのワークフローで利用したいプライベートなデータを格納することができます。シークレットは、リポジトリや組織レベルでキーと値のペアとして作成されます。
特定のリポジトリは、そのリポジトリレベルで作成されたシークレットにしかアクセスできませんが、組織レベルで作成したシークレットは組織内のすべてのリポジトリで共有されます。
リポジトリレベルで作成したシークレットは、共同作業者の権限を持っている人なら誰でもActionsで使用できます。シークレットの値はいつでも変更可能です。ただし、シークレットはフォークしたリポジトリのワークフローでは使用できません。
シークレットの命名には、以下のガイドラインが適用されます。
- シークレット名にスペースを含めることはできない
- シークレット名は大文字小文字を区別しない
- シークレット名は数字で始めることはできない
- シークレット名は接頭辞
GITHUB_
で始まってはいけない - シークレット名は一意でなければならない(同じ名前のシークレットが同じレベルに存在することはできません)
シークレットをGitHub Actionsのワークフローで使うには、以下のようにシークレット名の前にYML変数としてsecrets
を追加します。
${{ secrets.MY_SECRET_TOKEN }}
シークレットをマスクしてセキュリティをさらに高めることもできます。
シークレットをマスクする方法
まず、GitHubのシークレットを作成します。GitHubのリポジトリで「Settings」タブをクリックし、左のサイドバーから「Secrets」>「Actions」を選び、「New repository secret」をクリックして新しいシークレットを追加します。
シークレットに名前と値をつけ、「Add secret」 をクリックします。
シークレットを作成し、verySecretToken
の値を指定したら、ワークフローでそれを使うことができます。hide-secrets.ymlファイルを開き、次のように変更します。
name: Hide Sensitive Information
on: push
jobs:
print-secret-token:
runs-on: ubuntu-latest
steps:
- name: Add Mask
run: echo "::add-mask::${{ secrets.MY_SECRET_TOKEN }}"
- name: Echo a secret
run: echo "your secret token is ${{ secrets.MY_SECRET_TOKEN }}"
先ほどのコードとの違いとして、シークレットトークンを新しく作成したGitHubシークレット${{ secrets.MY_SECRET_TOKEN }}
に置き換えています。
コードをコミットしてGitHubリポジトリに変更内容をプッシュすると、シークレットがマスクされます。
まとめ
GitHub Actionsのログに機密情報を書き込んではいけません。プレーンテキストのマスキングはデータを隠すひとつの方法ですが、ワークフローのファイルにアクセスすると誰でも隠そうとしている情報を見ることができます。
今回の記事で説明したように、GitHub Actionsのシークレットを使えば機密データをより安全に保護した上でマスキングすることができます。
KinstaとGitの使い方もご紹介しています。この機会にアプリケーションホスティングを無料でお試しください。
コメントを残す