Amazon Web Services ブログ

Amazon DocumentDB 向けのロールベースのアクセス制御 (MongoDB 互換) のご紹介

Amazon DocumentDB (MongoDB 互換) は、MongoDB 3.6 ワークロードをサポートする高速でスケーラブル、かつ可用性に優れた完全マネージドのドキュメントデータベースサービスです。お客様は、基盤となるインフラストラクチャを気にすることなく、現在ご使用のものと同じ MongoDB 向けのアプリケーションコード、ドライバー、ツールを、そのまま Amazon DocumentDB 上で実行や管理をしたり、処理負荷を調整したりするのに使えます。

Amazon DocumentDB にロールベースのアクセス制御 (RBAC) のサポートが追加されました。RBAC では、1 つ以上の事前定義されたロール (たとえば、readreadWrite、または dbOwner) をユーザーに付与できます。これにより、1 つ以上のデータベースで実行を許可されている操作が決まります。RBAC の一般的な使用例は、単一のアプリケーション内で最小権限アクセスを実施することです。もう 1 つの一般的な使用例は、マルチテナントアプリケーションを構築することです。マルチテナントアプリケーションでは、複数の顧客にサービスを提供するソフトウェアとハードウェアをデプロイします。Amazon DocumentDB のコンテキストでは、マルチテナントアプリケーションの例に、各顧客 (またはテナント) がクラスター内のデータベースにアクセスする場合が挙げられます。

この記事では、Amazon DocumentDB の RBAC の概念と機能を紹介し、2 つのユースケースを取り上げ、RBAC を使用してマルチテナントアプリケーションを構築する際の設計上の考慮事項について説明します。新しい RBAC 機能の詳細については、ドキュメントの「ロールベースのアクセス制御 (組み込みロール)」を参照してください。

概念

Amazon DocumentDB は、以下の RBAC の主要な概念を用いています。

  • ユーザー – 認証して操作を実行できる名前付きエンティティ
  • パスワード – ユーザーを認証する秘密の言葉
  • ロール – ユーザーが 1 つ以上のデータベースでアクションを実行できることの指定
  • 管理者データベース – ユーザーを承認する特別なデータベース
  • データベース (DB) – コレクションを含むクラスター内の名前空間

次のコードにより、データベース foo にパスワード abc123read 権限を持つ app という名前のユーザーが作成されます (この記事で使われている名前とパスワードは例示目的で挙げているに過ぎません。常に強力なパスワードを選択してください)。

db.createUser({user: "app", pwd: "abc123", roles: [{role: "read", db: "foo"}]})

show users コマンドを使用して、クラスター内の既存のユーザーとロールを一覧表示できます。次のコードは、作成されたユーザーに対するこのコマンドの出力を示しています。

 {
	"_id" : "app",
	"user" : "app",
	"db" : "admin",
	"roles" : [
		{
			"db" : "foo",
			"role" : "read"
		}
	]
}

すべてのロール情報は、admin という名前の特別なデータベースに保存されます。このコード例では、ユーザー appadmin データベースに存在し、foo データベースで read ロールを持っていることがわかります。

RBAC のユースケース

RBAC がどのように機能するかを示すために、この記事では、RBAC の 2 つの最も一般的なユースケースを紹介します。1つは単一のアプリケーション内で最小権限アクセスを強制するケースと、もう 1 つは単一の Amazon DocumentDB クラスターでマルチテナントアプリケーションを有効にするケースです。

最小権限の強制

多くの場合、アプリケーションは単一の Amazon DocumentDB クラスターをデータストアとして使用しますが、特定の操作を実行するには承認が必要な複数のユーザーがいます。データの読み取りと書き込みが必要なユーザーもいれば、読み取りアクセスのみが必要なユーザーもいます。最小権限の原則は、基本的なセキュリティツールです。RBAC を使用して、ユーザーアクセスを機能の実行に必要なものだけに制限することにより、この原則を適用できます。この記事では、3 人のアプリケーションユーザー (appAdminappUseranalytics) のユースケースをご紹介します。各ユーザーは、実行する必要がある機能に基づいて異なるロールを持っています。次の図は、そのロールをまとめたものです。

最初のユーザー (appAdmin) はアプリケーション管理者で、インデックスを作成し、ユーザーを追加し、任意のデータベースでデータを読み書きする必要があります。このユーザーには、ロール dbAdminAnyDatabasereadWriteAnyDatabaseclusterAdmin を割り当てます。appAdmin のユーザーを作成し、必要なロールを付与するには、次のコードを入力します (これらのユーザーを作成するには、root ロールを持つユーザーとしてクラスターに認証する必要があります)。

