SaaS アカウント台帳を CSV+git で自動化した——管理者権限の変更だけ人が見る設計【実録】

以前の記事で、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 キーは個人ではなく専用の管理者アカウントで発行する
📄 台帳を手動で作る段階の進め方はこちらの記事で解説しています。
📄 SaaS のライセンスを無駄なく管理する考え方はこちらの記事で書いています。

📅 30分無料相談、受け付けています

「SaaS のアカウント台帳を手で更新し続けていて、監査に耐えるか不安」——そういった段階からお気軽にどうぞ。台帳の設計から自動化まで対応しています。

📅 30分無料相談を予約する →