我正在开发一个需要访问DynamoDB表的服务,该表必须通过授权用户访问该表来管理。账户管理由Cognito负责。我目前正在调查对DynamoDB表的直接访问,该表的读/写访问受限于具有相关IAM策略的用户组。
表中存在多个组织,并且多个用户绑定到一个组织。下面是该模型的一个示例。我还以多对一的关系存储部门和部门信息。
用户的Cognito Sub作为用户id存储在USR#下的数据库中。
+-------+-------+-----------------+------------+--------+
| PK | SK | Name | GSI1PK | GSI2PK |
+-------+-------+-----------------+------------+--------+
| ORG#1 | ORG#1 | Acme Inc | | |
| ORG#1 | USR#1 | John Doe | | |
| ORG#2 | ORG#2 | Globetex | | |
| ORG#2 | USR#2 | Jane Doe | | |
| ORG#1 | SEC#1 | Sector A1 | ORG#1SEC#1 | SEC#1 |
| DEP#1 | DEP#1 | Human Resources | ORG#1SEC#1 | DEP#1 |
+-------+-------+-----------------+------------+--------+
到目前为止,我可以在特定IAM政策中以硬编码的方式限制对每个组织的访问。但是,这是不可扩展的。如果要有一百个组织,一百个用户组也必须有一个单独的策略。此政策的示例如下。
是否有任何方法可以创建一个IAM策略,该策略使用自定义Cognito变量,例如"组织",允许我创建一个仅限制访问该组织的行的单一策略?我无法使用以下代码来完成此操作。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query"
],
"Resource": [
"arn:aws:dynamodb:region:id:table/TableName"
],
"Condition": {
"ForAllValues:StringEquals": {
"dynamodb:LeadingKeys": [
"${cognito-identity.amazonaws.com:org}"
]
}
}
}
]
}
编辑:为了清楚起见,我的查询是在验证时将自定义Cognito变量动态插入IAM策略。
例如,用户A将custom:org.Acme作为Cognito属性,用户B将custom:org/Globex作为其自定义Cognito特性。
上面代码中详细介绍的单个策略可以将此属性直接插入到策略中,因此一个策略可以用于不同组织中的多个用户。
经过进一步的研究,我不确定这是可能的,但如果有人有任何经验尝试这样的东西,我很乐意听到
我认为你已经接近了,根据这篇文章,它应该是StringLike
而不是StringEquals
"Condition": {
"ForAllValues:StringLike": {
"dynamodb:LeadingKeys": [
"{TENANTID}-*"
]
}
可能还想阅读多租户SaaS存储策略白皮书
编辑我认为静态策略不可能随心所欲。
然而,链接文章中的代码确实提供了";管理来自任何租户的用户的访问";。
关键点是role/AccessDynamoWithTenantContext
的使用
tenantPolicy = getPolicy(event['tenantID'])
assumed_role = sts_client.assume_role(
RoleArn="arn:aws:iam::<account-id>:role/AccessDynamoWithTenantContext",
RoleSessionName="tenant-aware-product",
Policy=tenantPolicy,
)
以及tenentId在getPolicy()
中的动态注入
policy = json.dumps(policyTemplate).replace("{TENANTID}", tenantID)
return policy