この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
いろんなデータベースやAPIと接続してWebアプリをサクッと作れるRetoolですが、DynamoDBと連携する場合は、IAMユーザのアクセスキーを使います。 もし、アクセスキーが流出したら一大事です。 そこで、AssumeRoleを使って、少しでも影響が小さくなる方法を試してみました。
Retoolについては、下記をご覧ください。
おすすめの方
- RetoolでAssumeRoleしたい方
IAMユーザとIAMロールと実験用のDynamoDBテーブルを作成する
CloudFormationテンプレート
下記を作成します。
- Retool用のIAMユーザ
- Retool用のIAMユーザに付与するIAMポリシー(AssumeRoleのみ可能)
- Retool用のIAMユーザがAssumeRoleするIAMロール(DynamoDBに対する操作権限のみ)
- DynamoDBテーブル
AssumeRoleを活用すると、「Retool用のIAMユーザ」のアクセスキーが流出しても、AssumeRoleしかできません。 また、AssumeRoleする条件として「RetoolのIPアドレスのみ許可」しています。 そのため、第三者がアクセスキーを使っても、Retool以外はAssumeRoleできず、結果としてDynamoDBにアクセスできません。
aws.yaml
AWSTemplateFormatVersion: 2010-09-09
Description: IAM and DynamoDB for Retool
Resources:
# Retool用のIAMユーザ
RetoolUser:
Type: AWS::IAM::User
Properties:
UserName: retool-user
# Retool用のIAMユーザに付与するIAMポリシー(AssumeRoleのみ可能)
# -> もし、アクセスキーが流出しても、AssumeRoleしかできない
RetoolUserPoricy:
Type: AWS::IAM::Policy
Properties:
PolicyName: retool-user-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "sts:AssumeRole"
Resource: !GetAtt RetoolRole.Arn
Users:
- !Ref RetoolUser
# Retool用のIAMユーザがAssumeRoleするIAMロール(DynamoDBに対する操作権限のみ)
RetoolRole:
Type: AWS::IAM::Role
Properties:
RoleName: retool-user-role
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action: "sts:AssumeRole"
Principal:
AWS:
- !GetAtt RetoolUser.Arn
Condition:
IpAddress:
aws:SourceIp:
# Retoolからのアクセスのみ、AssumeRoleできる
# IP Addresss -> https://docs.retool.com/docs/connecting-your-database
- 13.80.4.170/32
- 13.93.15.89/32
- 13.93.15.84/32
- 13.76.231.249/32
- 13.76.97.52/32
- 13.76.194.227/32
- 52.177.12.28/32
- 52.177.12.26/32
- 52.177.118.220/32
- 52.175.194.171/32
- 52.175.251.223/32
- 52.247.195.225/32
Policies:
- PolicyName: retool-user-role-policy
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: "Allow"
Action:
- "dynamodb:ListTables"
Resource: "*"
- Effect: "Allow"
Action:
- "dynamodb:DeleteItem"
- "dynamodb:ListTagsOfResource"
- "dynamodb:DescribeReservedCapacityOfferings"
- "dynamodb:DescribeTable"
- "dynamodb:GetItem"
- "dynamodb:DescribeContinuousBackups"
- "dynamodb:DescribeLimits"
- "dynamodb:BatchGetItem"
- "dynamodb:BatchWriteItem"
- "dynamodb:PutItem"
- "dynamodb:ListBackups"
- "dynamodb:Scan"
- "dynamodb:Query"
- "dynamodb:DescribeStream"
- "dynamodb:UpdateItem"
- "dynamodb:DescribeTimeToLive"
- "dynamodb:ListStreams"
- "dynamodb:DescribeGlobalTableSettings"
- "dynamodb:ListGlobalTables"
- "dynamodb:GetShardIterator"
- "dynamodb:DescribeGlobalTable"
- "dynamodb:DescribeReservedCapacity"
- "dynamodb:DescribeBackup"
- "dynamodb:GetRecords"
Resource: !GetAtt RetoolDeviceTable.Arn
MaxSessionDuration: 3600
# DynamoDBテーブル
RetoolDeviceTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: retool-device-table
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: deviceId
AttributeType: S
KeySchema:
- AttributeName: deviceId
KeyType: HASH
Outputs:
RetoolRoleArn:
Value: !GetAtt RetoolRole.Arn
Retoolで操作するDynamoDBテーブルが決まっている場合、dynamodb:ListTables
以外は、Resource
にDynamoDBテーブルのARNを指定するとさらに安全になります。
デプロイ
aws cloudformation deploy \
--template-file aws.yaml \
--stack-name IAM-and-Retool-Sample-Stack \
--capabilities CAPABILITY_NAMED_IAM
アクセスキー取得
aws iam create-access-key \
--user-name retool-user
IAMロールのARNを取得
aws cloudformation describe-stacks \
--stack-name IAM-and-Retool-Sample-Stack \
--query 'Stacks[].Outputs'
手元のPCで、AssumeRoleできないことを確認する
AsssumeRoleの条件に「RetoolのIPアドレス」を指定しているので、手元のPCからAssumeRoleできないことを確認します。
アクセスキーを環境変数に登録する
さきほど取得したアクセスキーを環境変数に設定します。
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=yyy
export AWS_DEFAULT_REGION=ap-northeast-1
この状態だと、DynamoDBテーブルにアクセスできない
Retool用のIAMユーザには、AssumeRoleする権限のみを付与しているため、DynamoDBテーブルにアクセスできません。
$ aws dynamodb list-tables
An error occurred (AccessDeniedException) when calling the ListTables operation: User: arn:aws:iam::000000000000:user/retool-user is not authorized to perform: dynamodb:ListTables on resource: arn:aws:dynamodb:ap-northeast-1:000000000000:table/*
AssumeRoleもできない
さきほど取得した「AssumeRole用のARN」を指定します。許可されていないIPアドレスなので、AssumeRoleできません。
$ aws sts assume-role \
--role-arn arn:aws:iam::000000000000:role/retool-user-role \
--role-session-name local-test \
--duration-seconds 900
An error occurred (AccessDenied) when calling the AssumeRole operation: User: arn:aws:iam::000000000000:user/retool-user is not authorized to perform: sts:AssumeRole on resource: arn:aws:iam::000000000000:role/retool-user-role
Retoolのリソースを作成する
必要事項を入力して、DynamoDBに対するリソースを作成します。
「Role to assume (ARN)」が未入力の場合、「Test Connection」が失敗します。
「Role to assume (ARN)」を入力すると、接続成功しました。
Retoolでデータ取得を確認する
適当なデータをDynamoDBテーブルに格納する
RetoolのアプリでDynamoDBテーブルのデータを確認する
以前に作成したアプリを流用します。
TableのResource
とTable
をさきほど作成したリソースとDynamoDBテーブルに変更します。
Method
はscan
を指定します。
「Save & Run」を選択すると、無事にデータ取得できました!
異なるDynamoDBテーブルには、アクセスできない
アクセスを許可していないDynamoDBテーブルの中身は、表示できません。期待通りですね。
さいごに
少し手間かもしれませんが、安全性が格段に向上します。 精神衛生上も気が楽になりますので、おすすめです。