AWS CDK - 无法在 Lambda 中承担细粒度授权的角色

M U*_*M U 2 amazon-web-services amazon-iam serverless aws-serverless aws-cdk

我对 AWS 的具体情况相当陌生,所以请原谅我提出一个愚蠢的问题。我一直在寻找答案,但没有找到任何可以回答我的问题的问题。

我正在构建一个项目,并尝试使用此 AWS 教程正确获得权限:https://aws.amazon.com/blogs/apn/partitioning-pooled-multi-tenant-saas-data-with-amazon-动态数据库/

我创建了角色和策略:

const tenantUserRole = new Role(this, "TenantUserRole", {
      assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
    });
table.grantReadWriteData(tenantUserRole);
Run Code Online (Sandbox Code Playgroud)

然后,在我的 Lambda 中,我尝试:

const role = await stsClient.send(
    new AssumeRoleCommand({
      Policy: getPolicy("tenant"),
      RoleArn: process.env.TENANT_ROLE_ARN,
      RoleSessionName: "foo",
    })
  );
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我在 Lambda 中收到错误:

{ "errorType": "AccessDenied", "errorMessage": "用户:arn:aws:sts::xxx:assumed-role/ProjectStack-createUserServiceRoleB9D8AADE-GRDI6MWXA5MY/ProjectStack-createUserC6ED88E6-K0S95UXTN9MH 无权执行: sts:AssumeRole on资源:arn:aws:iam::xxx:role/ProjectStack-TenantUserRoleB79B8D3A-11N644X7UF0SR","trace":["AccessDenied:用户:arn:aws:sts::xxx:assumed-role/ProjectStack-createUserServiceRoleB9D8AADE-GRDI6MWXA5MY/ProjectStack -createUserC6ED88E6-K0S95UXTN9MH 无权对资源执行:sts:AssumeRole:arn:aws:iam::xxx:role/ProjectStack-TenantUserRoleB79B8D3A-11N644X7UF0SR",

目标是始终根据用户上下文解析权限,那么我应该在 CDK 堆栈中做什么才能使我的所有 Lambda 能够执行必须执行的操作?

sam*_*ler 9

正如 @Maurice 所描述的,应该信任角色而不是服务主体(lambda.amazonaws.com)。\n下面是 CDK 代码。

\n

TenantUserRole被信任apiRole正在被使用aws lambda

\n
import * as cdk from \'@aws-cdk/core\';\nimport * as iam from \'@aws-cdk/aws-iam\';\n\nexport class CdkWorkshopStack extends cdk.Stack {\n  constructor(scope: cdk.App, id: string, props?: cdk.StackProps) {\n    super(scope, id, props);\n    // aws lambda role\n    const lambdaRole = new iam.Role(this, \'apiRole\', {\n      roleName: \'apiRole\',\n      assumedBy:  new iam.ServicePrincipal(\'lambda.amazonaws.com\'),\n    });\n    // trusted by TenantUserRole for access\n    const tenantUserRole = new iam.Role(this, \'TenantUserRole\', {\n      roleName: \'TenantUserRole\',\n      assumedBy: new iam.ArnPrincipal(lambdaRole.roleArn),\n    });\n\n    // policy to allow assume role TenantUserRole\n    lambdaRole.addToPolicy(\n      new iam.PolicyStatement({\n        resources: [tenantUserRole.roleArn],\n        actions: [\'sts:AssumeRole\'],\n      })\n    );\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这里它看起来像角色的信任策略。

\n
\xe2\x9d\xaf\xe2\x9d\xaf aws  iam get-role --role-name TenantUserRole\n{\n    "Role": {\n        "Path": "/",\n        "RoleName": "TenantUserRole",\n        "RoleId": "AROA2WXKNDTKKGFADASD",\n        "Arn": "arn:aws:iam::1234567890:role/TenantUserRole",\n        "CreateDate": "2021-03-03T23:34:13+00:00",\n        "AssumeRolePolicyDocument": {\n            "Version": "2012-10-17",\n            "Statement": [\n                {\n                    "Effect": "Allow",\n                    "Principal": {\n                        "AWS": "arn:aws:iam::1234567890:role/apiRole"\n                    },\n                    "Action": "sts:AssumeRole"\n                }\n            ]\n        },\n        "Description": "",\n        "MaxSessionDuration": 3600,\n        "RoleLastUsed": {}\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

允许 aws lambda 角色代入的策略TenantUserRole

\n
\xe2\x9d\xaf\xe2\x9d\xaf aws iam get-role-policy  --role-name apiRole  --policy-name apiRoleDefaultPolicy771DC0DD\n{\n    "RoleName": "apiRole",\n    "PolicyName": "apiRoleDefaultPolicy771DC0DD",\n    "PolicyDocument": {\n        "Version": "2012-10-17",\n        "Statement": [\n            {\n                "Action": "sts:AssumeRole",\n                "Resource": "arn:aws:iam::1234567890:role/TenantUserRole",\n                "Effect": "Allow"\n            }\n        ]\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如何将信任策略与 IAM 角色结合使用\n

\n

在 lambda 中,您需要在假设TenantUserRole需要使用这些凭据并创建dynamodb客户端之后使用该客户端进行 api 调用putItem

\n
import boto3\n\ndef lambda_handler(event, context):\n    sts = boto3.client(\'sts\')\n    // assume TenantUserRole\n    creds = sts.assume_role(\n        RoleArn=\'arn:aws:iam::1234567890:role/TenantUserRole\',\n        RoleSessionName="tempsession"\n        )\n    // Use Credentials from the assume call to make dynamodb client\n    tenant_user_dyanmodb_client = boto3.client(\n    \'dynamodb\',\n    aws_access_key_id=creds.get(\'Credentials\').get(\'AccessKeyId\'),\n    aws_secret_access_key=creds.get(\'Credentials\').get(\'SecretAccessKey\'),\n    aws_session_token=creds.get(\'Credentials\').get(\'SessionToken\')\n    )\n\n   // call put item\n    tenant_user_dyanmodb_client.put_item(TableName=\'fruitSalad\', Item={\'fruitName\':{\'S\':\'Banana\'},\'key2\':{\'N\':\'value2\'}})\n\n
Run Code Online (Sandbox Code Playgroud)\n