Viva Engage Core APIで403エラーが出る原因と必要な権限:verified_adminでは不足するケースとYammer group_idのGraph紐付け

Viva Engage(旧Yammer)のCore APIで、/meではverified_adminがtrueなのに、特定エンドポイントだけHTTP 403(アクセス拒否)になる――この現象は「権限はあるはず」という思い込みが原因でハマりがちです。本記事では403の正体をロールと公開範囲の観点で整理し、必要な権限と運用上の落としどころ、さらにNetwork Data Exportのgroup_idをMicrosoft Graphに紐付ける考え方まで解説します。

目次

結論:verified_adminは“万能の管理者”ではない

まず押さえるべきポイントは、Viva Engage Core APIで見えるロール(/meで返るフラグ)は「管理画面の一部操作ができる」ことを示しても、非公開(プライベート)領域や他ユーザーの所属情報まで横断的に閲覧できることを保証しない、という点です。

特に次の3つは、公開設定やプライバシーに直結するため、403が出やすい代表格です。

  • /users/in_group/:group_id.json(特定グループのメンバー取得)
  • /threads/:thread_ids.json(特定スレッドの取得)
  • /groups/for_user/:user_id.json(特定ユーザーが所属するグループ一覧取得)

なぜ「ユーザー一覧」「グループ一覧」は通るのに、特定APIだけ403になるのか

一覧系のAPIは、基本的に公開範囲に応じて“見えてよい範囲”だけを返す作りになっていることが多く、呼び出し側が管理者でなくても成立します。一方で、今回の3エンドポイントは次のように性質が異なります。

エンドポイント返す情報センシティブ度403が起きやすい条件
/users/in_group/:group_id.json指定グループのメンバー全員高(所属情報)非公開グループを“横断参照”しようとした
/groups/for_user/:user_id.json指定ユーザーが所属するグループ(公開/非公開含む)非常に高(行動・所属の推測につながる)ネットワーク管理者以外が他ユーザーの所属を取ろうとした
/threads/:thread_ids.jsonスレッド本文・メタ情報高(非公開グループ内投稿を含み得る)スレッドが非公開グループ内/閲覧権がない

つまり「呼べるAPI」と「呼べないAPI」の差は、ロールそのものだけでなく、対象データが“公開”か“非公開”か、そして呼び出しユーザーが“当事者”か“第三者”かで決まります。

/meのロールフラグを読み解く(よくある誤解を潰す)

/meで取得した以下のような状態は、一見すると強い権限に見えます。

  • admin: true
  • verified_admin: true
  • m365_yammer_admin: false
  • o365_tenant_admin: false

ここで重要なのは、verified_adminは“管理者であることの検証フラグ”に近い一方、ネットワーク全体を横断して非公開領域まで取得できるかは、別ロール(ネットワーク管理者など)に依存する、という見立てです。

フラグ意味のイメージAPIアクセスへの影響(ざっくり)
admin何らかの管理ロールを持つ一覧系など“公開範囲”の操作では効くが、非公開領域の横断は保証しない
verified_admin管理者として検証済み“便利な管理操作”はできても、非公開/他者所属の参照は制限されることがある
m365_yammer_adminViva Engage/YammerをM365側で統括する管理者扱いネットワーク横断に近い操作が必要な場合に影響しやすい
o365_tenant_adminテナント全体の管理者相当横断権限の“上位”として扱われる構成もある(環境依存)

実務では、/meのフラグだけで判断せず、「対象グループが非公開か」「自分がそのグループの管理者/メンバーか」を必ずセットで確認します。

エンドポイント別:403の原因と必要なロール(最重要)

/users/in_group/:group_id.json(グループメンバー一覧)

このAPIは指定したグループのメンバーを“全件”返すため、グループが非公開の場合は強い制約がかかります。

グループの種類取得できる典型パターン403になりやすい典型パターン解決の方向性
公開グループ一般ユーザー/verified_adminでも参照できることが多いネットワーク設定で外部連携を制限しているトークンのユーザー/ネットワーク設定を再確認
非公開(プライベート)グループネットワーク管理者、または当該グループのグループ管理者verified_adminのみで、他人が所属する非公開グループのメンバー一覧を取ろうとしたNetwork Admin付与、または対象グループのGroup Adminに追加

ポイントは、「メンバー一覧=所属情報」であり、非公開グループでは“閲覧できる人が限定される”のが自然な設計だという点です。

/groups/for_user/:user_id.json(ユーザーの所属グループ一覧)