db.createUser( { user: "appAdmin", pwd: "abc123",  roles: [{"db":"admin", "role":"dbAdminAnyDatabase" }, {"db":"admin", "role":"readWriteAnyDatabase"}, {"db":"admin", "role":"clusterAdmin"}]})

2 番目のユーザー (appUser) はメインアプリケーションユーザーで、製品データベースに読み取りと書き込みを行う必要があります。appUser ユーザーを作成して必要なロールを付与するには、次のコードを入力します。

db.createUser( { user: "appUser", pwd: "abc124",  roles: [ { role: "readWrite", db: "products"}]})

3 番目のユーザー (analytics) は、products データベースからデータを読み取るだけでよい分析アプリケーション向けです。analytics ユーザーを作成して必要なロールを付与するには、次のコードを入力します。

db.createUser( { user: "analytics", pwd: "abc125",  roles: [ { role: "read", db: "products"}]})

次の CLI コマンドを使用して、appUser としてクラスターに接続および認証できます。

mongo "mongodb://appUser:abc124@<clusterName>.us-east-1.docdb.amazonaws.com:27017/"

接続文字列で特定のデータベースを指定しない場合、デフォルトで test データベースに対してユーザーを認証します。アプリケーションデータは製品データベースにあるため、use ステートメントを発行して、接続のコンテキストを製品データベースに切り替えることができます。次のコードを参照してください。

製品を使用する

これで、製品カタログを読み書きできるようになりました。ドキュメントをカタログコレクションに挿入するには、次のコードを入力します。

db.catalog.insertMany([
{ "_id":1, "name":"banana", "inventory": 10},
{ "_id":2, "name":"passion fruit", "inventory": 22},
{ "_id":3, "name":"pink laddy apple", "inventory": 78},
])

次の出力が表示されます。

{ "acknowledged" : true, "insertedIds" : [ 1, 2, 3 ] }

これで、データをクエリして特定の種類の果物を見つけることができます。たとえば、パッションフルーツの現在の在庫を確認する場合は、次のコードを入力します。

db.catalog.find({"name": "passion fruit"})

次の出力が表示されます。

{ "_id" : 2, "name" : "passion fruit", "inventory" : 22 }

次に、appUser からログアウトします。次のコードを参照してください。

db.logout()

次の出力が表示されます。

{ "ok" : 1 }

logout コマンドを発行した後も、Amazon DocumentDB クラスターに接続していますが、どのユーザーとしても認証されていません。これで、製品データベースの読み取り権限のみを持つ analytics ユーザーとして認証できます。次のコードを参照してください。

db.auth("analytics", "abc125")

読み取り専用のロールで認証されているため、データを読み取ることができます。次のコードを参照してください。

db.catalog.find({"name": "passion fruit"})

次の出力が表示されます。

{ "_id" : 2, "name" : "passion fruit", "inventory" : 22 }

ただし、データの書き込みは許可されていません。たとえば、次のコードは新しいデータを挿入しようとしています。

db.catalog.insert({"name": "lemons", "quantity": 99})

次の出力が表示されます。

WriteResult({ "writeError" : { "code" : 13, "errmsg" : "Authorization failure" } })

マルチテナントアプリケーション

この 2 番目のユースケースでは、ゲーム開発アプリケーションをサポートするデータベースがあります。コストを最適化するため、各ゲーム開発者がクラスター内の独自のデータベースにアクセスできるマルチテナントクラスターを使用します。4 つのゲームスタジオが自社のゲームプラットフォームにサインアップしました。その 4 つとは、bigCowraceCarxQuest、および bounce です。これらの顧客にデータへのアクセス権を与えるには、4 人のデータベース管理者ユーザーを作成します (顧客ごとに 1 人)。各管理者ユーザーは、自分のゲーム用に自分のデータベースを管理できます。次の図は、ユーザーのロールをまとめたものです。

DocumentDB クラスター全体の管理者ロールを持つユーザーでログインした後、各ゲーム DB の管理者ユーザーを作成し、クラスター内の特定のデータベースに適切なロールをスコープできます。次のコードを参照してください。

db.createUser( { user: "bigCowAdmin", pwd: "abc123",  roles: [ { role: "dbOwner", db: "bigCow"}]})
db.createUser( { user: "raceCarAdmin", pwd: "def456",  roles: [ { role: "dbOwner", db: "raceCar"}]})
db.createUser( { user: "xQuestAdmin", pwd: "ghi789",  roles: [ { role: "dbOwner", db: "xQuest"}]})
db.createUser( { user: "bounceAdmin", pwd: "jkl012",  roles: [ { role: "dbOwner", db: "bounce"}]})

各管理者ユーザーは各自のデータベースを認証および管理できますが、クラスター内の他のデータベースでアクションを実行することは許可されていません。たとえば、bigCowAdmin ユーザーは、xQuest データベースの読み取りまたは書き込みを行うことができません。

