![[アップデート] Amazon DynamoDBがリソースベースポリシーをサポートしました](https://devio2023-media.developers.io/wp-content/uploads/2023/08/amazon-dynamodb.png)
[アップデート] Amazon DynamoDBがリソースベースポリシーをサポートしました
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
別アカウントからのアクセス許可を簡単に行いたい
こんにちは、のんピ(@non____97)です。
皆さんはDynamoDBに対して別アカウントからのアクセス許可を簡単に行いたいなと思ったことはありますか? 私はあります。
従来、別アカウントから自アカウントのDynamoDBにアクセス許可をするためには、自アカウント内のIAMロールにAssume Roleさせてから操作をする必要がありました。手元でAWS CLIで操作する場合はプロファイルを指定するだけなので訳ないですが、Step FunctionsのステートマシンやLambda関数で別アカウントのDynamoDBを操作する際は、都度Assume Roleする必要があり非常に手間です。
Step Functionsでタスク毎にAssume Roleする方法は以下記事をご覧ください。
今回、アップデートによりAmazon DynamoDBでリソースベースポリシーが使えるようになりました。
AWS Blogsにも投稿されていますね。
これにより、他アカウントのユーザーにAssume Roleを依頼することなく、直接操作を依頼することが可能になりました。イメージは先述のAWS Blogの図が分かりやすいです。
リソースベースポリシーがない場合

リソースベースポリシーがある場合

また、リソースベースポリシーを使うことで、データストア側で操作できる権限を絞ることができるのもありがたいポイントですね。IAMポリシーで適当に全DynamoDBに許可するようなIAMポリシーをアタッチされても、特定のテーブルには特定のユーザーしかアクセスさせたくないケースもあります。
実際に試してみました。
いきなりまとめ
- DynamoDBのリソースベースポリシーは以下に対してアクセス許可を設定可能
- テーブル
- インデックス
- ストリーム
- API毎にリソースベースポリシーで設定可否がある
- リソースベースポリシーはIAM Access Analyzerとも連携可能
- 意図しないアクセス許可に気づきやすい
- リソースベースポリシーを設定する際は検証用のDynamoDBテーブルで評価しよう
- 設定に誤りがあると、rootユーザーでしか操作できなくなる可能性がある
DeleteResourcePolicyの許可があるのであれば、リソースベースポリシーを剥がしてアクセスすることが可能
- 主な注意事項
- リソースベースポリシードキュメントの最大サイズは20KB
- 対象リソースに対するポリシーの更新に成功した場合、対象リソースへのポリシーの更新は15秒間行えない
- 古いDynamoDBグローバルテーブルのレプリカでは設定できない
- リソースベースポリシーによってDynamoDBのサービスリンクロールがグローバルテーブルのデータをレプリケートするアクションが拒否された場合、レプリカの追加または削除はエラーで失敗する
- AWSマネージドキーのキーポリシーは変更できないため、AWSマネージドキーを使用している場合はクロスアカウントアクセスを許可してもアクセスできない
DynamoDBのリソースベースポリシーとは
概要
DynamoDB自身にアタッチするポリシーです。テーブルポリシーとも言うようです。
DynamoDBのリソースベースポリシーの詳細は以下AWS公式ドキュメントにまとまっています。
「そもそもリソースベースポリシーとは?」という方は以下記事をご覧ください。
DynamoDBのリソースベースポリシーはテーブルだけでなく、インデックス、ストリームにも設定することが可能です。具体的にリソースベースポリシーで設定可能なAPIは以下のとおりです。ExportTableToPointInTimeなどクロスアカウントでサポートされていないAPIもあるので注意しましょう。
Data Plane - Tables/indexes
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DeleteItem | Yes | Yes |
| GetItem | Yes | Yes |
| PutItem | Yes | Yes |
| Query | Yes | Yes |
| Scan | Yes | Yes |
| UpdateItem | Yes | Yes |
| TransactGetItems | Yes | Yes |
| TransactWriteItems | Yes | Yes |
| BatchGetItem | Yes | Yes |
| BatchWriteItem | Yes | Yes |
PartiQL
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| BatchExecuteStatement | Yes | No |
| ExecuteStatement | Yes | No |
| ExecuteTransaction | Yes | No |
Control Plane - Tables
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| CreateTable | No | No |
| DeleteTable | Yes | Yes |
| DescribeTable | Yes | Yes |
| UpdateTable | Yes | Yes |
Version 2019.11.21 (Current) global tables
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeTableReplicaAutoScaling | Yes | No |
| UpdateTableReplicaAutoScaling | Yes | No |
Version 2017.11.29 (Legacy) global table
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| CreateGlobalTable | No | No |
| DescribeGlobalTable | No | No |
| DescribeGlobalTableSettings | No | No |
| ListGlobalTables | No | No |
| UpdateGlobalTable | No | No |
| UpdateGlobalTableSettings | No | No |
Tags
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| ListTagsOfResource | Yes | Yes |
| TagResource | Yes | Yes |
| UntagResource | Yes | Yes |
Backup/Restore
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| CreateBackup | Yes | No |
| DescribeBackup | No | No |
| DeleteBackup | No | No |
| RestoreTableFromBackup | No | No |
Continuous Backup/Restore (PITR)
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeContinuousBackups | Yes | No |
| RestoreTableToPointInTime | Yes | No |
| UpdateContinuousBackups | Yes | No |
Contributor Insights
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeContributorInsights | Yes | No |
| ListContributorInsights | No | No |
| UpdateContributorInsights | Yes | No |
Export
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeExport | No | No |
| ExportTableToPointInTime | Yes | No |
| ListExports | No | No |
Import
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeImport | No | No |
| ImportTable | No | No |
| ListImports | No | No |
Kinesis
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeKinesisStreamingDestination | Yes | No |
| DisableKinesisStreamingDestination | Yes | No |
| EnableKinesisStreamingDestination | Yes | No |
| UpdateKinesisStreamingDestination | Yes | No |
Resource policies
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| GetResourcePolicy | Yes | No |
| PutResourcePolicy | Yes | No |
| DeleteResourcePolicy | Yes | No |
Time-to-Live
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeTimeToLive | Yes | No |
| UpdateTimeToLive | Yes | No |
DynamoDB Streams
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeStream | Yes | Yes |
| GetRecords | Yes | Yes |
| GetShardIterator | Yes | Yes |
| ListStreams | No | No |
Others
| API action | Resource-based policy support | Cross-account support |
|---|---|---|
| DescribeLimits | No | No |
| DescribeEndpoints | No | No |
| ListBackups | No | No |
| ListTables | No | No |
抜粋 : IAM actions supported by resource-based policies - Amazon DynamoDB
リソースベースポリシーはIAM Access Analyzerとも連携可能です。これにより、別アカウントへの意図しないアクセス許可に気づきやすくなります。IAM Access Analyzerの説明は以下記事をご覧ください。
DynamoDBのリソースベースポリシーでできること
DynamoDBのリソースベースポリシーでできることの一例は以下のとおりです。
- テーブルに対して特定のユーザーにのみ権限を付与する
- 特定ユーザー以外は拒否することも可能
- テーブルの特定のパーティションキーや属性のみに対するクエリ操作のみ許可する
- 指定した送信元IPアドレスやVPCエンドポイント経由以外からはアクセス拒否する
具体的なポリシーは以下AWS公式ドキュメントに記載があります。
DynamoDB固有の条件キーを使うことで細やかなアクセス制御を行うことが可能です。条件キーの詳細は以下AWS公式ドキュメントをご覧ください。
ちなみに、「拒否する」という設定を入れる場合は非常に注意が必要です。設定に誤りがあると、rootユーザーでしか操作できなくなる可能性があります。検証用のDynamoDBテーブルで評価した上で設定しましょう。CloudFormationで設定する場合は以下記事で紹介しているとおり、Condition句で明示的にCloudFormation経由での実行を許可してあげると良いでしょう。こうすることで何かあった場合でもCloudFormation経由で操作することが可能です。
注意事項
主な注意事項は以下のとおりです。
- リソースベースポリシードキュメントの最大サイズは20KB
- 対象リソースに対するポリシーの更新に成功した場合、対象リソースへのポリシーの更新は15秒間行えない
- 古いDynamoDBグローバルテーブルのレプリカでは設定できない
- リソースベースポリシーによってDynamoDBのサービスリンクロールがグローバルテーブルのデータをレプリケートするアクションが拒否された場合、レプリカの追加または削除はエラーで失敗する
- AWSマネージドキーのキーポリシーは変更できないため、AWSマネージドキーを使用している場合はクロスアカウントアクセスを許可してもアクセスできない
S3のようにアクセスポイントはないので、Condtion句が複雑だったり、対象のステートメントを記述している場合は20KBに到達はしやすいかと思います。
詳細は以下AWS公式ドキュメントをご覧ください。
やってみた
クロスアカウントアクセスの許可
実際に試してみます。
まずはクロスアカウントアクセスを許可を試します。
デフォルトではDynamoDBテーブルはリソースベースポリシーは設定されていません。

この状態で別アカウントからDynamoDBテーブルの情報を参照してみます。
$ aws dynamodb describe-table \
--table-name arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer
An error occurred (AccessDeniedException) when calling the DescribeTable operation: User: arn:aws:sts::<別AWSアカウントID>:assumed-role/<IAMロール名>/<セッション名> is not authorized to perform: dynamodb:DescribeTable on resource: arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer because no resource-based policy allows the dynamodb:DescribeTable action
はい、拒否されました。
それでは、別アカウントのIAMロールのセッションのアクセスを許可します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:sts::<別AWSアカウントID>:assumed-role/<IAMロール名>/<セッション名>"
},
"Action": "dynamodb:DescribeTable",
"Resource": "arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer"
}
]
}
許可したいアクションの一覧やプリンシパル、条件などもマネジメントコンソールからポチポチできます。

