SharePointで秘密度ラベル(Sensitivity labels)を使っていると、「どんなラベルが使えるのか」「各ファイルに何のラベルが付いているのか」をAPIで把握したくなります。本記事では、SharePoint RESTだけでは一覧取得できない理由と、Microsoft Graphで定義一覧・付与状況を取得する実践手順をまとめます。
SharePointの秘密度ラベルとは(何が「一覧」なのかを整理)
秘密度ラベル(Sensitivity labels)は、Microsoft Purview(旧 Microsoft Information Protection / AIP)の仕組みで定義される「情報の取り扱いルール」です。ラベルはテナントで一元定義され、ユーザーやグループに公開(発行)され、OfficeファイルやSharePoint/OneDrive上のドキュメントに付与されます。
ここで混乱しやすいのが、「ラベルを一覧したい」と言ったときに、実は次の2種類が混在している点です。
- ラベル定義の一覧:テナントにどんな秘密度ラベルが存在するか(表示名、説明、色、優先度、親子関係など)
- ラベル付与状況の一覧:SharePoint上のどのファイルに、どのラベルが付いているか(ライブラリ全体で集計したい、棚卸ししたい)
この2つは「取得対象」と「取得単位」が違うため、APIの選び方も実装方法も変わります。まずは目的を切り分けるのが最短ルートです。
| あなたが欲しい「一覧」 | 主な用途 | 基本方針 | 取得の粒度 |
|---|---|---|---|
| ラベル定義(どんなラベルがあるか) | ラベルのカタログ化、社内ツールへの選択肢表示、ID→表示名の辞書化 | Microsoft Graphでラベル一覧を取得 | ラベル(テナント/ユーザー) |
| 付与状況(どのファイルに何が付いたか) | 棚卸し、監査、ライブラリ別・ラベル別の件数集計、移行前後比較 | ファイル列挙→ファイルごとにラベル取得→自前で集計 | driveItem(ファイル) |
混同注意:保持ラベル(Retention label)や「ラベル列」とは別物
検索キーワードが「SharePoint ラベル API」だと、保持ラベル(Retention label)や、ドキュメントライブラリのメタデータ列(Choice列など)に行き着くことがあります。しかし、本記事で扱う秘密度ラベルは情報保護(暗号化・透かし・共有制御など)のラベルであり、保持(保管期間)とは管理領域もAPIも異なります。
「保持ラベル(retention)」はCompliance/Records管理寄り、「秘密度ラベル(sensitivity)」はPurview Information Protection寄り、と覚えておくと迷子になりにくいです。
結論:SharePoint REST APIだけでは「秘密度ラベル定義の一覧」を直接取得できない
SharePoint REST APIは、リスト/ライブラリ、ファイル、ユーザー、権限などのSharePoint固有のリソースに強い一方で、秘密度ラベルの「定義(カタログ)」を一覧で返すエンドポイントを提供していません。秘密度ラベルはPurview側の管理領域にあり、SharePoint単体のRESTでテナント全体のラベル定義を引き出すのは基本的に想定されていないためです。
したがって、ラベルの「定義」を一覧したい場合はMicrosoft Graph APIを使うのが現実解になります(Microsoft LearnでもGraph利用が前提として扱われています)。
ラベル定義を一覧取得する(Graphで「どんなラベルがあるか」を取る)
ラベル定義の一覧取得は、Graphの「Sensitivity labels」一覧APIで行います。ポイントは、どのAPIバージョンで、誰の視点(テナント全体/ユーザー視点)で取得するかです。
代表的な取得パターン
| パターン | 取得できるもの | 呼び出し例 | 向いているケース | 注意点 |
|---|---|---|---|---|
| テナント全体のラベル定義(v1.0) | 組織に存在するラベルの一覧 | GET https://graph.microsoft.com/v1.0/security/dataSecurityAndGovernance/sensitivityLabels | 社内システムのマスター同期、ID辞書の作成 | 権限(スコープ)と管理者同意が必要 |
| ラベル定義(beta: informationProtection) | informationProtection配下のラベル一覧 | GET https://graph.microsoft.com/beta/security/informationProtection/sensitivityLabels | サンプル検証、ドキュメントの差分確認 | betaは変更され得るため本番利用は慎重に |
| ユーザー視点のラベル定義(beta: /me) | そのユーザーに見えているラベル一覧 | GET https://graph.microsoft.com/beta/me/security/informationProtection/sensitivityLabels | 「発行されたラベルだけ」をUIに出したい | 委任権限(ユーザーサインイン)が必要 |
必要な権限(スコープ)の考え方
Graphのラベル一覧APIは、委任(Delegated)とアプリ(Application)で必要権限が分かれます。記事冒頭の「どの視点で一覧したいか」がここに直結します。
- 委任権限:ユーザーがサインインして、そのユーザーの見えている範囲で取得したい(例:Webアプリで「自分が選べるラベル」を表示)
- アプリ権限:バックグラウンドでテナント全体のマスターを同期したい(例:棚卸しバッチ、監査レポート、データレイク連携)
たとえば beta の informationProtection 系の一覧では、委任は InformationProtectionPolicy.Read、アプリは InformationProtectionPolicy.Read.All が典型です。v1.0 のテナント全体一覧では SensitivityLabel.Read(最小)または SensitivityLabels.Read.All といった権限が案内されています。詳細は各Microsoft LearnのAPIページを参照してください。
実行手順(アプリ権限でテナント全体のラベルを同期する)
「まずはラベル定義を全部取って、社内ツールのマスターにしたい」ケースの定番フローです。
- Microsoft Entra ID(Azure AD)でアプリ登録を作成
- Microsoft Graph の Application permissions に、ラベル一覧APIに必要な権限を追加
- 管理者が Admin consent を付与
- クライアントシークレット(または証明書)を用意
- OAuth 2.0(Client Credentials)でアクセストークン取得
- Graphのラベル一覧APIを呼び出す
トークン取得(Client Credentials)の例です(実際の値は置き換えてください)。
POST https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token
Content-Type: application/x-www-form-urlencoded
client_id={clientId}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret={clientSecret}
&grant_type=client_credentials
続いてラベル一覧を取得します。
GET https://graph.microsoft.com/v1.0/security/dataSecurityAndGovernance/sensitivityLabels
Authorization: Bearer {access_token}
レスポンスはラベルの配列になります。運用では、少なくとも id(ラベルID) と displayName(表示名) を辞書として保持しておくと、後述の「ファイル付与状況の集計」で必ず役立ちます。
レスポンスを設計に落とし込むコツ(ID辞書・キャッシュ・差分検知)
ラベル定義は頻繁に変わるものではありませんが、運用では「変更がゼロではない」点が重要です。たとえば表示名変更、ラベルの廃止、親ラベル配下のサブラベル追加などが起こり得ます。そこでおすすめは次の運用設計です。
- ラベルIDを主キーにする:表示名は変更される可能性があるため、IDベースで管理する
- 取得結果をキャッシュする:毎回Graphに取りに行くのではなく、1日1回などで同期してアプリ側に保持
- 差分をログに残す:前回取得と比較して、表示名変更や新規追加を検知(監査や運用トラブル回避に効く)
- beta依存を避ける:本番は可能な限り v1.0 を採用し、betaは検証用途に限定
SharePoint上のファイルに付与された秘密度ラベルを取得する(driveItemごとに抽出して集計)
「このサイトのドキュメントライブラリに、どのラベルがどれだけ付いているか」を知りたい場合、必要なのは“ラベル定義の一覧”ではなく、ファイル(driveItem)単位のラベル情報です。
ここで大事なのは、ラベル付与状況の取得は単発の一覧APIで完結しないことです。基本形は次の流れになります。
- 対象サイト/ドキュメントライブラリ(drive)を特定する
- ライブラリ内のファイル(driveItem)を列挙する(ページングあり)
- 各ファイルに対して、秘密度ラベル情報を取得する(抽出APIなど)
- 取得結果を自前で集計し、レポート化する
まずはIDを揃える(site-id / drive-id / item-id の取り方)
APIが正しくても、IDの取り違えで詰まることがよくあります。棚卸しバッチや運用スクリプトを作るなら、最初にIDの取り方を型として押さえておくと安定します。
| 欲しいID | よく使う取り方(例) | メモ |
|---|---|---|
| site-id | GET /sites/{hostname}:/sites/{site-path} または GET /sites?search={keyword} | テナント内で同名サイトがあると検索結果が複数になることがある |
| drive-id(ライブラリ) | GET /sites/{site-id}/drives | ドキュメントライブラリごとにdriveが分かれる |
| item-id(ファイル) | GET /drives/{drive-id}/root/children などの一覧結果から取得 | ページング(@odata.nextLink)に注意 |
手元で素早く確認したいなら、Graph Explorerで同じリクエストを叩いてIDを確認すると、環境差分の切り分けが早くなります。
代表的な取得API:driveItem: extractSensitivityLabels
Graphには、ファイルに付与された秘密度ラベル情報を抽出するアクションとして driveItem: extractSensitivityLabels が用意されています。これを使うと、指定したファイルに関連する秘密度ラベル情報を取得できます。
呼び出しイメージ(driveId と itemId を使う例):
POST https://graph.microsoft.com/v1.0/drives/{drive-id}/items/{item-id}/extractSensitivityLabels
Authorization: Bearer {access_token}
サイト起点で呼ぶ場合は、次のような形になります。
POST https://graph.microsoft.com/v1.0/sites/{site-id}/drive/items/{item-id}/extractSensitivityLabels
実際のレスポンス構造や必要権限はMicrosoft Learnの該当ページを確認してください(ファイル内容にアクセスできる権限が前提になりやすい点に注意)。
ファイル列挙の基本:まずdriveItemを一覧する
抽出APIは「ファイル単位」なので、先に対象範囲のファイル一覧を作ります。典型は、ドキュメントライブラリ(drive)配下を列挙する方法です。
GET https://graph.microsoft.com/v1.0/sites/{site-id}/drives
GET https://graph.microsoft.com/v1.0/drives/{drive-id}/root/children?$top=200
Authorization: Bearer {access_token}
レスポンスに @odata.nextLink が出ている場合は、次リンクをたどって全件取得します。ここをサボると「一部しか集計できていなかった」という事故につながります。
スケール設計:大規模ライブラリを現実的に回すための工夫
数千〜数十万ファイル規模になると、「全件列挙→全件抽出」を愚直にやるだけでは、時間もAPIコール数も膨らみ、スロットリング(HTTP 429)に直面します。現場では次の工夫が効きます。
- 差分(増分)で回す:毎回フルスキャンせず、変更分だけ処理する(Graphのdeltaクエリを検討)
- バッチ化・並列化は“控えめに”:並列を上げすぎると429が増え、結果的に遅くなる。リトライ(Retry-After)前提で設計
- 対象範囲を絞る:特定ライブラリ、特定フォルダー、特定拡張子などに限定してコール数を減らす
- 結果を永続化する:CSV/DBに保存し、2回目以降は「未取得・更新あり」だけを処理
集計の考え方:ラベルIDを“定義一覧”と突合する
ファイルから取れるラベル情報が「ラベルID中心」になるケースは珍しくありません。そこで、先に取得しておいたラベル定義の一覧(ID→表示名)と突合して、レポートとして読める形にします。
| 処理ステップ | 入力 | 出力 | ポイント |
|---|---|---|---|
| ラベル定義同期 | Graph(ラベル一覧) | labelId → displayName の辞書 | 毎回取らずキャッシュ推奨 |
| ファイル列挙 | Graph(driveItem一覧) | itemId, name, webUrl, lastModifiedDateTime… | ページング・再帰に注意 |
| ラベル抽出 | Graph(extractSensitivityLabels) | itemId → labelId(複数の可能性) | 429対策・リトライ必須 |
| 集計 | 辞書+抽出結果 | ラベル別件数、サイト別、ライブラリ別など | 監査観点で「未ラベル」も数える |
集計結果の例(イメージ):
| ラベル | 件数 | 備考 |
|---|---|---|
| 機密(社外秘) | 128 | 共有リンク制限の対象 |
| 社内限定 | 542 | 既定のラベルとして利用 |
| 未ラベル | 87 | 棚卸しで重点確認 |
PowerShellでの実装例(概念サンプル)
運用で一番手軽なのはPowerShellです。以下は「ラベル定義を取得→ファイル列挙→抽出→集計」の骨格だけを示した概念サンプルです(実運用ではページング、再帰、リトライ、ログ出力、永続化を追加してください)。
# 1) アクセストークンを取得済みとする($token)
$headers = @{ Authorization = "Bearer $token" }
# 2) ラベル定義(辞書)を取得
$labels = Invoke-RestMethod -Headers $headers -Uri "[https://graph.microsoft.com/v1.0/security/dataSecurityAndGovernance/sensitivityLabels](https://graph.microsoft.com/v1.0/security/dataSecurityAndGovernance/sensitivityLabels)" -Method GET
$labelMap = @{}
$labels.value | ForEach-Object { $labelMap[$*.id] = $*.displayName }
# 3) 対象ドライブ配下のアイテムを列挙(例:root直下)
$items = Invoke-RestMethod -Headers $headers -Uri "[https://graph.microsoft.com/v1.0/drives/{drive-id}/root/children?$top=200](https://graph.microsoft.com/v1.0/drives/{drive-id}/root/children?$top=200)" -Method GET
# 4) 各ファイルのラベルを抽出してカウント
$count = @{}
foreach ($item in $items.value) {
if ($item.file -ne $null) {
$res = Invoke-RestMethod -Headers $headers -Uri "[https://graph.microsoft.com/v1.0/drives/{drive-id}/items/$($item.id)/extractSensitivityLabels](https://graph.microsoft.com/v1.0/drives/{drive-id}/items/$%28$item.id%29/extractSensitivityLabels)" -Method POST
foreach ($lab in $res.value) {
$name = $labelMap[$lab.id]
if (-not $count.ContainsKey($name)) { $count[$name] = 0 }
$count[$name]++
}
}
}
# 5) 結果表示
$count.GetEnumerator() | Sort-Object -Property Value -Descending
ポイントは、抽出APIはPOSTであること、そして実運用ではリトライと差分処理を入れないと継続運用が厳しいことです。
よくあるつまずき(実務で多い3パターン)
- 「ラベル一覧が取れたのに、ユーザーのUIに出すとラベルが合わない」
テナント全体の定義一覧と、ユーザーに発行されているラベルは一致しない場合があります。UI用途は委任権限で /me 系の取得を検討し、マスター用途はテナント全体取得で割り切るのが安全です。 - 「403 Forbidden になる」
権限不足(スコープ不足、Admin consent未実施、アプリ権限と委任権限の取り違え)が大半です。Graph Explorerで要求権限を確認し、最小権限から積み上げてください。 - 「429 Too Many Requests で止まる」
大量ファイルに対する抽出はコール数が増えます。並列数を落とし、Retry-Afterに従ってリトライする設計が必須です。可能なら差分処理でフルスキャンを避けましょう。
よくあるエラーと対処(棚卸しバッチの運用で効く)
Graphでラベルを扱うときに遭遇しやすいエラーを、原因と対処をセットで整理します。運用スクリプトにリトライやログ出力を入れる際のたたき台として使ってください。
| HTTP | 症状 | 主な原因 | 対処 |
|---|---|---|---|
| 401 Unauthorized | トークンが無効/期限切れ | トークン取得フローの不備、スコープ指定ミス | /.default の指定、テナントID・client secretの見直し。長時間処理は途中でトークン更新を考慮 |
| 403 Forbidden | 権限不足で拒否 | 必要スコープ不足、Admin consent未実施、委任/アプリ権限の取り違え | Microsoft Learnの「Permissions」節を確認し、権限追加→管理者同意。UI用途は委任権限、バッチ用途はアプリ権限を選ぶ |
| 404 Not Found | サイト/ドライブ/アイテムが見つからない | IDの取り違え、パス指定ミス、アクセス権がないリソース | Graph Explorerで site-id / drive-id / item-id を再取得。対象にアクセスできる権限があるか確認 |
| 429 Too Many Requests | スロットリング | 大量の列挙・抽出、並列しすぎ | Retry-Afterを尊重し指数バックオフで再試行。並列数を下げ、差分処理・対象絞り込みを導入 |
| 5xx | 一時的な失敗 | サービス側の一時障害、ネットワーク揺れ | リトライ(上限付き)とログ出力。継続的ならMicrosoft 365の障害情報も確認 |
SharePoint REST APIでできること/できないこと(誤解を防ぐ整理)
| やりたいこと | SharePoint REST | Microsoft Graph | コメント |
|---|---|---|---|
| 秘密度ラベル定義の一覧取得 | 基本的に不可 | 可能 | Purview側の定義をGraphで取得するのが王道 |
| ライブラリ内のファイル一覧取得 | 可能 | 可能 | 大規模・増分処理はGraphのdelta等も検討 |
| ファイルに付与されたラベル情報の取得 | 限定的(環境依存) | 可能(抽出APIなど) | 一覧化するならGraph中心が安定 |
まとめ:最短で「一覧取得」を成功させる実務的な手順
- まず「定義一覧」か「付与状況」かを切り分ける(実装が別物)
- 定義一覧はGraphのSensitivity labels一覧APIで取得し、ID辞書を作る
- 付与状況は「ファイル列挙→ファイルごとにラベル取得→自前で集計」が基本形
- 大規模運用は差分処理・リトライ・キャッシュが勝ち筋

コメント