アクセス権のないデータベースに bigCow ユーザーが書き込もうとしていることを示すには、現在のユーザーとしてログアウトします。次のコードを参照してください。

db.logout()

次の出力が表示されます。

{ "ok" : 1 }

次の mongo シェルコマンドを使用して、bigCowAdmin としてクラスターに接続および認証できます。

mongo "mongodb://bigCowAdmin:abc123@&lt;clusterName&gt;.us-east-1.docdb.amazonaws.com:27017/"

次に、接続のコンテキストを xQuest データベースに切り替えます。次のコードを参照してください。

use xQuest

次の出力が表示されます。

switched to db xQuest

データベース xQuestfoo コレクションに単一のドキュメントを書き込むことができます。次のコードを参照してください。

db.foo.insert({'x':1})

次の出力が表示されます。

WriteResult({ "writeError" : { "code" : 13, "errmsg" : "Authorization failure" } })

予想どおり、bigCowAdmin ユーザーはそのコマンドの実行を許可されていません。

接続が xQuest データベースのコンテキストにある場合でも、ユーザーがデータベースがクラスター内に存在することを確認できるわけではありません。接続のコンテキストはクライアント側の構造であり、接続のコンテキストを任意のデータベースに切り替えることが可能です。けれどもそれは、データベースが存在すること、またはデータベースからの読み取りまたは書き込みへのアクセス権限があることを意味しません。たとえば、次のコードは、xQuest データベースのコレクションを一覧表示しようとします。

db.runCommand( { listCollections: 1})

次の出力が表示されます。

{ "ok" : 0, "errmsg" : "Authorization failure", "code" : 13 }

xQuestAdmin ユーザーには、コレクションを一覧表示することを許可するロールがないため、このコマンドを実行すると認証に失敗します。ただし、接続のコンテキストを、bigCowAdmin ユーザーが権限を持つ bigCow データベースに切り替えると、bigCow データベースでコマンドを実行することが許可されます。次のコードを参照してください。

use bigCow

次の出力が表示されます。

switched to db bigCow

これで認証され、データベース bigCowfoo コレクションに書き込むことができます。次のコードを参照してください。

db.foo.insert({'x':1})

次の出力が表示されます。

WriteResult({ "nInserted" : 1 })

同様に、bigCowAdmin ユーザーにはロール dbOwner があるため、bigCow データベースにコレクションを一覧表示できます。次のコードを参照してください。

db.runCommand( { listCollections: 1})

次の出力が表示されます。

{
	"waitedMS" : NumberLong(0),
	"cursor" : {
		"firstBatch" : [
			{
				"name" : "foo",
				"type" : "collection",
				"options" : {
					"autoIndexId" : true,
					"capped" : false
				},
				"info" : {
					"readOnly" : false
				},
				"idIndex" : {
					"v" : 2,
					"key" : {
						"_id" : 1
					},
					"name" : "_id_",
					"ns" : "bigCow.foo"
				}
			}
		],
		"id" : NumberLong(0),
		"ns" : "bigCow.$cmd.listCollections"
	},
	"ok" : 1
}

マルチテナント設計の考慮事項

SaaS (Software as a Service) アプリケーションを構築する開発者は、コストを最適化するためにマルチテナントアプリケーションを構築することに関心を持っていることがよくあります。SaaS 開発者は通常、共有コンピューティングリソースとストレージリソースに対して RBAC などの認証セキュリティ制御を行うことを通じてテナント (または顧客) を分離します。Amazon DocumentDB では、クラスターごとまたはデータベースごとに (RBAC を使用して) テナントを分離することにより、SaaS アプリケーションを構築できます。このセクションでは、クラスターとデータベースの両レベルでの分離の設計上の考慮事項とトレードオフについて説明し、アプリケーションアーキテクチャに最も適したパターンを評価するのに役立てます。マルチテナントデータ分離を実現するための高レベルなアプローチの詳細については、「AWS でマルチテナントストレージモデルを構築する SaaS ストレージ戦略」ホワイトペーパーを参照してください。

クラスターの分離

クラスターの分離モデルでは、データをテナントごとに単一の Amazon DocumentDB クラスターに論理的に分離します。各テナントには個別の専用クラスターがあるため、コンピューティング、ストレージ、バックアップ、暗号化キー、発生したコストなど、すべてのディメンションにわたって完全なテナント分離を実現します。

データベースの分離

データベース分離モデルでは、各テナントは、承認メカニズム (RBAC など) を通じて共有環境で分離されます。Amazon DocumentDB クラスター内では、各テナントを Amazon DocumentDB クラスター内の 1 つ以上の個別のデータベースに関連付けることにより、データベースレベルの分離を実現します。

コストの最適化

