Dataverse でレコードを共有する方法 (部署やアクセスチームなど)

# はじめに


Microsoft Dataverse でキャンバスアプリを共有する方法について、以下の記事で紹介しました。

https://qiita.com/Takashi_Masumori/items/6f0d9a094e40564736be

上記でも触れたように、Microsoft Dataverse では、セキュリティロールを利用して、テーブルに対して、特権 (例：作成、読み取り)、アクセスレベル `ユーザー`、`組織`) という仕組みでアクセス権を付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a58c15a6-9ee9-488c-4799-e3c96469fc75.png)

そして、例えば、自分が作成した行について、アプリを利用する人は誰でも読み取り可能ですが、変更や削除は自分 (アプリの管理者は除く) しかできないようにしたい場合、以下のような感じで設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/391cfc90-9eeb-b32c-a380-f9c42a4b7f40.png)

個人的に、アクセスレベルの`ユーザー`、`組織`を組み合わせることでアクセス制御に関する要件を満たせるケースも多くあると思いますが、今回は、それ以外の以下のような要件に関するアプローチ、考慮事項等について整理してみたいと思います。

* 同じ部署の人が作成したレコードは操作可能だが、異なる部署の人が作成したレコードは操作できないようにしたい

* 部署など関係なく、特定のユーザーに対して任意のタイミングでレコードを共有したい

# 同じ部署の人が作成したレコードは操作可能だが、異なる部署の人が作成したレコードは操作できないようにしたい

アプリ利用者が多い場合、自分が作成したレコード (`ユーザー`) or アプリ利用者が作成したレコードすべて (`組織`) というアクセスレベルでは要件を満たせない場合があると思います。

例えば、自部門の人が作成したデータは閲覧可能だが、他部門の人が作成したデータは閲覧できないようにしたいといった要件が考えられます。

このような要件がある場合、以下の、部署や部署配下のアクセスレベルを利用することが考えられます。こちらの部署について、もう少し深掘りしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/9464e76d-fb62-c52d-28fe-a89318d7dd12.png)

## 部署とは

英語では、Business units となっており、何らかの事業単位となります。こちらを利用することで、部署 (Business units) が同じ人が作成したレコードの場合、操作が可能、異なる場合は操作ができないといったことが実現可能です。

例えば、以下のようにアクセス権を設定していた場合の動作は以下のような動作になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/dc00ea54-419d-50ef-bdda-6393c33d592a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/1efb08dd-d797-39c9-e756-5d5db5cbdf89.png)

このようなアクセス権制御の要件を満たすことが可能ですが、実際に設計、運用をする際は色々考慮が必要になりますので、この点について深掘りしたいと思います。

## 部署のメンバーの割当、メンテナンスについて

まず、部署の作成は以下から可能で、環境単位で作成していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/39cc7142-b8cb-8e74-7bca-795f966d82fc.png)

メンバーの割当は、チームを介して行います。チームについては以下の情報を参考にしていただければと思います。

https://learn.microsoft.com/ja-jp/power-platform/admin/manage-teams

https://jpdynamicscrm.github.io/blog/powerplatform/About-group-team-in-Dataverse/

所有者チームの場合は手動でメンバーを割り当てる必要がありますが、Azure AD と紐づくチームの場合、メンバーのメンテナンスは Azure AD 側に委ねることになります。

元々 Azure AD のグループのメンバーは、組織改正があった際などにバッチ処理などでメンテナンスする運用となっている場合、Dataverse を利用するアプリ作成者がメンバーをメンテナンスする必要がなくなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ef583057-d46c-5388-3373-dbc61ab19caf.png)

そのため、こちらを利用すればやりたいことが楽に実現できるとお考えになる方も多いと思いますが、実際の運用を踏まえるともう少し考慮することがあります。

### ユーザーが所属する部署

