役割ベースの権限
項目一覧
Overview
受信するユーザーリクエストと Device Sync セッションに自動的に割り当てられるロールを定義することで、アプリのデータを保護します。各ロールには、詳細なデータアクセス権限と、ロールが適用されるタイミングを決定する動的条件があります。
Device Sync を使用した一般的なシナリオで権限を設定する方法の例については、Device Sync 権限ガイドを参照してください。
権限とは
権限とは、アプリのデータに対してできることとできないことを制御するため、Atlas App Services が個人ユーザーに割り当てるステータスです。App Services ではドキュメント レベルの権限とフィールド レベルの権限をどちらも使用します。
ドキュメント レベルの権限は、MongoDB コレクション内の特定のドキュメントにおける、ユーザーによる挿入、削除、変更、検索を制御します。
フィールド レベルの権限は、ドキュメントの特定フィールドにおける、ユーザーによるデータの読み取りや書込みを制御します。
ドキュメントレベルの権限
ロールのドキュメントレベルの権限によって、ドキュメント全体に影響するアクションを実行できるかどうかが決まります。これらの権限は、内容に関係なく常にドキュメント全体に適用されます。ロールは以下のドキュメントレベルの権限を持つことができます。
挿入:新しいドキュメントを挿入できます。
削除:既存のドキュメントを削除できます。
検索:Atlas Search を使用してドキュメントを検索できます。
フィールドレベルの権限
ロールのフィールドレベルの権限によって、ユーザーがドキュメント内のフィールドを読み書きできるかどうかが決まります。これらの権限は適用されるフィールドにのみ影響するため、ユーザーはドキュメント全体のサブセットに対してのみ、読み取りまたは書込みアクセス権限を持つことができます。
特定のフィールドにはフィールドレベルの権限を定義し、明示的に定義しない追加フィールドにはデフォルトの読み取り/書込み権限を定義できます。
読み取り権限フローチャート
次の図は、ユーザーが特定のドキュメントを読み取れるかどうかを App Services が判断する方法を示しています。
書込み権限フローチャート
次の図は、ユーザーが特定のドキュメントを書き込めるかどうかを App Services が判断する方法を示しています。
ロール
ロールとは、MongoDB コレクション内のドキュメントに対してユーザーが持つことのできる権限のセットの名称です。ロールには、アプリサービスがそのロールをユーザーに割り当てるかどうかを決定する「apply when」式があります。また、ロールが割り当てられたときにユーザーに与えられる一連のドキュメントレベルおよびフィールドレベルの権限もあります。
App Services は、ユーザーが割り当てられた役割に基づいて実行する権限を持つ操作のみにコミットします。ロールにドキュメントまたはそのフィールドの一部を読み取る権限がない場合、App Services はそのドキュメントまたはフィールドを結果から除外します。
例
employees
という名前のコレクションで、各従業員がすべての雇用データを含む独自のドキュメントを持っているとします。このコレクションには、従業員とマネージャーという 2 つのロールがある可能性があります。Device Sync を使用していないため、App Services はドキュメントごとにロールを選択します。
ユーザーが自分のドキュメントをリクエストした場合、そのロールは従業員となります。従業員は自分のデータを読み書きできますが、自分のドキュメントを作成したり削除したりすることはできません。
あるユーザーが、ユーザーの
manages
配列に名前が記載されている別のユーザーのドキュメントをリクエストした場合、そのユーザーのロールはマネージャーです。マネージャーは直属の部下のデータを読み書きでき、ドキュメントの作成や削除が可能です。ユーザーが特定のドキュメントの従業員でもマネージャーでもない場合、そのユーザーにはロールがないため、ドキュメントの読み取り、書き込み、検索はできません。
{ "name": "Manager", "apply_when": { "email": "%%user.custom_data.manages" }, "insert": true, "delete": true, "read": true, "write": true, "search": true, "fields": {}, "additional_fields": { "read": true, "write": true } } { "name": "Employee", "apply_when": { "email": "%%user.data.email" }, "insert": false, "delete": false, "read": true, "write": true, "search": true, "fields": {}, "additional_fields": { "read": true, "write": true } }
{ "_id": ObjectId(...), "employeeId": "0528", "name": "Phylis Lapin", "team": "sales", "email": "phylis.lapin@dundermifflin.com", "manages": [] } { "_id": ObjectId(...), "employeeId": "0713", "name": "Stanley Hudson", "team": "sales", "email": "stanley.hudson@dundermifflin.com", "manages": [] } { "_id": ObjectId(...), "employeeId": "0865", "name": "Andy Bernard", "team": "sales", "email": "andy.bernard@dundermifflin.com", "manages": [ "phylis.lapin@dundermifflin.com", "stanley.hudson@dundermifflin.com" ] }
App Services がロールを割り当てる方法
App Services では、Device Sync(フレキシブル モード)を使用しているかどうかによって、ロールの割り当て時間が異なります。
Device Sync を使用する場合、App Services は同期セッションの開始時に、同期するコレクションごとにロールを割り当てます。同期セッションとは、同期接続を開始してから閉じるまでの時間のことです。
Device Sync を使用しない場合、App Services はドキュメントごと、リクエストごとにロールを割り当てます。
Device Sync を使用するかどうかにかかわらず、コレクション固有のロールのセットと、その他の不特定のコレクションに適用されるデフォルトのロールを定義できます。ロールを割り当てるために、App Services は各ロールの「apply when」式を指定した順序で評価します。「apply when」式が true と評価したときに適用される最初のロールが割り当てられたロールになります。一致するロールがない場合、アクセスは拒否されます。
特定のリクエストまたは同期セッションで評価されるロールのセットは、ユーザーがアクセスしているコレクションによって異なります。コレクションにコレクション レベルのロールを定義した場合、コレクション レベルのロールが評価されます。それ以外の場合、データソースのデフォルト ロールがあれば、それらが評価対象になります。
コレクション レベルのロールが適用されない場合、App Services はデフォルト ロールに「フォールバック」しません。コレクション レベルのロールが定義されている場合、コレクション レベルのロールのみが評価されます。デフォルト ロールは、コレクション レベルのロールが定義されていない場合にのみ評価されます。
Device Sync を使用しない場合
Device Sync を使用しない場合、App Services はすべてのドキュメントにロールを動的に割り当てます。ユーザーには、受信クエリに一致するドキュメントごとに個別のロールが割り当てられます。ロールが割り当てられない場合もあります。
アプリはフィルターを評価して適用し、クエリを実行します。
例
次の要求により、App Services は、city
フィールドが "Chicago"
に設定されている restaurants
コレクション内のすべてのドキュメントに対してロールを評価します。
db.restaurants.updateMany( { "city": "Chicago" }, { "$set": { "city": "Chicago, IL" } } );
クエリによって返されるドキュメントごとに、アプリがロールの順序で可能なロールを評価し、該当する場合は最初のロールを割り当てます。「apply when」式が特定のドキュメントに対して実行され、true
と評価された場合、ロールがそのドキュメントに適用されます。
例
従業員は常に自分のチームに所属することになるため、各自のドキュメントには従業員ロールとチームメイトロールの両方が適用されます。しかし、使えるロールは 1 つのみのため、より明確な従業員ロールを使用する必要があります。
これを構成するには、コレクションのロール定義で チームメイト より前に 従業員 を指定します。
{ "database": "<Database Name>", "collection": "<Collection Name>", "roles": [ { "name": "Manager", ... }, { "name": "Employee", ... }, { "name": "Teammate", ... } ] }
Device Sync を使用する場合
Device Sync を使用する場合、App Services は同期されたコレクションごとに、各 Flexible Sync セッションの開始時にロールを割り当てます。ロールは、セッション中に各コレクションに適用されるアクセス許可を決定します。
App Services はコレクションごとに最大 1 つのロールを割り当てます。特定の同期されたコレクションにロールを指定しなかった場合、App Services は代わりにデフォルト ロールを使用します。コレクションにロールが適用されない場合、ユーザーはそのコレクション内のエントリの同期 (または読み取りまたは書込み)ができません。
セッション中、ロールは割り当てられたままの状態です。ユーザーのセッションの途中でユーザーのセッションロールに関連する変更があった場合、新しいセッションを開始するまで、そのユーザーには更新されたロールが割り当てられません。たとえば、ユーザーのメタデータまたはロールの「apply when」式が変更された場合、ユーザーは次回セッションを開始するまで、そのコレクションの既存のロールを使用し続けます。
Device Sync を使用する際には、権限システムに関する特別な考慮事項がいくつかあります。詳しくは、Device Sync 対応の権限を参照してください。
一般的な権限モデルを使用して Flexible Sync を設定するためのガイドについては、Device Sync 権限ガイドを参照してください。
Apply When 式
ロールの「apply when」式は、ロールを割り当てるかどうかを決定するルール式です。
式変数を使用して、ロールを動的にすることができます。たとえば、%%user
展開を使用して、リクエストを発行した特定のユーザーを参照できます。これにより、ユーザーごとにデータアクセス権限をカスタマイズできます。
Device Sync を使用していないときは、ロールが割り当てられている現在のドキュメントを参照できます。例として、%%root
を使用できます。これにより、ドキュメントごとにデータ アクセス権限をカスタマイズできます。
ドキュメント フィルター
ロールの document_filters
式によって、その後のロールのそドキュメントレベルおよびフィールドレベルの権限が評価されるかどうかが決まります。Device Sync ではこれが必須です。
注:App Services はドキュメントごとにドキュメント フィルターを評価します。これらをトップレベルのクエリフィルターと混同しないでください。
ロールの順序
与えられたコレクションの役割はそれぞれ、評価および適用される順序を決定する位置を持っています。式がロール順に評価されると、各ロールは、ロールが適用されるか、ロールがなくなるまで適用されます。
ユーザーが持つことができるロールは、指定されたクエリ内のドキュメントごとに 1 つだけです。イベント内において複数のロールの「apply when」式が true である場合、ロールの順序により適用されるロールが決まります。そのため、ロールを定義するときは、最も明確なロールを一番最初に置いてください。
同期の互換性
Device Sync(フレキシブルモード)が有効な場合、割り当てられたロールは同期に互換性がなければなりません。詳細については、同期互換ロールを参照してください。
ロールと権限を定義する
アプリのデータ アクセス ルールは、App Services UI から、または App Services CLI を使用して構成ファイルをデプロイすることで構成できます。
左側のナビゲーション メニューで Rulesをクリックし、データ ソースのコレクション リストからコレクションを選択します。Default roles and filtersを選択して、クラスター全体のデフォルト ルールを構成することもできます。
ロールがまだ定義されていない場合は、新しいロールを作成するように求められます。それ以外の場合は、既存のロールの順序付きリストが表示されます。
[Add role] をクリックして、新しいロールを定義します。事前設定されたロールを開始点として使用するか、[Skip (start from scratch)] をクリックします。
ロールに名前を付けます。名前は任意のものにすることができますが、特定のコレクション内では一意である必要があります。ユーザーやデータとの関係を説明する名前の使用を検討してください。たとえば、
Admin
やOwner
などです。"apply when" 式を定義し、指定されたユーザが指定されたドキュメントのロールをいつ持つかを決定します。
ロールのドキュメントレベルの権限を定義します。
ロールのドキュメント フィルターを定義します。これは Device Sync(フレキシブル モード)に必要です。
ドロップダウンを使用して、ロールの フィールドレベルの権限 を選択します。Specify field-level permissions 選択した場合は、権限を定義するフィールド名を入力します。
名前を付ける各フィールドと Additional Fields には、None、Read、Read & Write のいずれかを選択して権限を指定します。
ロールを保存します。
コレクションに複数のロールが割り当てられている場合は、各ロールの矢印をクリックしてロールの順序を変更できます。
アプリの最新バージョンを取得します。
appservices pull --remote="<Your App ID>" 1 つまたは複数のコレクションのロールとフィルターを定義します。また、未設定のコレクションに適用するデフォルト ロールとフィルターを定義することもできます。詳細については、ルール構成を参照してください。
/data_sources/<data source>/<database>/<collection>/rules.json{ "database": "<Database Name>", "collection": "<Collection Name>", "roles": [ { "name": "<Role Name>", "apply_when": {}, "document_filters": { "read": { <Expression> }, "write": { <Expression> } }, "insert": true, "delete": true, "search": true, "fields": { "myField": { "read": true, "write": true } }, "additional_fields": { "read": true, "write": true } } ], "filters": [ { "name": "<Filter Name>", "apply_when": {}, "query": {}, "projection": {} } ] } /data_sources/<data source>/default_rule.json{ "roles": [ { "name": "<Role Name>", "apply_when": {}, "document_filters": { "read": { <Expression> }, "write": { <Expression> } }, "insert": true, "delete": true, "search": true, "fields": { "myField": { "read": true, "write": true } }, "additional_fields": { "read": true, "write": true } } ], "filters": [ { "name": "<Filter Name>", "apply_when": {}, "query": {}, "projection": {} } ] } アプリをデプロイします。
appservices push
注意
App Services のロールベースの権限に関するセキュリティの考慮事項
ロールベースの権限とフィルターで、コレクション内の特定のドキュメントとフィールドを隠すことができますが、システムが任意のクエリによるコレクションへのアクセスを許可している場合、データが意図せず表示される可能性があります。
たとえば、コレクションに格納されている値に応じてエラー(ゼロ除算エラーなど)を発生させるクエリまたは関数は、ロールまたはフィルターによる制限でクエリ元のユーザーがドキュメントを直接表示できない場合でも、ドキュメントに関する情報を表示することがあります。ユーザーは、他の方法(データの分布に影響を受ける可能性のあるクエリの実行時間を測定するなど)で基礎となるデータについて推論することもできます。
この可能性を認識し、必要に応じてデータアクセス パターンを監査してください。