データベース分離を使用してマルチテナントアプリケーションを構築する利点と主要な動機の 1 つは、密度によってコストを最適化する機能です。アプリケーションと顧客の保証によっては、すべてのテナントが同時にアクティブであるとは限らないことがわかっているため、単一のクラスター上のテナントの数をオーバーサブスクライブすることができます。この密度により、テナントあたりのコストを削減できるため、ソリューション全体のコスト効率が向上します。

パフォーマンスの分離

マルチテナントアプリケーションアーキテクチャを選択する場合、パフォーマンスの分離は重要な考慮事項です。クラスターの分離を用いる場合、各テナントには専用のクラスターがあり、その結果専用のコンピューティングリソースがあります。これにより、そのテナントの要件に基づいて、一貫して保証されたサービス品質が実現します。たとえば、あるテナントが r5.large インスタンスのクラスターで開始したところ、アプリケーションのスループットが 2 倍になる場合、そのクラスターの r5.xlarge インスタンスをスケーリングして、そのテナントに 2 倍のコンピューティングリソースを効果的に与えることができます。

データベースの分離により、テナントは Amazon DocumentDB クラスター内のコンピューティングリソースを共有します。このアプローチの利点は、単一クラスターで最大数百のテナントという高密度のテナントを実現できることです。テナントの総使用率が時間の経過とともに比較的均一である場合、テナント全体で比較的一貫したエクスペリエンスを提供できます。データベースの分離の欠点は、1 人以上のテナントがクラスター内のリソース量を過度に使用すると、他のテナントのサービス品質に悪影響を及ぼす可能性があることです (よく騒々しい隣人問題と呼ばれます)。データベースの分離モデルを選択するときは、騒々しい隣人リスクを認識して説明し、テナントに適切な期待を抱かせることが大切です。

一般的な緩和戦略の 1 つは、サービス内に階層化を導入することです。基本層では、各テナントが共有クラスター上のデータベースにアクセスできます (したがって、騒々しい隣人リスクにさらされます)。パフォーマンスの分離が必要なテナントには、各テナントが独自のクラスターを持つ上位階層を提供できます。

セキュリティの分離

マルチテナントアプローチを選択する際のもう 1 つの考慮事項に、セキュリティの分離があります。Amazon DocumentDB の保存時の暗号化機能 (デフォルトで有効) は、単一の顧客マスターキー (CMK) を使用して、クラスター内のストレージボリューム、バックアップ、スナップショットを暗号化します。ストレージ暗号化キーを他のテナントと共有してはならないテナントがいる場合は、 (別の CMK を使用する) クラスターの分離を使用するか、またはアプリケーションでクライアント側の暗号化を実行し、AWS KMS を介してクライアント側でそれらのキーを管理します。クライアント側の暗号化は、共有クラスター環境でキーの分離を実現できますが、複雑さが増し、アプリケーションのパフォーマンスに潜在的に影響を与える可能性があります。

まとめ

この記事では、Amazon DocumentDB 向けの RBAC を紹介し、2 つの一般的なユースケースをご紹介し、マルチテナントアプリケーションを構築するための設計上の考慮事項について説明しました。Amazon DocumentDB の RBAC の詳細については、ドキュメントの「ロールベースのアクセス制御 (組み込みロール)」を参照してください。

Amazon DocumentDB の詳細については、「Amazon DocumentDB の開始方法」を参照するか、YouTube で「Getting Started with Amazon DocumentDB」の動画をご覧ください。詳細については、「Amazon DocumentDB の強化 (MongoDB 互換)」を参照してください。現在 MongoDB で使用しているものと同じアプリケーションコード、ドライバー、およびツールを使って、Amazon DocumentDB での開発を開始できます。

AWS SaaS Factory について

AWS SaaS Factory は、AWS パートナーネットワーク (APN) パートナーに、SaaS デリバリーモデルの採用を促進および誘導するのに役立つリソースを提供しています。SaaS Factory には、AWS で SaaS ソリューションを構築するためのリファレンスアーキテクチャ、AWS での主要なワークロードのデプロイを自動化するクイックスタート、AWS で SaaS ビジネスを構築するための特別なトレーニングの機会などが用意されています。SaaS ソリューションを開発する APN テクノロジーパートナーは、是非プログラムにご参加ください!

AWS SaaS Factory の詳細 >>

 


著者について

 

Joseph Idziorek は、アマゾン ウェブ サービスのプリンシパルプロダクトマネージャーです。

 

 

 

 

Judah Bernstein は、SaaS (Software-as-a-Service) を専門とするアマゾン ウェブ サービスのシニアパートナーソリューションアーキテクトです。

 

 

 

 

Jeff Duffy は、アマゾン ウェブ サービスのシニア NoSQL スペシャリストソリューションアーキテクトです。