Dataverseで階層アクセス制御(BU単位でのデータスコープ設定)を設計すると、セキュリティロールの行数が数万〜十万に膨らむことがある。
管理できないと感じた場合、数え方が違っている可能性が高い。実際に管理すべきは行数ではなく、定義の数——より正確には RoleTemplate(ロール定義の実体エンティティ)の数だ。
BU(Business Unit:ビジネスユニット、組織単位)がいくつ増えても、RoleTemplate は一セットだけ存在する。行数が膨らんでも、管理対象の定義数は環境規模にかかわらず百数十件の範囲に収まる。


なぜ行数が「BU数×定義数」に膨らむのか

Dataverse のセキュリティロール(特定のテーブルへの操作権限をまとめた権限グループ)は、BU ごとに個別の行として発行される仕組みになっている。BU が 10 あり、ロール定義が 20 あれば、行数は 200 になる。BU が数十〜数百規模の組織では、行数が数万を超えることも珍しくない。

Microsoft の公式ドキュメント(Security roles and privileges、2024 年更新)には次のように明示されている。

“A security role can exist in the root business unit (BU) and replicated to different BU’s, and therefore the role ID is not unique across environments.”

Dataverse は内部で Role エンティティ(行として BU ごとに複製される側)と RoleTemplate エンティティ(ロール定義の実体)を分離して設計している。この二層構造が行数の爆発を生む一方で、管理の複雑さを大幅に抑えてもいる。


複製された行が「空の殻」とはどういう意味か

複製された Role 行が格納しているのは次の 3 点だけだ。

格納情報内容
roleIdこの行固有の識別子(BU ごとに異なる GUID)
BusinessUnitIdこの行がどの BU に属するかの参照
roleTemplateIdどの RoleTemplate を参照するか(全環境・全 BU で固定の GUID)

権限の中身——どのテーブルへの読み書き・削除が可能か、という情報——は Role 行に存在しない。それは参照先の RoleTemplate が保持する。

この設計は公式ドキュメントで次のように表現されている。

“you should use RoleTemplateId when you try to lookup or process Microsoft Dataverse security roles, as these role template IDs are unique and constant in all environments.”

Security roles and privileges

roleId は BU ごとに異なるため環境をまたいで使えない。roleTemplateId は全環境・全 BU で不変だ。この非対称が「Role 行は識別のための殻、定義の実体は RoleTemplate」という設計構造を示している。

行数が多く見えるのは、殻が BU の数だけ並んでいるからだ。管理対象は複製 Row の数ではなく、その中身(RoleTemplate)の数になる。


定義を変えると「伝播」でなく「同時に」全員に効く

「テンプレートを 1 箇所変えたら全 BU に反映されるか」という問いへの答えは「そうだ、伝播ではなく同時に」だ。

Role 行は RoleTemplate を「参照」しているため、RoleTemplate の変更は、それを参照するすべての BU のすべての Role 行に即時反映される。コピーを並べているのではなく実体を共有しているため、BU 数が増えても同期コストは発生しない。

ただし留意点がある。反映の速度を保証する公式数値はない。「同時に」はアーキテクチャとしての設計帰結であり、実際の反映タイミングを保証する SLA は公開されていない。


本当に管理すべき数——定義数(RoleTemplate)を正しく数え直す

Dataverse の基盤ロールテンプレート(システム定義のため削除不可)の規模感は次の通りだ。

環境タイプ基盤ロールテンプレートの目安
Dataverse 単体(非 Dynamics 365)約 20 件(Basic User / System Administrator / Environment Maker 等)
Dynamics 365 標準セット17 件(SystemAdmin / Customizer / BasicUser 等)
Dynamics 365 アプリ追加インストール時100 件以上になり得る

出典:MicrosoftDocs/powerapps-docs – security-roles.md(2024 年)

インストール済みのアプリ構成によって総数は大きく変動する。「百数十件・うちカスタム十数件」はPoC環境固有の参考値であり、他環境への直接適用はできない。ただし「基盤ロールが大半を占め、削除できるカスタムロールは少数」という傾向は、多くの環境で共通する。

削減効果について正直に言うと、削除できるのはカスタムロールだけで基盤ロールは削除不可だ。カスタムが十数件なら削減の余地はもとから限られる。そして「行数を縮める」こと自体に管理コスト削減の直接効果はない——問題は行数の大きさではなく、定義数を正確に把握できていなかったことだったのだから。


ただし走査(全件読み出し)コストは行数に比例して残る

管理は軽いが、走査は重い。この非対称は設計時に意識する必要がある。

セキュリティロールを全件取得する API コールやスクリプトを実行すると、行数に比例した走査コストが発生する。Microsoft のクエリ最適化指針(Query anti-patterns、2024 年)では全件取得は非推奨とされており、データベースに不均衡な負荷をかけるクエリはスロットリング(Throttling:クエリの実行制限)される場合があると明記されている。

走査時間の具体的な数値は公式ドキュメントに記載がない。行数が多い環境ほどスロットリングのリスクが上がる、という一般原則として理解するのが適切だ。

実際の対処は一つに集約される。ロールを操作するスクリプト・Power Automate フロー・Web API コールでは、roleId(BU ごとに変わる値)ではなく roleTemplateId(全環境で不変の値)を軸にフィルタリングする。目的のロール定義を直接参照できるため、全件走査を回避できる。


設計・運用時に確認する 4 点

場面判断の軸
ロール行数が増えて管理不安管理対象は定義数(RoleTemplate 数)。行数はカウントしない
テンプレートを変更したいRoleTemplate を 1 件変更すれば全 BU に即時反映。BU ごとの個別変更は不要
ロールを棚卸したいroleTemplateId を軸に一覧化する。roleId は環境ごとに変わるため棚卸の軸には使えない
全件走査スクリプトが重いroleTemplateId でフィルタリングして件数を絞る。全件取得は避ける

この構造を実際に確認したい場合、M365 Developer Program の無料テナントに Dataverse 環境を作り、Role エンティティと RoleTemplate エンティティを別々にクエリしてみると二層構造の実体を目視で把握できる。

→ BU 設計全体の判断軸(owner と owningBU の 2 軸がどう動くか)は、関連記事「DataverseのownerとowningBU——所有権2軸の設計論」で整理している。


まとめ

Dataverse のセキュリティロールは BU 数 × 定義数で行が膨らむが、複製された行は識別情報と参照情報だけで権限の実体を持たない。管理対象は行数ではなく定義数(RoleTemplate)であり、roleTemplateId を軸に設計・操作することが正確な数え方の出発点になる。


次の一歩:PowerShell または Dataverse Web API で RoleTemplate エンティティを取得し、自環境の定義数を確認する。/api/data/v9.2/roletemplates に対してシンプルな GET を投げると、基盤ロールと識別するための ismanaged フィールドを含めた一覧が返る(2026 年時点の仕様)。定義数を把握した上で、roleTemplateId をキーにしたロール操作スクリプトを 1 本作ると、棚卸と変更管理の両方に使い回せる。


関連記事