サービスアカウント漏洩検知の組織ポリシーを試す

2024/05/31に公開されました。
2024/05/31に更新されました。

サービスアカウント漏洩検知の組織ポリシーが6月16日から強制有効されるので、その前に試してみた


author: kuribo-

はじめに

インフラチームのkuribo-です。

組織ポリシーたくさんあってそこまで詳しくないので、勉強のために組織ポリシーを触ってみました。
今回試してみるのは、2024年3月頃に追加されたサービスアカウントキーの漏洩検知の組織ポリシーです。
この組織ポリシーについてはGoogleからメールで2024年6月16日以降までに何も対応しない場合は漏洩しているサービスアカウントは無効化されるようになると案内が出ています。
(constraints/iam.serviceAccountKeyExposureResponseをWAIT_FOR_ABUSEという設定にすることで無効にならないようにできます。)

ですので、その結果どうなるのか?を確認するために試してみました。

組織ポリシーとは

やって欲しくないことや、こういう設定にしなさいなど強制力を持たせてプロジェクトを制御するための仕組みです。
例えば、「リソースを作成するリージョンを制限する(国内のみの場合は東京・大阪のみなど)」「サービスアカウントキーを発行できないようにする」などです。
制限することで自由度は減りますが、危険度が減るのでその会社のセキュリティルールに合わせてルールを設定することが多くあります。
(データは国内にしか置いてはいけないという会社のセキュリティルールがあるような場合など)

それでは、組織ポリシーを試していきます。

組織ポリシーの有効化する前に

現状GithubではサービスアカウントキーをPushしようとすると検知する仕組みが入っています。
以下のようなエラーです。

$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 10 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 2.24 KiB | 2.24 MiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote:
remote: - GITHUB PUSH PROTECTION
remote:   —————————————————————————————————————————
remote:     Resolve the following violations before pushing again
remote:
remote:     - Push cannot contain secrets
remote:
remote:
remote:      (?) Learn how to resolve a blocked push
remote:      https://docs.github.com/code-security/secret-scanning/pushing-a-branch-blocked-by-push-protection
remote:
remote:
remote:       —— Google Cloud Service Account Credentials ——————————
remote:        locations:
remote:          - commit: d05224b469a58b104411927a462758289a7f36e6
remote:            path: policy-test-424808-d2cf7a28d8ed.json:1
remote:
remote:        (?) To push, remove secret from commit(s) or follow this URL to allow the secret.
remote:        https://github.com/kuriboo1002/policy-test/security/secret-scanning/unblock-secret/2h8QCt9B1Jv1voPaY1Ya2ua3tNZ
remote:
remote:
remote:
To github.com:kuriboo1002/policy-test.git
 ! [remote rejected] main -> main (push declined due to repository rule violations)
error: failed to push some refs to 'github.com:kuriboo1002/policy-test.git'

これはPublicリポジトリだから発生する検知のようです。
(Privateの場合は発生しませんでした)
ですので、Publicリポジトリに対してサービスアカウントキーを誤ってPushしてしまうという自体は避けられます。
(secret-scanning/unblock-secretのURLのところにアクセスして許可しない限りは)

尚、許可した後に今回のPolicyを有効化しても、サービスアカウントキーの無効化が起こらなかったので、
その場合はポリシー違反にならないようです。
(検証ミスしたかな?と若干思っていますが)

ですので、今回はPrivateリポジトリにサービスアカウントキーPush済みのリポジトリを、
誤ってPublic化した際に公開してしまった場合という流れで検証します。

組織ポリシーの有効化ともろもろ準備

今回はいろいろ使うので以下を準備します。

  • 組織ポリシー(DISABLE_KEYの設定)
  • サービスアカウントキー(権限はつけちゃダメ)
  • 漏洩させるためのリポジトリ(Private -> Public)

同じことを試す場合は、絶対にサービスアカウントに権限をつけてはいけません。
あえて漏洩させるので、悪意のある人に知られて無効化される前に悪さをされるとも限りませんので。

組織ポリシーの設定

serviceAccountKeyExposureResponseで検索すると1つのポリシーが出てくるのでクリックします。
そうすると以下の画面が表示されます。
policy_default

今回はDISABLE_KEYを設定します。
設定すると以下のような感じ。
policy_disable_key

サービスアカウントの準備

新しくサービスアカウントを作成します。
このサービスアカウントはあえて漏洩させるので権限は何もつけません。
そのサービスアカウントのサービスアカウントキーも作成します。
service_account

リポジトリの準備

テスト用のGithubのPrivateリポジトリを作成します。
そこに先ほど作成したサービスアカウントのサービスアカウントキーをPushしておきます。
repository

これで準備完了です。
いざ、GithubのPrivateリポジトリをPublicに変更します。

あえてサービスアカウントを漏洩してみる

Publicリポジトリへの変更前

この時のサービスアカウントキーの状態は何も変わりがありません。
service_account_after_push

Publicリポジトリへの変更後

repositoryをPublicに変更します。
repository_public

そうすると、ものの1分程度でしょうか?
すぐにサービスアカウントキーが無効化されました。
service_account_after_public

リポジトリの方に特に警告みたいなものは出ていませんでした。

まとめ

今回は組織ポリシーの動作を検証してみました。

Github側の機能として、PublicリポジトリにサービスアカウントキーがPushできないことがわかりました。
そもそもPublicリポジトリを利用している場合は今回の組織ポリシーが強制的に有効になっても大きな問題にはならなさそうですね。

ですので、PrivateリポジトリからPublicに変更するような場面で効果を発揮しそうでした。
Publicに変更した時にリポジトリにサービスアカウントキーが含まれていた場合、
組織ポリシーのconstraints/iam.serviceAccountKeyExposureResponseDISABLE_KEYに設定されていると、
サービスアカウントキーが公開されてすぐに無効化されることがわかりました。
このポリシーを設定しておくことで間違えて公開してしまった場合も問題が起こりづらいですね。

はじめにのところで書きましたが、6月16日からはこのポリシーがデフォルト動作になります。
現在Publicのリポジトリにサービスアカウントキーが置かれている場合は6月16日以降すぐに無効化されるようになります。
もしそれで困る場合は、今のうちに組織ポリシーのconstraints/iam.serviceAccountKeyExposureResponseWAIT_FOR_ABUSEに設定しましょう。
(あまりそういうケースはないとは思われますが)

今回組織ポリシーについてかなり勉強になりました。

※本記事は、ジーアイクラウド株式会社の見解を述べたものであり、必要な調査・検討は行っているものの必ずしもその正確性や真実性を保証するものではありません。

※リンクを利用する際には、必ず出典がGIC dryaki-blogであることを明記してください。
リンクの利用によりトラブルが発生した場合、リンクを設置した方ご自身の責任で対応してください。
ジーアイクラウド株式会社はユーザーによるリンクの利用につき、如何なる責任を負うものではありません。