G-gen の武井です。当記事では、Google SecOps で検知したアラートの是正対応を Playbooks で自動化する方法を解説します。

はじめに
Google SecOps とは
Google Security Operations(以下 Google SecOps、旧称 Chronicle)は、Google Cloud が提供する統合セキュリティ運用プラットフォームです。
SIEM、SOAR、脅威インテリジェンス、Gemini を利用した AI による運用支援を提供します。これらにより、脅威の検知・調査・対応を一元的に行えます。結果として、セキュリティ運用の効率化と高度化を実現できます。
以下の記事も参考にしてください。
Playbooks(ハンドブック)とは
Playbooks(和名表記はハンドブック)では、SIEM によって検知されたアラートに対してあらかじめ一連の対応手順を定義することで、自動または半自動でアクションを実行します。これにより、対応プロセスを標準化・迅速化できます。
Playbooks は次の要素で構成されます。
| 要素 | 概要 |
|---|---|
| トリガー (Triggers) |
Playbooks を起動する条件。特定のアラートやイベントの発生時、またはスケジュールを契機に自動実行される |
| アクション (Actions) |
実行される処理。例えば「VirusTotal への照会」、「Jira チケット起票」、「ユーザーの無効化」など |
| フロー (Flows) |
条件分岐や承認を制御する仕組み。自動判断やアナリストの入力を挟みながら次の処理を決定する |
| ブロック (Blocks) |
再利用可能な処理単位。複数の Playbooks で共通利用できる部品化されたモジュール |
| ループ (Loops) |
配列(リスト)に対する繰り返し処理。for each として、アラート内のエンティティ群やリスト項目を1件ずつ反復し、各項目に対して同じアクションを実行する |
| AI エージェント (AI Agents) |
AI エージェントを組み込み、自律的な分析・判断を行わせるステップ。Triage and Investigation Agent(TIN)で、アラートを自律調査して True/False Positive の判定・信頼度スコアを返し、その結果を後続の分岐に利用できる |
検証の流れ
当記事では GitHub の Private リポジトリが意図せず Public リポジトリに変更されたというシナリオのもと、以下の段取りで検証を行います。

| 順序 | 設定項目 | 設定箇所 |
|---|---|---|
| 1 | カスタムルールの設定 | Google SecOps |
| 2 | カスタムインテグレーションの設定 | Google SecOps |
| 3 | Playbooks の設定 | Google SecOps |
| 4 | 動作確認 | Google SecOps および GitHub |
なお、GitHub の監査ログを Google SecOps に取り込む方法については、以下の記事で解説しています。
カスタムルールの設定
前述のシナリオに該当するログを取り込んだ際、それをアラートとして検知できるよう、検知ルールを準備します。
Google SecOps には事前定義済みの検知ルールが多数用意されていますが、今回のシナリオ向けに独自のカスタムルールを作成します。事前定義済みの検知ルールを参考にしつつ、Gemini in Google SecOps を使用したルール作成が効果的です。
作成したカスタムルール(今回の例では g_gen_github_repo_visibility_to_public)は以下の通りです。また、作成したルールでアラート検知ができるよう、Detecting と Alerting を有効にします。
rule g_gen_github_repo_visibility_to_public {
meta:
author = "G-gen"
description = "Detects a GitHub repository whose visibility is changed to public"
severity = "HIGH"
tactic = "TA0010"
technique = "T1567"
events:
$e.metadata.product_name = "GITHUB"
$e.metadata.product_event_type = "repo.access"
$e.additional.fields["visibility"] = "public" nocase
outcome:
$repo_name = array_distinct($e.target.resource.name)
$actor_id = array_distinct($e.principal.user.userid)
$new_visibility = array_distinct($e.additional.fields["visibility"])
$previous_visibility = array_distinct($e.additional.fields["previous_visibility"])
condition:
$e
}