まず、Dataverse の各レコードには、レコードの所有者が存在します。そして、当たり前かもしれませんが、既定では、そのレコードを作成したユーザーが所有者となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/5d28b0cf-4438-fd19-c0f2-dfd6244eb526.png)

そして、Dataverse の各環境のユーザーには、所属する部署を持ち、既定では、以下のように、組織のトップの階層の部署 (ルート部署) に所属することになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/0c29c044-7464-a9bf-505f-beb37d556ca2.png)

つまり、部署 A、部署 B を作成し、チームを介してこちらと紐づく Azure AD のグループと紐づけを行っただけの場合、以下のような動作になってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/020e27dd-da71-6b53-bf6e-58d0efd2fbb6.png)

こちらを踏まえると、以下のような対策が考えられますが、懸念点もございます。

* Datavese の各環境のユーザーが所属する部署を Power Automate 等で定期的にメンテナンスする
* レコードが作成された際、Power Automate を起動し、Azure AD のグループと紐づくチームをレコードの所有者にする

まず、前者のユーザーが所属する部署を定期的にメンテナンスする方法について、各ユーザーが紐づく部署情報 (Dataverse の環境における) を管理する必要があり、大規模な組織レベルでメンテナンスするのは現実的ではないかもしれません (アプリ作成者の負担が大きくなります) 。

後者について、実は以下のようにレコードの所有者をチームにすることができます。そのため、ユーザーがレコードを作成した際に、レコードの所有者をチームに変更することが出来れば、部署が同じ人が作成したレコードの場合、操作が可能、異なる場合は操作ができないといったことが実現可能です。

しかし、こちらの場合も、ユーザー A がレコードを作成したらチーム A (部署 A) をレコードの所有者に変更するといった管理情報が必要になり、大規模な組織レベルでメンテナンスするのは現実的ではないかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/4465af77-0cc6-343e-d3d4-b1c24a3de0a2.png)

### その他考慮事項

上記も踏まえつつですが、その他考慮事項について、以下の情報をベースに述べたいと思います。

https://learn.microsoft.com/ja-jp/training/modules/fast-track-security/2-security-workshop-topics

こちらのドキュメントにて、メンテナンス性やパフォーマンス等の観点から、部署 (Business units) の数を最小限に抑えることをお勧めする旨の記載があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/fa3c21d4-1789-45ae-fb44-9cdec7262fc5.png)

日本語では部署という名前になっていることから、組織の部署と紐付ける (Azure AD のグループをチームを介して紐付けて)、つまり、組織階層と完全に同じような部署 (Business units) 階層を作成してアクセス権を制御する運用をイメージされるかもしれませんが、上述の情報を踏まえ、どのような単位で部署 (Business units) を利用するかについて、慎重に検討する必要があると考えます。

個人的には、部署とチームの紐づけは基本的に変わらない、また、ユーザーの所属部署を変更するにせよ、レコードの所有者を変更するにせよ、メンテナンス可能な範囲で利用するといった感じでしょうか。

# 部署など関係なく、特定のユーザーに対してレコードを共有したい

例えば、何かのプロジェクト単位、担当しているお客様単位など、組織階層などとは関係なくレコードを共有したい場合もあると思います。

こちらについては、レコードの共有とアクセスチームという ２ つのアプローチが考えられます。

## レコードの共有

以下の箇所からレコードを他のユーザーに共有できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e6a599c3-4eb1-1db5-b344-0540fd5774a5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/8a20653e-ef16-edbe-2aa4-9a5b0d562213.png)

ただし、以下に記載がある通り、こちらの共有について、多数のユーザー間で多数のレコードを共有すると、パフォーマンス上懸念があるようです。

https://learn.microsoft.com/ja-jp/training/modules/fast-track-security/2-security-workshop-topics

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e25b4ed7-3f16-c42e-3d74-bcf23fde1f34.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/9dbad4f8-3e19-28b6-b26d-20528a18043e.png)

## アクセスチーム

