Publicリポジトリを検知して通知する仕組みを作ってみた

Publicリポジトリを検知して通知する仕組みを作ってみた | Dブログ
SECURITY
GitHub Forgejo

Publicリポジトリを検知して通知する仕組みを作ってみた

GitHub Actions + Forgejo Actions + Mattermost Webhook による自動パトロール構築記

2026年3月末に発生したAnthropic社のAIコーディングツール「Claude Code」のソースコード流出事件、びっくりしましたね。弊社でも他人事とは思えず、GitHubとForgejoを定期的に見回ってPublicリポジトリを検知したらMattermostに通知してくれる番犬システムを作ってみました。

GitHub
CI/CD
GitHub Actions
マネージド環境。gh CLIが標準で使える。
API
gh repo list
–public オプションで最初からPublicのみ取得。
認証
MONITOR_TOKEN
repo読み取り権限を持つTokenをSecretsに格納。
Forgejo
CI/CD
Forgejo Actions (EC2)
AWS上のforgejo-runnerを活用。
実行環境
catthehacker/ubuntu
Dockerコンテナ。ジョブ後に自動破棄。
API
/api/v1/repos/search
private=false パラメータでフィルタリング。
認証
FORGEJO_TOKEN
TokenをSecretsに格納して環境変数で渡す。
共通 / 通知
curl / jq / Mattermost Webhook
jqでJSONを解析、curlでMattermostのIncoming WebhookにPOST。
1
認証トークンの発行

組織のリポジトリ一覧を取得するため、repo スコープを持ったPersonal Access Tokenを発行します。

2
GitHub Secretsへの登録

作成したTokenを MONITOR_TOKEN、MattermostのWebhook URLを MATTERMOST_WEBHOOK_URL としてリポジトリのSecretsに保存します。

3
Workflowファイル(YAML)の作成

.github/workflows/patrol.yml を作成し、schedule(cron)でJST 9:00・18:00の定期実行を設定します。

4
抽出と通知ロジックの実装

gh repo list --public で公開リポジトリのみを取得します。結果が空でない場合のみMattermostへPOSTするスクリプトを記述します。

通知ロジックのコア:

# Publicリポジトリを最大1000件取得
PUBLIC_REPOS=$(gh repo list $ORG_NAME \
  --public --limit 1000 \
  --json name --jq '.[].name')

if [ ! -z "$PUBLIC_REPOS" ]; then
  # 検知時のみMattermostへ通知
  MESSAGE="### 【警告】: 公開リポジトリを検知しました\n\
**$ORG_NAME** 内で以下がPublic設定です。\n\n\
- ${PUBLIC_REPOS// /\\n- }"
  curl -X POST -H 'Content-Type: application/json' \
    -d "{\"text\": \"$MESSAGE\", \"username\": \"GitHubパトロールボット\"}" \
    $MM_URL
else
  echo "公開リポジトリはありませんでした。"
fi

GitHub側は gh repo list --public オプションで最初からPublicのみ取得できるためシンプル。--limit 1000 で大規模組織にも対応します。

1
Forgejo-runner(セルフホスト)の準備

AWS上の既存サーバーに forgejo-runner を導入します。

2
認証トークンの発行

組織のリポジトリ一覧を取得するため、リポジトリ閲覧権限を持ったAccess Tokenを発行します。

3
Forgejo Secretsへの登録

作成したTokenを FORGEJO_TOKEN、MattermostのWebhook URLを MATTERMOST_WEBHOOK_URL としてリポジトリのSecretsに保存します。

4
Workflowファイル(YAML)の作成

.forgejo/workflows/patrol.yml を作成し、schedule(cron)でJST 9:00・18:00の定期実行を設定します。

5
抽出と通知ロジックの実装

/api/v1/repos/search APIでリポジトリ一覧を取得し、jqで対象オーナーのPublicリポジトリのみ抽出します。結果が空でない場合のみMattermostへPOSTするスクリプトを記述します。

通知ロジックのコア:

# Forgejo APIでリポジトリ一覧を取得し、jqで絞り込み
SERVER_URL="${GITHUB_SERVER_URL}"
OWNER="${GITHUB_REPOSITORY_OWNER}"

PUBLIC_REPOS=$(curl -s \
  -H "Authorization: token $FORGEJO_TOKEN" \
  "$SERVER_URL/api/v1/repos/search?private=false" | \
  jq -r ".data[] | select(.owner.login == \"$OWNER\") | .full_name")

if [ ! -z "$PUBLIC_REPOS" ]; then
  MESSAGE="### 【警告】: 公開リポジトリを検知しました\n\
**$OWNER** 内で以下のリポジトリがPublic設定です。\n$PUBLIC_REPOS"
  curl -i -X POST -H 'Content-Type: application/json' \
    -d "{\"text\": \"$MESSAGE\", \"username\": \"Forgejoパトロールボット\"}" \
    $MATTERMOST_URL
else
  echo "公開リポジトリはありませんでした。"
fi

構築を進める中で、Forgejoサーバー側の設定を確認していたところ、重要な事実が判明しました。

✅ Forgejoはそもそも外部公開できない設定だった

管理画面のDanger Zoneを確認したところ、「公開 (Public)」に変更するボタン自体が存在しませんでした。管理者レベルの設定で、世界への公開がシステム的にブロックされていることが確認できました。

「Internal(ログイン者のみ)」は意図的な運用のケースがあるため通知対象から除外し、万が一Publicが有効化された場合のみ反応するサイレント監視の形としました。この『仕様の裏付け』が取れたことで、監視の設計を「Internalは許容、Publicは異常」と明確に定義できました。

🛡️

これで GitHub・Forgejo 双方のPublicリポジトリを自動監視 できるようになりました。普段は静かで、何かあった時だけ通知が来る──理想的な番犬システムのできあがりです!

© 2026 Dブログ ── mk-dt.com

Recruit

ディーメイクでは各ポジションで一緒に働く仲間を募集中! エンジニア、デザイナー、ディレクターなど、多彩な職種があります。
一緒に成長していきましょう!

  • URLをコピーしました!

コメント

コメントする