インテグレーションの設定
インテグレーションとは
Playbooks は、それ単体で GitHub のような外部サービスを操作できません。外部サービスへの接続と操作を担うのがインテグレーションです。
Google SecOps では、VirusTotal や Slack をはじめ数多くの外部サービスに対応したインテグレーションが Content Hub(マーケットプレイスに相当)で提供されています。
カスタムインテグレーションとは
カスタムインテグレーションとは、Google SecOps 組み込みの IDE(統合開発環境)を使って独自に作成するインテグレーションです。
2026年7月現在、GitHub に関するインテグレーションは存在しないため、「GitHub への接続」と「リポジトリの可視性(公開範囲)変更」の2つのアクションを含むカスタムインテグレーションを作成し、これらを後段の Playbooks から呼び出します。
- 参考 : Use the IDE
カスタムインテグレーションの作成
SecOps の管理コンソールから Response > IDE > +と遷移し、インテグレーション(今回の例では GitHubCustom)を作成します。

次に、インテグレーションの歯車アイコンをクリックします。

画面が遷移したら、以下2つのパラメータを追加します。API Token を必須(Mandatory)にすると既定値の入力を求められ、秘匿値が残ってしまうため、ここでは必須を Off にします。
| パラメータ | タイプ | 既定値 | 必須 |
|---|---|---|---|
API Root |
String | https://api.github.com |
On |
API Token |
Password | (空) | Off |

カスタムアクションの作成
インテグレーション(土台)の次に、その上で動くアクションを作成します。アクションには即座に結果が返る Sync と、長時間処理向けの Async がありますが、今回はいずれも即応答のため Sync を選択します。
先程同様、Response > IDE > +と遷移し、以下2つのアクションを作成します。
- 接続確認用アクション(
Ping): GitHub に正しく接続できるかを確認します。Google SecOps では、すべてのインテグレーションがこの接続テスト用アクションを1つ持つ必要があります。 - 可視性変更用アクション(
Set Repository Visibility): GitHub REST API のPATCH /repos/{owner}/{repo}を呼び出し、リポジトリの可視性を変更します。

接続確認用アクション (Ping)では GitHub の GET /user を呼び出し、トークンが有効であることを確認します。
from SiemplifyAction import SiemplifyAction from SiemplifyUtils import output_handler from ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED import requests INTEGRATION_NAME = "GitHubCustom" @output_handler def main(): siemplify = SiemplifyAction() siemplify.script_name = "Ping" api_root = siemplify.extract_configuration_param(INTEGRATION_NAME, "API Root", default_value="https://api.github.com") token = siemplify.extract_configuration_param(INTEGRATION_NAME, "API Token") status = EXECUTION_STATE_COMPLETED result_value = "true" try: resp = requests.get( f"{api_root}/user", headers={ "Authorization": f"Bearer {token}", "Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28", }, timeout=30, ) resp.raise_for_status() output_message = f"Successfully connected to GitHub as {resp.json().get('login')}." except Exception as e: status = EXECUTION_STATE_FAILED result_value = "false" output_message = f"Failed to connect to GitHub: {e}" siemplify.end(output_message, result_value, status) if __name__ == "__main__": main()

可視性変更用アクション(Set Repository Visibility) では実行のたびに外から渡す入力パラメータを2つ定義します。
設定パラメータがインテグレーション全体で共通の接続情報であるのに対し、入力パラメータは実行ごとに変わる値(対象リポジトリなど)を受け取ります。
| パラメータ | タイプ | 既定値 | 必須 |
|---|---|---|---|
Repository Full Name |
String | (空) | Off |
Target Visibility |
String | private |
On |
Repository Full Name は、後段の Playbooks でアラートから動的に渡すため、ここでの必須は Off で問題ありません。
from SiemplifyAction import SiemplifyAction from SiemplifyUtils import output_handler from ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED import requests INTEGRATION_NAME = "GitHubCustom" @output_handler def main(): siemplify = SiemplifyAction() siemplify.script_name = "Set Repository Visibility" api_root = siemplify.extract_configuration_param(INTEGRATION_NAME, "API Root", default_value="https://api.github.com") token = siemplify.extract_configuration_param(INTEGRATION_NAME, "API Token") full_name = siemplify.extract_action_param("Repository Full Name", print_value=True) target = siemplify.extract_action_param("Target Visibility", default_value="private", print_value=True) status = EXECUTION_STATE_COMPLETED result_value = "true" try: owner, repo = full_name.split("/", 1) url = f"{api_root}/repos/{owner}/{repo}" resp = requests.patch( url, headers={ "Authorization": f"Bearer {token}", "Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28", }, json={"visibility": target}, timeout=30, ) if resp.status_code == 200: siemplify.result.add_result_json(resp.json()) output_message = f"Reverted {full_name} to {target}." else: status = EXECUTION_STATE_FAILED result_value = "false" output_message = f"Failed ({resp.status_code}): {resp.text}" except Exception as e: status = EXECUTION_STATE_FAILED result_value = "false" output_message = f"Error: {e}" siemplify.end(output_message, result_value, status) if __name__ == "__main__": main()

