DynamoDB细粒度访问与Cognito



我正在开发一个需要访问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

相关内容

  • 没有找到相关文章

最新更新