セキュリティ ロールを割り当てることができず、レコードも所有しないチームです。上述の通り、プロジェクトチームなど、一時的にアクセス権を付与する際のアプローチの一つです。

https://learn.microsoft.com/ja-jp/dynamics365/customerengagement/on-premises/developer/use-access-teams-owner-teams-collaborate-share-information?view=op-9-1

https://learn.microsoft.com/ja-jp/power-platform/admin/create-team-template-add-entity-form

以下、実際のアクセスチームの使用例です。以下のようにしてユーザーを追加することで追加されたユーザーはレコードへのアクセスが可能になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/319e0697-b328-c7d8-780b-46dc62524ffc.png)

設定方法について、まず、チームのテンプレートを作成します。その際、付与したいアクセス権を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/d5cd9bf4-cc00-b5ca-a509-2d4007724913.png)

アクセスチームを利用したいテーブルにて、アクセスチームを有効にします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/c9883344-5349-c985-0d31-5964757ea47d.png)

そして、テーブルのビューにサブグリッドを追加し、ユーザーテーブルを選択して、作成したチームテンプレートを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/3611b461-13aa-b70e-ab1f-9e75874ec535.png)

その結果、アクセスチームでユーザーを追加すると、そのレコードに対して、テンプレートで設定したアクセス権が付与されることになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/f22cdf1d-bbb8-35f2-9d7c-ca3cf00ee793.png)

動作確認してみます。まず、以下の状態で testuser002 がレコードを参照しようとすると、アクセス権がない旨のエラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/08378b9f-2f73-24b9-d291-627a57c5bbd3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/5fd2d6eb-e1d7-0d6d-7130-736cdd247f6d.png)

testuser002 を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e706c2c0-06c1-a1cb-5cfd-44dcea8408b4.png)

testuser002 の方でレコードを参照できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/6a6d50f8-02c1-f4ce-f5e1-7d96f2805b75.png)

上述のセキュリティ ワークショップのトピックでも、レコードの共有よりはアクセスチームの方が推奨されているように見受けられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/973ad8b0-9409-ad8a-84fe-c2836feefdf9.png)

なお、例えば、レコードが追加された際にアクセス権を自動で追加したいといった要件がある場合、まず、レコードが作成された際に Power Automate が自動起動するようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a41b4d1a-e1d5-0381-edba-dec507032a57.png)

その上で、ユーザーテーブルに対して以下のアクションを実行します。

* 行 ID は、ユーザーテーブルにおいて、アクセス権を追加したいユーザーの一意な識別子 (GUID) です
* Record はアクセス権を追加したいレコードの GUID です。今回は、取引先企業 (accounts) のテーブルを利用しているため、トリガーとなったレコードの一意な識別子 (GUID) を選択します 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b3ef28ab-905b-072a-96fa-ca87e7b71753.png)

* teamtemplate teamtemplateid は予め作成しておいたチームテンプレートの主キーを入れます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/192daa8a-ab81-d729-c052-92778494d0cc.png)

動かしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/2f6f8d71-bf95-428b-2f6e-98b78537378d.png)

新規作成したレコードについて、アクセスチームに testuser004 が自動で追加されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/335763d0-ac21-72ee-9bf3-4d4435925b32.png)

:::note
今回は、決め打ちで testuser004 をアクセスチームに追加しましたが、アクセスチームに追加したいユーザー (アクセス権を付与したいユーザー) の情報を控えておき、ユーザーテーブルのユーザーの一意な識別子 (GUID) をベースにアクセスチームに追加する感じになると思います
:::

# まとめ

今回は、Microsoft Dataverse のレコードを共有する方法について、主に、部署やアクセスチームについて深掘りしてみました。レコードのアクセス制御について、細かい要件がある場合、これらの機能がソリューションになる可能性がありますが、少なからず考慮事項などもあるため、この辺も踏まえつつ設計計、運用の参考にしていただけると幸いです。