このAPIは、指定ユーザーが所属するグループ(公開・非公開)をまとめて返すため、情報の性質が非常にセンシティブです。基本的に利用できるのはネットワーク管理者のみ、という扱いになりやすい領域です。

やりたいこと403になりやすい例実務での代替案
特定ユーザーの所属グループを網羅的に取得したいverified_adminで他ユーザーの所属を取得Network Adminで実行する/要件を「公開グループのみ」に落とす
“自分自身”の所属グループを知りたい他ユーザーIDを誤って指定しているまずは自分のユーザーIDで検証し、呼び出し対象を見直す

運用上は、このAPIを“誰でも叩ける”状態にすると、組織内の活動や所属構造が推測されやすくなります。API設計としても制限が強いのは妥当です。

/threads/:thread_ids.json(スレッド取得)

スレッド取得は一見「投稿の取得」ですが、スレッドが非公開グループに属していれば、実質的に非公開コンテンツの取得になります。アクセス可否は次の条件で決まります。

  • ネットワーク管理者(Network Admin)
  • 当該グループのグループ管理者(Group Admin)
  • そのスレッドの投稿者本人(Thread Poster)

上記以外が非公開グループ内のスレッドを取りに行くと、403になりやすいです。

スレッドの場所呼び出しユーザー結果の傾向
公開グループ/全体一般ユーザー取得できることが多い
非公開グループメンバーだが管理者ではない設定次第で取得可/不可が分かれやすい(少なくとも“閲覧権”が必要)
非公開グループ第三者(非メンバー)403になりやすい
非公開グループNetwork Admin / Group Admin / 投稿者本人取得できる可能性が高い

403を最短で切り分けるチェックリスト

403は「認証の失敗」ではなく「認証は通っているが許可されていない」状態です。原因を早く確定するために、次の順で潰すと効率的です。

  1. 対象が非公開グループ/非公開スレッドではないか(まずここが最頻出)
  2. 呼び出しユーザーは当該グループのメンバーか(非メンバーなら403が自然)
  3. 呼び出しユーザーはGroup Adminか(グループ管理者として追加されているか)
  4. Network Admin(ネットワーク管理者)か(Viva Engageの管理センター側で付与されているか)
  5. 対象ID(group_id / thread_id / user_id)の取り違えがないか(別ネットワーク・別ユーザーのIDを渡していないか)
  6. 同じトークンで“公開グループの同種API”が通るか(通るならトークンより権限・公開範囲が濃厚)

特に「一覧は通るのに、特定グループ/特定ユーザー関連だけ403」は、ほぼ権限不足か公開範囲の制約です。

必要な権限をどう付けるべきか(最小権限の設計パターン)

API連携では“強すぎる管理者アカウントで全部取る”が一番簡単に見えますが、監査・運用・セキュリティの観点で避けたいケースも多いはずです。要件別に、現実的な付与パターンを整理します。

要件おすすめの権限設計メリット注意点
公開グループのデータだけ集計したい一般ユーザー権限(必要最小限)運用が軽い、情報漏えいリスクが低い非公開グループは取得対象外になる
特定の非公開グループだけ対象にしたい対象グループのGroup Admin(またはメンバー)に限定して付与範囲が明確で監査しやすいグループが増えると運用が増える
ネットワーク全体(非公開含む)を横断して取得したいNetwork Admin(ネットワーク管理者)で実行403の詰まりが最小化される権限が強い。保管・ログ・実行基盤の統制が必須
“誰がどのグループに所属しているか”を網羅したいNetwork Adminが基本線。可能なら要件自体を再検討取得自体は可能になる扱う情報がセンシティブ。目的・保存期間・閲覧権の設計が重要

運用で差が出る:403を前提にした実装のコツ

Viva Engageのデータは公開範囲が混在するため、完璧に「すべて取れる」前提で作ると障害になります。現場では次のような実装にしておくとトラブルが減ります。

  • 403は“例外”ではなく“想定内”として扱う(ログに残し、処理は継続できる設計にする)
  • 取得対象の優先順位を付ける(公開→対象グループ→全体、のように段階化)
  • グループの公開設定をメタデータとして保持(後で「なぜ取れないか」を説明しやすい)
  • API呼び出しアカウントを“人”にしない(退職・異動で権限が変わると連携が止まる)

また、監査対応を考えると、誰がいつどのAPIを叩き、どの範囲を取得したかを残せるようにしておくと安心です。

Network Data ExportのMessages.csvにあるgroup_idをMicrosoft Graphのグループに紐付ける