インスタンス設定
作成したカスタムインテグレーションは、インスタンスとして有効化することで使用可能になります。
SecOps の管理コンソールから Response > Integrations Setup > 環境区分(今回は Default Environment)> +と遷移し、先程作成したカスタムインテグレーションを選択してインスタンスを作成します。

インスタンスが作成できたら、歯車アイコンからパラメーターを入力し、Test > Save の順で保存します。
なお、今回は検証のため、個人アカウントで発行した Personal Access Token を使用していますが、本番運用では Fine-grained PAT や GitHub App による認証が望ましいです。

Playbooks の設定
Playbooks の構成
ここまでで、アラートを検知するカスタムルールと、是正対応を実行するカスタムインテグレーションが揃いました。最後に、これらを束ねて「検知から是正までを自動化する」ワークフローを Playbooks として組み立てます。
今回作成する Playbooks は、以下の流れで構成します。SecOps の管理コンソールから Response > Playbooks > + と遷移して新規 Playbooks(今回の例ではGitHub_Public_to_Private_Demo)を作成します。
| 順序 | 要素 | 設定内容 |
|---|---|---|
| 1 | トリガー | カスタムルールでアラートを検知した場合に起動 |
| 2 | コンディション | 特定の GitHub Organization 配下のリポジトリかを判定 |
| 3 | アクション① | #2 が True の場合、カスタムインテグレーションで可視性を変更 |
| 4 | アクション② | ケースにコメントを記入 |
| 5 | アクション③ | ケースのクローズ |

トリガー
トリガーは Playbooks の起動条件です。今回は、カスタムルールが検知したアラートにのみ反応させるため、Alert Type が g_gen_github_repo_visibility_to_public である場合に設定します。これにより、このアラート以外では Playbooks が起動しません。

コンディション
コンディションは Playbooks 内の条件分岐です。ある条件を満たす場合のみ後続の処理へ進み、満たさない場合は別ルート(ELSE)へ分岐させられます。
コンディションを挟んだ理由は、是正の対象を特定の Organization のリポジトリに限定するためで、今回の例では g-gen-secops-test/ で始まる場合のみ、後続のアクションへ進むよう設定します。

アクションの設定
アクションは Playbooks で実行する実際の処理です。今回はコンディションの条件を満たした場合、3 つの処理を実行します。
1つ目は、Public に変更されたリポジトリの可視性を Private に戻す処理(Set Repository Visibility)です。カスタムインテグレーションで作成したインスタンスを選択し、入力パラメータを以下のように設定します。
対象のリポジトリはプレースホルダ(Event.event_target_resource_name)とすることで、発火したアラートから動的に判断します。

2つ目は、ケースにコメントを記入する Case Comment です。これは Google SecOps 標準の Siemplify インテグレーションに含まれるアクションで、ケースに任意のコメントを記入するために使用します。Comment に自動対応の記録を残します。

3つ目は、対応が完了したケースをクローズする Close Case です。先程同様 Siemplify インテグレーションに含まれるアクションで、自動対応の済んだケースを未対応のまま残さずクローズするために使用します。

動作確認
動作確認を行うため、カスタムルールの検知対象となる操作(リポジトリの可視性を Public に変更)を実行します。

しばらくすると、Google SecOps のケース画面にてアラートを検知していたことがわかりますが、その時点で既にケースがクローズされています。
Playbooks の起動条件を満たすアラートが検知されたため、可視性変更からケースのクローズまでの一連処理が自動的に実行され、かつ、正常終了していることがわかります。

ケースの詳細を確認すると、Case Comment で定義したコメントが入力済みです。

肝心の GitHub リポジトリの可視性についても Public -> Private に変更されていることを確認できました。

