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: trueverified_admin: truem365_yammer_admin: falseo365_tenant_admin: false
ここで重要なのは、verified_adminは“管理者であることの検証フラグ”に近い一方、ネットワーク全体を横断して非公開領域まで取得できるかは、別ロール(ネットワーク管理者など)に依存する、という見立てです。
| フラグ | 意味のイメージ | APIアクセスへの影響(ざっくり) |
|---|---|---|
admin | 何らかの管理ロールを持つ | 一覧系など“公開範囲”の操作では効くが、非公開領域の横断は保証しない |
verified_admin | 管理者として検証済み | “便利な管理操作”はできても、非公開/他者所属の参照は制限されることがある |
m365_yammer_admin | Viva 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は「認証の失敗」ではなく「認証は通っているが許可されていない」状態です。原因を早く確定するために、次の順で潰すと効率的です。
- 対象が非公開グループ/非公開スレッドではないか(まずここが最頻出)
- 呼び出しユーザーは当該グループのメンバーか(非メンバーなら403が自然)
- 呼び出しユーザーはGroup Adminか(グループ管理者として追加されているか)
- Network Admin(ネットワーク管理者)か(Viva Engageの管理センター側で付与されているか)
- 対象ID(group_id / thread_id / user_id)の取り違えがないか(別ネットワーク・別ユーザーのIDを渡していないか)
- 同じトークンで“公開グループの同種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グループ”へ辿れる可能性が高まります。
実務での考え方としては、次のような流れになります。
- エクスポートの
group_idを起点に、Viva Engage側で当該グループの詳細情報を取得する - 詳細情報にMicrosoft 365グループとの連携情報(IDやURLなど)が含まれていれば、それをキーにMicrosoft Graphでグループ情報を取得する
- 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連携を長く安定させる近道です。

コメント