シークレットとは
ソフトウェア開発でのシークレットは、システム、サービス、データ、API へのアクセスを認証または認可するために使われる機密情報です。 以下に例を示します。
- API キーとアクセス トークン: GitHub の REST API などの外部サービスを操作するために使用できます。 アクセス トークンを使うと、GitHub Actions などのサービスで認証が必要なタスクを実行することもできます。これについては後で説明します。
- データベース資格情報: ローカルと外部のデータベースとストレージへのアクセスを許可します。
- 秘密キー: SSH や PGP などの秘密キーは、他のサーバーへのアクセスやデータの暗号化に使用できます。
シークレットは非常に多くのアクセスを提供し、それには重要なシステムも含まれるため、シークレットをセキュリティで保護することが非常に重要であることがわかります。
シークレットが露出されると発生する可能性があること
- 攻撃者は、シークレットによってアクセスが許可されるすべてのものに認可なしでアクセスできます。
- ハッカーは、機密ユーザー データなどのデータを盗むことができます。 これにより、プライバシーと法律に関する予期しない事態が発生し、お客様とそのアプリケーションに対する信頼が損なわれる可能性があります。
- 露出されたシークレットによって、ハッカーがクラウド プロバイダー アカウントで未認可のワークロードを実行した場合、お客様にコストが発生する可能性があります。
- ハッカーは、露出されたシークレットを使ってサーバーを削除、変更、中断することができ、ダウンタイムやデータ損失を引き起こす可能性があります。
シークレットによってお客様が利用できるようになるすべてのアクセスと能力、そしてハッカーがそれを使ってできることを考えてみてください。 たとえば、GitHub アカウントの personal access token が露出されると、ハッカーがユーザーとして GitHub に投稿して変更を行う可能性があります。
シークレットの管理に関するベスト プラクティス
このような問題を避けるには、ベスト プラクティスに従って漏洩を防ぎ、シークレットが露出された場合の損害を制限します。
最小限の特権の原則 (PoLP) に従う
可能な限り、シークレットで実行できることとアクセスできるものを、必要なもののみに制限します。 次に例を示します。
- シークレットがデータの読み取りにのみ使われ、データを変更しない場合は、読み取り専用にします。
- お使いの API でシークレットを特定のスコープまたはアクセス許可のみに制限できる場合は、必要なもののみを選びます。 たとえば、GitHub シークレットで作成する必要があるものが issue のみの場合、そのシークレットでリポジトリの内容や他のものにアクセスできるようにする理由はありません。
- シークレットによってそれを所有するユーザー アカウントへのフル アクセス権が攻撃者に与えられる場合は、シークレットの所有権を取得できるサービス アカウントの作成を検討します。
アプリケーションでシークレットを保護する
- シークレットをハードコーディングしてはなりません。 常に、環境変数またはプラットフォームのシークレット管理ツール (GitHub のリポジトリ シークレットなど) を使います。
- シークレットを他のユーザーと共有する必要がある場合は、パスワード マネージャーなどの専用ツールを使います。 メールやインスタント メッセージを使ってシークレットを送信してはなりません。
- 可能であれば、有効期限を設定し、定期的にシークレットをローテーションします。これにより、古いシークレットが悪用されるリスクが減ります。
- アプリケーションでログが生成される場合は、ログに記録される前にシークレットが削除されていることを確認します。 そうしないと、アクティブなシークレットがプレーンテキスト ファイルに保存される可能性があります。
シークレットが露出された場合の被害を制限する
- たとえ露出されたのが 1 秒間だけであっても、シークレットの侵害を考慮して、シークレットをすぐに取り消します。 その後、新しいシークレットを生成し、安全に格納します。
- 侵害されたシークレットで実行された疑わしいアクティビティを示している可能性があるアクティビティ ログを調べます。
- シークレットがどのようにして露出されたかを検討し、二度と発生しないようにプロセスを変更します。
GitHub はシークレットのセキュリティ保護にどのように役立つか
シークレットを安全に保つためにできることは数多くありますが、GitHub にもシークレットの機密の維持に役立つ機能がたくさんあります。 誰でも間違いを犯すので、誤って露出されたシークレットをキャッチする機能が用意されています。
- プッシュ保護は、GitHub 上のリポジトリへのシークレットのプッシュをブロックします (後で説明します)。
- シークレット スキャンは、リポジトリをスキャンし、シークレットが検出されたらアラートを作成します。 一部のシークレットについては、シークレットの自動取り消しなどのアクションを実行できるように、プロバイダーにも通知します。
シークレットの安全な保管の実践
この練習では、personal access token を作成し、それを安全に格納して、GitHub Actions で使えるようにします。 作成するアクションは、issue に対応する簡単なワークフローです。
1.練習用のリポジトリを作成する
最初に、作業用のリポジトリを作成します。 new2code
アカウントには、すぐに作業を始めるのに使用できるテンプレート リポジトリがあります。
- 新しいリポジトリのページに移動します。 このリンクに従うと、
new2code
アカウントでテンプレートが事前に選択されています。 - [Owner] で、自分のユーザー アカウントが選ばれていることを確認します。
- [Repository name] フィールドに「
secret-action
」と入力します。 - 説明フィールドの下で [Public] を選んでリポジトリの可視性を設定します。
- [Create repository] (リポジトリの作成) をクリックします。
2.ダミー トークンをコミットする
誰もが間違いを犯すものであり、コーディングの過程のどこかで誤ってシークレットをコミットする可能性があります。 この演習では、トリガーされるアラートに慣れ親しみやすくなるように、意図的に偽のトークンをコミットします。
-
先ほど作成したリポジトリに移動します。
-
ファイルの一覧で
.github/workflows
をクリックして、YAML ワークフロー ファイルに移動します。 -
ファイルの一覧で
comment.yml
をクリックして、ワークフロー ファイルを開きます。 -
ワークフロー ファイルを編集するには、右上の をクリックします。
-
13 行目の
GH_TOKEN: ""
で、引用符の間に次のダミー トークンを挿入します。secret_scanning_ab85fc6f8d7638cf1c11da812da308d43_abcde
最終的な結果はこのようになります。
GH_TOKEN: "secret_scanning_ab85fc6f8d7638cf1c11da812da308d43_abcde"
-
変更をコミットするには、右上の [Commit changes...] をクリックした後、ダイアログでもう一度 [Commit changes] をクリックします。
-
プッシュ保護アラートと "Secret scanning found a GitHub Secret Scanning secret on line 13" というメッセージが表示されるはずです。
ダミー トークンで試していなかったら、これは一歩間違えばトークンが露出されることを警告するものです。 アラートに対して選択できるオプションを確認します。
-
コミットを停止し、シークレットが露出されないようにするには、[Cancel] をクリックします。 右上の [Cancel changes] をクリックし、メッセージが表示されたら保存されていない変更を破棄します。
3.実際のトークンを作成する
それでは、ベスト プラクティスに従ってみましょう。 最初に、ユーザーに代わってアクションを実行できる personal access token を作成します (作成されるコメントはユーザー アカウントから送信されているように見えます)。
Note
各構成ステップで最小特権の原則にどのように従っているのかに注意してください。 トークンは、必要な最短の有効期限を持ち、必要なリポジトリにのみアクセスでき、作業に必要な最小限のアクセス許可を持ちます。
- 新しい personal access token ページに移動します。
- [Token name] で新しいトークンの名前を指定します。 "Action token" のようなものを使用できます。
- [Expiration] で [7 days] を選びます。
- [Repository access] で [Only select repositories] を選びます。
- [Select repositories] ドロップダウンで、前に作成した演習用リポジトリだけを選びます。
- [Permissions] セクションの [Repository permissions] の右にある をクリックして、使用可能なすべてのアクセス許可を表示します。
- [Issues] まで下にスクロールし、右側のドロップダウンで [Read and write] を選びます。
- ページの下部にある [Generate token] をクリックします。 メッセージが表示されたら、もう一度 [Generate token] をクリックして確認します。
この瞬間から、結果のトークンを安全に取り扱うことが極めて重要です。 この後すぐにトークンを使うので、簡単にクリップボードにコピーしておいてかまいません。
4. トークンを安全に格納する
これで、新しいトークンをリポジトリに安全に格納できるようになりました。
-
演習を始めるときに作成したリポジトリに移動します。
-
リポジトリ名の下にある [設定] をクリックします。 [設定] タブが表示されない場合は、 [] ドロップダウン メニューを選び、 [設定] をクリックします。
-
サイドバーの [セキュリティ] セクションで、 [ シークレットと変数] を選択し、次に [アクション] をクリックします。
-
[Repository secrets] で [New repository secret] をクリックします。
-
[Name] フィールドにシークレットの名前を入力します。 この演習では、
MY_TOKEN
を使用します。 -
[Secret] フィールドに、前に生成した personal access token を貼り付けます。
-
[シークレットの追加] をクリックします。
シークレットが安全に暗号化され、使用する準備が整いました。
5.アクションでトークンを参照する
これで、トークンを使うように YAML ワークフロー ファイルを更新し、動作をテストできます。
-
リポジトリに戻ります。 リポジトリの設定にいる場合は、リポジトリ名の下にある [ Code] をクリックできます。
-
ファイルの一覧で
.github/workflows
をクリックして、YAML ワークフロー ファイルに移動します。 -
ファイルの一覧で
comment.yml
をクリックして、ワークフロー ファイルを開きます。 -
ワークフロー ファイルの編集を始めるには、右上の をクリックします。
-
13 行目の
GH_TOKEN: ""
で、空の引用符を${{ secrets.MY_TOKEN }}
に置き換えます。 これは、前に追加したリポジトリ シークレットを参照しています。GH_TOKEN: ${{ secrets.MY_TOKEN }}
-
変更をコミットするには、右上の [Commit changes...] をクリックします。
-
[Commit changes] ダイアログで、[Commit message] を編集して行っている変更を反映します。 たとえば、「Updating workflow to use repository secret」などと入力します。
-
[Commit directly to the
main
branch] が選択されていることを確認します。 -
[変更をコミットする] をクリックします。
6.トークンとワークフローをテストする
これで設定はすべて終わりです。 次に、ワークフローをテストしてみましょう。
-
リポジトリ名の下にある [イシュー] をクリックします。
-
[New issue](新しい Issue) をクリックします。
-
[Add a title] には任意のタイトルを入力できます。
-
[Add a description] のテキスト領域に、「
Hello
」と入力します。 -
テキスト領域の下にある [Create] をクリックします。
ワークフローが完了するまでの時間が経過すると、新しいコメントが表示されます。 ユーザーのトークンを使っているため、コメントはユーザー自身によって作成され、あいさつ文が含まれます。
次のステップ
シークレット スキャンとプッシュ保護について詳しくは、GitHub Skills の「シークレット スキャンの概要」コースをご覧ください。