大規模テナントの監査をスケールさせる:ページング、スロットリング、大規模テナントのM365監査の管理
By Mirko Peters ·
ブログへようこそ。大規模な Microsoft 365 環境を管理しているなら、標準で用意されているレポートツールでは表面的な情報しか得られないことは、すでにご存じでしょう…
Automatically translated with AI from the original post. Read the English original
ブログへようこそ。大規模な Microsoft 365 環境を管理している方なら、標準の既定レポート ツールでは表面的な情報しか得られないことをご存じでしょう。セキュリティ チームやコンプライアンス担当者が大規模テナントを確認しようとすると、基本的なスクリプトや管理センターの既定の画面では、何千ものユーザー、グループ、ファイルを前にして機能しなくなります。大規模な M365 テナントの監査には基本的なスクリプト以上のものが必要で、Microsoft Graph API を使った戦略的でプログラムによるアプローチが求められます。この総合ガイドでは、最近のポッドキャスト エピソード Map Microsoft 365 Users, Groups, Files, and Shares with Graph の内容をさらに掘り下げます。@odata.nextLink によるページングの扱い方、指数バックオフによる 429 レート制限への対応、そして Page 1 バイアスなどのよくある落とし穴を避け、テナント全体を把握する方法を詳しく見ていきましょう。
M365 監査の課題の紹介
企業環境は自然に拡大していきます。ユーザーは入れ替わり、プロジェクトは一夜にして部門を生み出し、外部ベンダーがコラボレーション スペースに招待されます。時間が経つにつれ、管理者の可視性は低下します。既定の管理センターに表示されるのは基盤の断片的な情報にすぎず、悪意のある攻撃者や不注意な内部関係者が悪用しうる死角が残ります。テナントのセキュリティ態勢を正しく把握するには、手作業によるポイントアンドクリックの監査から、API を使った Graph のトラバースによる自動化への移行が必要です。ただし、こうしたクエリを企業規模に拡大すると、大量のデータ ペイロード、厳しいスロットリング、入れ子が深い関係構造といった複雑な課題が生じます。
M365 は独立していない:関係ベースのアクセスを理解する
Microsoft 365 の基本的な特徴の 1 つは、SharePoint、Teams、OneDrive が独立したサイロではないことです。これらのサービスは、グループ メンバーシップや基盤となるアクセス制御リストを通じて、絶えず相互に影響し合っています。たとえばユーザーをセキュリティ グループに追加するという 1 回の管理操作が、標準の画面では監査の痕跡をほとんど残さないまま、数十のチーム サイト、ドキュメント ライブラリ、プライベート チャネルに波及することがあります。
ここから見過ごされがちなコンプライアンス リスクが生まれます。孤立したチャットで共有されたゲスト リンク、別のチームのライブラリに複製されたファイル、終了した古いプロジェクトに残された共有は、企業データへの目に見えない経路となります。M365 のアクセスは、場所ではなく本質的に関係性によって決まります。効果的に監査するには、各サービスを独立した島として扱うのではなく、これらの連鎖した関係をマッピングする必要があります。
Graph Explorer によるフットプリントのマッピング
大規模な自動化を書く前に、Graph Explorer を使ってユーザーのフットプリントを手作業で追跡する方法を理解しておく必要があります。コードを書く前に、クエリを段階的に組み立てておくことで、ロジックが正しいことを確認できます。ユーザーとの接点をマッピングするための手順は次のとおりです。
- ユーザーを起点にする:GET /v1.0/users/{userPrincipalName}?$select=id,displayName,userPrincipalName を使って、ユーザー オブジェクトの基本情報を取得します。
- メンバーシップを列挙する:GET /v1.0/users/{id}/memberOf?$select=id,displayName を使って、そのidentityに紐付くグループとロールを取得します。
- グループから関連リソースへ展開する:Microsoft 365 グループおよび Teams の場合は、GET /v1.0/groups/{groupId}/drive/root/children?$select=id,name,lastModifiedDateTime,webUrl で基盤の SharePoint サイトを対象にするか、GET /v1.0/sites/{siteId}/drives でサイトのドライブを直接列挙します。
- 項目のアクセス許可とリンクを取得する:GET /v1.0/drives/{driveId}/items/{itemId}/permissions?$select=id,grantedToV2,link,roles,shareId を使って、個々のファイルへのアクセスを確認します。
- 誰が何にアクセスしたかを追跡する:サインイン ログやセキュリティ アラートを、ファイルとサイトのコンテキストと関連付けてアクションを照合します。
- Teams の投稿まで確認する:GET /v1.0/teams/{teamId}/channels/{channelId}/messages?$search="filename" を使って、特定のファイル参照をチャネル メッセージから検索します(beta のアクセス許可と要件に留意してください)。
実際に使えるノイズ除去フィルター
フィルターを使わずに Microsoft Graph にクエリを投げると、データの奔流に圧倒される近道になります。実際のリスクを浮かび上がらせるには、的確なフィルター戦略が必要です。以下は、展開しておくべきクエリ パターンです。
- 過去7日間の外部共有:GET /v1.0/drives/{driveId}/items/{itemId}/permissions?$filter=link/scope eq 'anonymous' or link/scope eq 'organization' を使い、匿名リンクや組織全体のリンクを対象にします。
- リスクの高いファイルの種類のみ:$filter=endsWith(resourceReference/name,'.xlsm') や endsWith(resourceReference/name,'.pst') などのフィルターを追加し、マクロやアーカイブを含むファイルを検出します。
- 業務時間外に Teams で機密性の高い用語が言及されるケース:confidential などの用語でチャネル メッセージを検索し、作成日時が通常の業務時間外の結果で絞り込みます。
- ペイロードを軽量に保つ:必要な識別子、名前、URL、タイムスタンプのみを返すよう、常に $select パラメーターを指定します。
- トリアージの上限:クイックな抜き取り確認には $top=50 を使用しますが、データストアへの完全なエクスポートを実行する際はこのパラメーターを削除します。
エンタープライズ規模で必須の対策:ページングとスロットリング
数十万件のオブジェクトを抱えるテナント全体で監査を実行する場合、API の上限とページングを考慮しないと、スクリプトは途中で止まります。API が返すすべてのページについて @odata.nextLink プロパティをたどるまで、データの取得は完了しません。これを無視すると、スクリプトは最初のバッチしか取得できず、テナントの大半を見逃すことになります。
さらに、HTTP 429 のレート制限応答には必ず従う必要があります。堅牢な指数バックオフのロジックを実装し、スクリプトが一時停止して冷却期間を待ち、中断した箇所から途切れなく再開できるようにします。リクエストは賢くまとめ、件数の少ない大きな論理リクエストを優先し、グループとサイトの対応関係をキャッシュしてください。大規模テナントでは、サイトまたは日付範囲でクロールを分割し、本番環境のパフォーマンスへの影響を避けるため業務時間外にスケジュールしてください。
よくある落とし穴と迅速な解決策
M365 の監査を拡張する際には、経験豊富な管理者でも障害に直面します。よくある落とし穴と解決方法は次のとおりです。
- 落とし穴:スキーマが時間とともに変わるため、CSV エクスポートの内容がずれていく。解決策:バージョン管理された変換を使って Graph API を直接利用し、未知のフィールドも適切に処理する。
- 落とし穴:GUID とユーザー プリンシパル名(UPN)などの識別子が混在し、データベースの結合が壊れる。解決策:すべてを、ユーザー、グループ、サイト、ドライブ、アイテム、アクセス許可を含む、整理された意味モデルに正規化する。
- 落とし穴:最初のページだけを重視する偏りにより、結果の奥深くにあるセキュリティ インシデントの大半を見逃す。解決策:処理したページ数を常に記録し、想定されるデータ量が急減した場合にアラートを設定する。
- 落とし穴:無関係なファイルが大量に流入し、処理エンジンの負荷が高まる。解決策:共有範囲、期間、機密用語リストに厳密なフィルターを適用する。
- 落とし穴:Teams の共有が基になるファイルと切り離されている。解決策:チャネル メッセージの Web URL をドライブ アイテムに直接関連付け、両方の識別子をまとめて保存する。
このアプローチで得られる経営層向けKPI
技術データは、経営陣向けに実行可能なビジネス インテリジェンスへと変換できて初めて価値があります。自動化された Graph 監査パイプラインを構築すると、次の強力な経営層向けKPIが得られます。
- 外部への公開のスピード:チームやサイトごとに分類した、週ごとの新規ゲスト リンクの作成数を測定します。
- 機密ファイルへのアクセス率:ラベルが付与されたコンテンツの一意の閲覧者を追跡し、社内ユーザーと外部ゲストを分けて把握します。
- グループ変更の波及リスク:主要なグループ メンバーシップの変更後 24 時間以内に新たにアクセス可能になったファイルを測定します。
- 拡散の可能性:単一のスプリント内で、複数のチームやサイトに現れる機密ファイルを監視します。
- 是正の効果:取り消されたリンクの数と、是正までの時間の指標を経時的に追跡します。
クイックスタート用クエリレシピ
独自の収集パイプラインの構築を始める準備ができたら、このコピー&ペーストで使える手順から始めてください。
- ユーザーの基本情報とメンバーシップを取得:/users/{upn}?$select=id,displayName と /users/{id}/memberOf?$select=id,displayName。
- 各 M365 グループについてドライブ アイテムを列挙:/groups/{groupId}/drive/root/children?$select=id,name,webUrl,lastModifiedDateTime&$top=200 を使用し、必ず @odata.nextLink をたどってください。
- 各アイテムのアクセス許可を取得:/drives/{driveId}/items/{itemId}/permissions?$select=id,roles,grantedToV2,link を使用し、匿名または組織のスコープでフィルターします。
- 指定のデータストアに行をエクスポートし、テナントの時刻、サイト ID、ドライブ ID、アイテム ID、Web URL、所有者、スコープ、有効期限の詳細を記録します。
- 正規化したデータを Power BI で可視化し、経営層向けと運用向けのダッシュボードを作成します。
これを常時更新されるダッシュボードにする
一度だけ実行した監査はスナップショットにすぎませんが、継続的に実行する監査はセキュリティプログラムになります。未加工の Graph 呼び出しを生きたダッシュボードに変えるには、Power Dataflows にデータを取り込み、Users、Groups、Sites、Drives、Items、Permissions、Messages の正規化されたテーブルを作成します。Items を中心としたスタースキーマでデータをモデル化し、Users および Groups との明確なリレーションシップを設定します。
lastModifiedDateTime フィールドに基づいて増分更新を構成し、リスクの高いサイトについては日中に更新を実行します。最後に、ラベル付きコンテンツに新しい外部リンクが出現したとき、または group-ripple のスパイクが不正なアクセス権の拡大を示したときに通知が発動するよう、自動アラートを設定します。
30日間の展開計画
ローマは一日にして成らず。エンタープライズ向けの監査フレームワークも、慎重な段階的準備が必要です。スムーズな展開を確実に行うため、次の30日間の展開計画に従ってください。
1週目: Azure アプリの登録を設定し、最小権限の Graph API アクセス許可を割り当て、$select および $filter パラメーターを使って最初のクエリのベースラインを設定します。
2週目: ページネーションスクリプトを開発し、識別子を一貫した UPN およびデバイス名に正規化して、最初のエンドツーエンドのデータエクスポートを正常に実行します。
3週目: Power BI のデータモデルを構築し、外部公開、波及リスク、dwell-to-revoke のタイムラインなどの主要業績評価指標(KPI)を構成します。
4週目: データ更新を自動化し、異常アラートを実装したうえで、セキュリティ調査チーム向けの標準運用手順(SOP)を文書化します。
対象となる読者
このフレームワークは、「緑色」のダッシュボードの裏に見えないリスクがあるのではと疑っている M365 管理者や SecOps リーダー、サードパーティ製ツールを増やさずにエンドツーエンドの共有の可視性を必要とするコンプライアンスチーム、そして安全な外部共有の維持に責任を負うコラボレーション担当者に向けて特別に設計されています。
現場のヒント
実際の環境でこれらのスクリプトを展開する際は、次の簡単なヒントを念頭に置いてください。調査は必ずユーザーまたはファイルのいずれかから開始し、そこから両方向に掘り下げて死角をなくしてください。グループへの追加イベントはすべてリスクの高い変更として扱い、24時間以内に下流のアクセス権を確認してください。ファイル名や Teams のメッセージを検索するための、機密性の高い用語の一覧を常に最新の状態に保ってください。最後に、ページ数と結果件数を慎重に記録してください。スクリプトが何も出力しない場合は、クリーンなテナントではなく、ジョブが壊れている兆候であることが多いためです。
まとめ
ページネーションの習得、レート制限の遵守、そして Page 1 bias(1ページ目への偏り)の回避は、大規模な Microsoft 365 テナントを保護する担当者にとって不可欠なスキルです。基本的な管理コンソールを超えて Microsoft Graph API のプログラムによる機能を活用することで、目に見えない共有リスクを明確で測定可能なセキュリティインサイトに変えることができます。
より詳しい内容、コードサンプル、実践的な Graph のレシピについては、ポッドキャストでの完全な議論をぜひお聴きください。関連するエピソードは Map Microsoft 365 Users, Groups, Files, and Shares with Graph で確認できます。引き続きセキュリティを確保し、自動化を続けてください。次のエピソードでお会いしましょう!