以前の記事で、SaaS アカウントの台帳は「最初はスプレッドシートで手動で回し、実態をつかんでから仕組みを考える」と書いた。今回はその続きだ。
ある IPO 準備中のスタートアップで、手動の台帳を自動更新の仕組みに移した。選んだのは SaaS 管理ツールでもスプレッドシートでもなく、CSV+git+GitHub Actions という地味な構成だ。なぜそうしたのか、どこで詰まったのかを書く。
この記事でわかること
- ▶ 台帳をスプレッドシートではなく CSV+git にした理由
- ▶ 「管理者権限の変更だけ人がレビューする」自動化の線引き
- ▶ サービス別の API のハマりどころ(Slack・Notion・EDR・MDM・Apple Business など)
- ▶ API キーを誰のアカウントで発行するか、という落とし穴
▼背景:「誰に何が付いているか」を俯瞰できなかった
この会社では、Slack や Notion のメンバー情報を管理画面から手で抜き出して、一覧を作っていた。しかも「契約上、API ではメンバー情報を取れない」と思われていた。
目的はシンプルだ。誰に、どのサービスの、どの権限が付いているかを1か所で俯瞰し、権限の付与と剥奪をスムーズにする。IPO 準備の IT 統制として、①アカウント管理の一元化、②アラートの一元化、③端末制御、の3本柱を立てた。その①がこの台帳だ。
▼なぜスプレッドシートではなく CSV+git なのか
台帳は2つの CSV ファイルにした。
| ファイル | 中身 |
|---|---|
| サービスマスタ | サービスごとの SSO 対応、管理者アカウントの有無、API の可否、認証方式、セットアップ工数 |
| アクセス台帳 | サービス・氏名・メールアドレス・権限・状態・付与日・最終確認日・端末名・メモ |
ここから「社員×サービス」のマトリクスを自動で生成する。
スプレッドシートにしなかった理由は1つ。変更履歴が git の差分として、そのまま監査証跡になるからだ。「いつ、誰の、どの権限が変わったか」を、あとから1行単位で追える。スプレッドシートの変更履歴でも追えなくはないが、セル単位の履歴を監査人に見せるのはつらい。
▼自動化の線引き:管理者権限の変更だけ人が見る
更新の流れはこうした。
STEP1 毎週月曜の朝、GitHub Actions が各サービスの API からアカウント一覧を取得する
STEP2 前回の台帳と比べて、追加・削除・権限や状態の変更を差分レポートにする
STEP3 差分があれば、プルリクエストを自動で作る
STEP4 管理者権限の変更が含まれなければ自動マージ。含まれていれば、人がレビューしてからマージ
STEP5 結果と、ジョブの失敗を Slack に通知する
全部を人が見ると、毎週のレビューが形骸化する。全部を自動にすると、本当に見るべき変更が埋もれる。監査で問われるのは特権の変更なので、そこだけ人の目を通す線引きにした。
もう1つ決めたのは、Claude Code は設定のときだけ使い、24時間動く実行基盤は GitHub Actions にすることだ。AI で作るコストは下がったが、保守のコストは下がっていない。作った人の PC でしか動かない仕組みは、その人がいなくなると止まる。リポジトリと Actions に寄せておけば、誰でも中身を読めて、引き継げる。
▼ハマりどころ1:名寄せは氏名ではなくメールで
最初は氏名で名寄せした。すると、同じ人物が最大4行に分裂した。サービスごとに、漢字・ローマ字・スペースの有無・旧姓など、表記がばらばらだったからだ。
名寄せのキーをメールアドレスに変えて解決した。もう1つ注意がある。「アカウントなし」と言い切れるのは、全件を取り込めているサービスだけだ。手動で一部だけ取り込んだサービスの空欄は「ない」のか「わからない」のか区別がつかない。マトリクスに注釈をつけて区別した。
▼ハマりどころ2:サービス別の API(2026年10月 実測)
| サービス | 方式 | ハマりどころ |
|---|---|---|
| Slack | Bot Token | users:read と users:read.email で一覧が取れた |
| Notion | Internal Integration | 個人のアクセストークンだとユーザー一覧の API が叩けない |
| HubSpot | サービスキー | Private App の新規作成は廃止が進んでいる |
| SentinelOne | API Token | ロールのフィールドは lowestRole(roleName ではない)。端末名から人物を推定できるのは約85%。「MacBook Air」のような汎用名は手で確認 |
| JumpCloud | API Key | コンソール管理者かどうかは API で判定できない。既知の管理者を設定値として持つしかない |
| Apple Business | JWT(ES256) | 状態が NEW のユーザーは有効な新規ユーザー。停止扱いと誤判定して、十数名を「停止中」と表示していた |
| Google Workspace | サービスアカウント | GCP のプロジェクト作成権限がないと詰む。当面は GAS で CSV を出力して取り込む |
| Zoom | Server-to-Server OAuth | アプリの作成がロール設定でブロックされることがある(オーナー権限が必要)。当面は管理画面の CSV |
| 経費精算 SaaS(一例) | なし | 公開 API がない。CSV を手で取り込む。銀行口座や初期パスワードの列は取り込まない |
「API で取れない」と決めつけない
「契約上、Slack と Notion のメンバー情報は API で取れない」という前提は、実際に試すと崩れた。Slack は Bot Token、Notion は Internal Integration で、メンバー一覧は取れた。取れないと言われたら、まずトークンの種類を確認する。
▼ハマりどころ3:API キーを誰のアカウントで発行するか
構築を急いだ結果、いくつかの API キーは作業者(つまり自分)の個人アカウントに紐づいた形で発行している。これは技術的な問題ではなく、運用の問題だ。作業者が異動・退職したら、そのアカウントと一緒にキーも失効し、台帳の更新が黙って止まる。
理想は、最初から専用の管理者アカウント(サービスアカウント)で発行することだ。今回は「まず構築を優先し、いずれ移す」と先方と合意して進めた。自分がいなくても回る仕組みを作りに来て、自分に依存する仕組みを作っては本末転倒なので、残課題として台帳にも明記している。
GitHub Secrets はバックアップにならない
API キーはローカルの環境変数ファイルと GitHub Secrets の二か所に置いた。だが GitHub Secrets は書き込み専用で、あとから値を読み出せない。正本はパスワード管理ツールに置く。
▼現時点の状況
- ▶ 自動取得:6サービス(週次更新・差分 PR・Slack 通知が稼働)
- ▶ 手動取り込み:3サービス(権限待ちが2つ、公開 API なしが1つ)
- ▶ 残課題:EDR の汎用名の端末の紐付け、手動取り込みの手順書化、API キーのサービスアカウント化
人事システムが決まれば、本来は人事情報を軸に「在籍しているのに付いていない」「退職したのに残っている」を突き合わせるのが筋だ。台帳はそのための土台になる。
▼まとめ
- ▶ 台帳は CSV+git。変更履歴がそのまま監査証跡になる
- ▶ 自動マージの例外は「管理者権限の変更」だけ。人が見る範囲を絞る
- ▶ 名寄せはメールで。全件取れていないサービスの空欄は「不明」と区別する
- ▶ 実行基盤は GitHub Actions。AI は設定時の道具にとどめる
- ▶ API キーは個人ではなく専用の管理者アカウントで発行する
📅 30分無料相談、受け付けています
「SaaS のアカウント台帳を手で更新し続けていて、監査に耐えるか不安」——そういった段階からお気軽にどうぞ。台帳の設計から自動化まで対応しています。
📅 30分無料相談を予約する →