外部アクセスをプレビューをクリックすると、IAM Access Analyzerを使って、どんな許可が行われるのか分析してくれます。

リソースベースポリシーを更新すると、以下のようになります。IAM Access Analyzerの検出内容も表示してくれるので親切です。

アクセス許可後、再度別アカウントから同じ操作をしてみます。
$ aws dynamodb describe-table \
--table-name arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "ArchiveRuleName",
"AttributeType": "S"
}
],
"TableName": "analyzer",
"KeySchema": [
{
"AttributeName": "ArchiveRuleName",
"KeyType": "HASH"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2023-03-14T03:02:01.840000+00:00",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 0,
"WriteCapacityUnits": 0
},
"TableSizeBytes": 1211,
"ItemCount": 4,
"TableArn": "arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer",
"TableId": "cd86261d-5b37-46ee-abc3-ec6cd62fae3f",
"BillingModeSummary": {
"BillingMode": "PAY_PER_REQUEST",
"LastUpdateToPayPerRequestDateTime": "2023-03-14T03:02:01.840000+00:00"
},
"TableClassSummary": {
"TableClass": "STANDARD"
},
"DeletionProtectionEnabled": false
}
}
拒否されずに取得できました。これは簡単です。
ちなみにリソースベースポリシーを短時間で更新するとResource-based policy for table analyzer modified within the previous 15000 milliseconds. Please try again after 2024-03-23T06-59-15.747Zと怒られました。15秒間隔を空けましょう。