2つ目の論点として、Network Data Export(エクスポート)で出てくるYammerのgroup_idを、Microsoft Graph上のMicrosoft 365グループと対応付けられるか、という問題があります。結論は「環境(運用モード)次第で、できる場合とできない場合がある」です。

紐付けできる可能性が高いケース:ネイティブモード(Native Mode)

Viva Engageがネイティブモードで運用されている場合、Viva Engageのグループは裏側でMicrosoft 365グループと1対1で結びついていることが多く、Yammer側のgroup_idから“対応するM365グループ”へ辿れる可能性が高まります。

実務での考え方としては、次のような流れになります。

  1. エクスポートのgroup_idを起点に、Viva Engage側で当該グループの詳細情報を取得する
  2. 詳細情報にMicrosoft 365グループとの連携情報(IDやURLなど)が含まれていれば、それをキーにMicrosoft Graphでグループ情報を取得する
  3. Graph側で、メールアドレス、表示名、所有者、関連するリソース(必要に応じて)を参照する

ここで大事なのは、“Yammerのgroup_idそのもの”がGraphのgroup id(GUID)にそのまま一致するわけではない点です。ネイティブモードでも、間に「連携情報(別ID)」が挟まるのが一般的です。

紐付けが難しい/できないケース:ネイティブモードではない、またはM365グループ非連携のグループ

一方で、次のようなグループはMicrosoft 365グループと結び付いていないことがあり、Graph側へ正規にマッピングできません。

  • 古い運用形態のYammerグループ(レガシー)
  • 外部ネットワーク向けのグループなど、M365グループを前提にしない構成
  • 組織の設定上、Viva EngageグループをM365グループへ接続していないケース

この場合、現実的な落としどころは次のいずれかになります。

アプローチ内容向いているケース弱点
Viva Engage内で完結させるYammerのgroup_idを一次キーとして、分析・保管・検索をViva Engage側の概念で統一するエクスポート分析が主目的Graph側の周辺情報(所有者、Teams連携など)は結び付きにくい
人手/半自動で対応表を作るグループ名、作成日、説明文などを材料に、M365グループと突合してマッピング表を作る対象グループ数が限定的名前変更・重複に弱い、継続運用が大変
ネイティブモード移行を検討する将来的にM365グループとの1対1管理を前提に整備するM365統合を強めたい移行は影響範囲が大きいので計画が必要

手元の情報だけでできる「紐付け可否」の見極めポイント

環境にログインできる場合、次の観点で“紐付けが現実的か”を早めに判断できます。

  • Viva Engageのグループ作成がMicrosoft 365グループと連動しているか(運用ルールやUIの挙動で分かることが多い)
  • グループ詳細にM365関連の項目が出るか(Outlook/SharePoint/Teamsへの導線がある等)
  • 同名のMicrosoft 365グループが存在するか(ただし同名はあり得るので確証にはしない)

もし“紐付けが必要な理由”が「所有者を特定したい」「Teams連携の有無を知りたい」などであれば、最初からGraph起点で調べる方が早いケースもあります。逆に“投稿内容の監査・分析”が主目的なら、Yammer側のIDで統一しても十分に価値が出ます。

よくある落とし穴(403と紐付けの両方に効く)

  • 「管理者だから見えるはず」という前提:verified_adminは万能ではなく、非公開領域は別扱いになりやすい
  • “ユーザーID”と“サインインしているユーザー”の混同:サービスアカウントで実行しているつもりが、実は別ユーザーのトークンになっている
  • 非公開グループの存在を想定していない:公開前提の集計ロジックだと、後から説明不能な欠損になる
  • group_idの意味を取り違える:Yammerのgroup_idはGraphのgroup idとは別物。紐付けには“連携情報”が必要

まとめ:403をゼロにするより、設計で勝つ

今回のように、/meでverified_admin: trueが取れても、非公開グループや他ユーザーの所属情報まで取得できるとは限りません。特に次の整理をしておくと、実務が一気に楽になります。

  • 403が出る3エンドポイントは、非公開領域・所属情報・スレッド閲覧権に強く依存する
  • 横断取得が必要なら、Network Admin(ネットワーク管理者)や当該Group Adminが現実的
  • /groups/for_user/:user_id.jsonは特にセンシティブで、ネットワーク管理者のみに寄せた運用が無難
  • Network Data Exportのgroup_idとGraphのグループは、ネイティブモードなら紐付け可能性が高いが、非ネイティブ/非連携グループはマッピングできないことがある

「どうしても全部取りたい」のか、「必要な範囲だけ確実に取りたい」のか。要件を言語化し、最小権限で成立する設計に落とし込むことが、Viva Engage API連携を長く安定させる近道です。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次