У меня есть роль, которую я могу взять на себя, и к этой роли прикреплены две политики. Моя цель - разрешить доступ только к MyTable
, а затем ко всем атрибутам, за исключением price
(исключено из политики):
access-specific-table.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListAndDescribe",
"Effect": "Allow",
"Action": [
"dynamodb:List*",
"dynamodb:DescribeReservedCapacity*",
"dynamodb:DescribeLimits",
"dynamodb:DescribeTimeToLive"
],
"Resource": "*"
},
{
"Sid": "LimitAccessToSpecificTable",
"Effect": "Allow",
"Action": [
"dynamodb:BatchGet*",
"dynamodb:DescribeStream",
"dynamodb:DescribeTable",
"dynamodb:Get*",
"dynamodb:Query",
"dynamodb:Scan",
"dynamodb:BatchWrite*",
"dynamodb:CreateTable",
"dynamodb:Delete*",
"dynamodb:Update*",
"dynamodb:PutItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/MyTable"
}
]
}
access-specific-attributes.json
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "LimitAccessToSpecificAttributes",
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:Query",
"dynamodb:BatchGetItem",
"dynamodb:Scan"
],
"Resource": [
"arn:aws:dynamodb:us-east-1:123456789012:table/MyTable"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:Attributes": [
"type",
"id",
"album_art",
"artist_id",
"format",
"name_title",
"sku",
"year"
]
},
"StringEqualsIfExists": {
"dynamodb:Select": "SPECIFIC_ATTRIBUTES"
}
}
}]
}
Я проверяю следующим образом:
#!/usr/bin/env python3
import decimal
import json
import boto3
from botocore.exceptions import ClientError
# Helper class to convert a DynamoDB item to JSON.
class DecimalEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, decimal.Decimal):
if o % 1 > 0:
return float(o)
else:
return int(o)
return super(DecimalEncoder, self).default(o)
sts = boto3.client("sts")
print("Default Provider Identity: : " + sts.get_caller_identity()["Arn"])
role_to_assume_arn = "arn:aws:iam::123456789012:role/LimitedDynamoDBRole"
role_session_name = "test_session"
response = sts.assume_role(
RoleArn=role_to_assume_arn, RoleSessionName=role_session_name
)
creds = response["Credentials"]
sts_assumed_role = boto3.client(
"sts",
aws_access_key_id=creds["AccessKeyId"],
aws_secret_access_key=creds["SecretAccessKey"],
aws_session_token=creds["SessionToken"],
)
print("AssumedRole Identity: " + sts_assumed_role.get_caller_identity()["Arn"])
# Create boto3 session with assumed role
session = boto3.Session(
aws_access_key_id=creds["AccessKeyId"],
aws_secret_access_key=creds["SecretAccessKey"],
aws_session_token=creds["SessionToken"],
)
# Attempt scanning "user" table, which is *not* allowed by policy
try:
dynamodb = session.resource("dynamodb")
table = dynamodb.Table("user")
response = table.scan()
except ClientError as e:
print("Error: %s" % e)
# Attempt GetItem on "MyTable" table, which does *not* allow
# the "price" attribute
try:
dynamodb = session.resource("dynamodb")
table = dynamodb.Table("pinehead_records_s3")
response = table.get_item(Key={"type": "album", "id": 15})
print(json.dumps(response["Item"], cls=DecimalEncoder, indent=4))
except ClientError as e:
print("Error: %s" % e)
Я предполагаю, что атрибут "цена" будет скрыт, поскольку он отсутствует в разделе "dynamodb:Attributes"
политики.
Однако, когда я делаю get_item
, этот атрибут явно возвращается:
{
"name_title": "Album title",
"artist_id": 20211,
"year": 1995,
"price": 4.91,
"id": 15,
"album_art": "/albumart/5/1/15.jpg",
"format": "7\" Vinyl",
"sku": "20211-15",
"type": "album"
}
Что я делаю не так?