特定のIAMロールからのアクセス以外は拒否
続いて、特定のIAMロールからのアクセス以外は拒否するようにしてみます。
特定のIAMロールからのアクセス以外は拒否する場合、以下記事で紹介しているとおりaws:userIdを使います。
実際には以下のように行います。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "dynamodb:*",
"Resource": "arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer",
"Condition": {
"StringNotLike": {
"aws:userId": "AROXXXXXXXXXXXX:*"
}
}
}
]
}
こちらのポリシーを設定後、許可しているIAMロール以外からアクセスをすると以下のようにアクセスできませんでした。

もちろん、許可しているIAMロールを使用している場合はアクセスできました。ただし、IAM Access Analyzerで使用しているIAMロールは許可されていないのでアクセスレベルがエラーとなっていますね。

もし、設定を間違えて誰もアクセスできなくなった場合はrootユーザーでリソースベースポリシーを変更しましょう。
また、DeleteResourcePolicyの許可があるのであれば、以下のようにリソースベースポリシーを剥がしてあげることで対処することが可能です。
$ aws dynamodb delete-resource-policy \
--resource-arn arn:aws:dynamodb:us-east-1:<AWSアカウントID>:table/analyzer
{
"RevisionId": "1711178503038"
}
クロスアカウントアクセスやリソース側で権限をさらに絞りたい場合に
Amazon DynamoDBでリソースベースポリシーが使えるようになったアップデートを紹介しました。
クロスアカウントアクセスやリソース側で権限をさらに絞りたい場合に非常に有用ですね。十分に検証した上で積極的に使っていきたいです。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!






