Lambda 能否承担具有认知 userId 条件的 IAM 角色?
Can Lambda assume an IAM role with a cognito userId condition?
我们有一个 dynamo table 用于我们应用程序的安全敏感部分,具有非常严格的读取访问限制(这里的目标是尽可能严格)。理想情况下,我们希望将对 table 的访问限制为仅具有匹配的 cognito-userId 前导键的行(遵循这种方法:https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_rows.html)。不幸的是,我们的要求是 lambda 函数需要代表用户读取值,以便随后处理并将值发送给用户(例如通过邮件)。
我们当前的设置如下所示:我们已经使用该前导键 IAM 条件创建了 IAM 规则,并将其附加到一个用户组,该用户组包括将访问该 table 的所有用户.到目前为止一切顺利,lambda 函数从上下文对象中获取规则并承担该角色(通过 sts:assumeRole,就像这样,它们都在同一个帐户中:https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pool-group/, https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/)
lambda 和承担的角色都有必要的策略,因此这也按预期工作。使用静态值进行测试,如下所示:
ForAllValues:StringEquals:
dynamodb:LeadingKeys:
- "SOMEKEY"
同时确认所有必需的凭据都已通过,角色正在承担,一切正常,直到这里。
不幸的是,当实际使用 ${cognito-identity.amazonaws.com:sub}
作为前导密钥标识符时,无论是否使用 aws-region 前缀,它都会停止工作。因此我的问题是,有没有人遇到过这个?这个变量什么时候被替换为 IAM 规则?它是在传递给 lambda 函数之前被解析(在这种情况下我们希望该值被填充)还是在 lambda 访问 dynamo 时被替换(在这种情况下它没有被解析,因为 lambda 而不是认知用户担任角色)?
有什么办法可以减轻这种情况吗?任何帮助将不胜感激
${cognito-identity.amazonaws.com:sub} 正在引用身份池中的 Cognito 身份 ID。因此,当您的应用程序使用身份池获取 AWS 临时凭证时,这些凭证将包含用户身份 ID。如果您的应用程序随后尝试从数据库中获取一行,则用户只能获取他们的行,即以其身份 ID 作为前导键的行。
因此,不用在 lambda 函数中承担 IAM 角色,而是使用 sts 承担角色,您可以将 Cognito ID 令牌传递给您的 Lambda,然后将 ID 令牌传递给身份池以获取凭证。然后,SDK 可以采用这些凭据,并且向 Dynamo 发出的请求将使用 ${cognito-identity.amazonaws.com:sub}.
关于此方法需要提及的一件事是,从身份池获得的凭据有效期为一个小时,因此我认为有必要实现一个缓存层以重用现有凭据,以避免在每次调用时从身份池请求新凭据.
希望对您有所帮助。
我们有一个 dynamo table 用于我们应用程序的安全敏感部分,具有非常严格的读取访问限制(这里的目标是尽可能严格)。理想情况下,我们希望将对 table 的访问限制为仅具有匹配的 cognito-userId 前导键的行(遵循这种方法:https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_rows.html)。不幸的是,我们的要求是 lambda 函数需要代表用户读取值,以便随后处理并将值发送给用户(例如通过邮件)。
我们当前的设置如下所示:我们已经使用该前导键 IAM 条件创建了 IAM 规则,并将其附加到一个用户组,该用户组包括将访问该 table 的所有用户.到目前为止一切顺利,lambda 函数从上下文对象中获取规则并承担该角色(通过 sts:assumeRole,就像这样,它们都在同一个帐户中:https://aws.amazon.com/premiumsupport/knowledge-center/cognito-user-pool-group/, https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-assume-iam-role/) lambda 和承担的角色都有必要的策略,因此这也按预期工作。使用静态值进行测试,如下所示:
ForAllValues:StringEquals:
dynamodb:LeadingKeys:
- "SOMEKEY"
同时确认所有必需的凭据都已通过,角色正在承担,一切正常,直到这里。
不幸的是,当实际使用 ${cognito-identity.amazonaws.com:sub}
作为前导密钥标识符时,无论是否使用 aws-region 前缀,它都会停止工作。因此我的问题是,有没有人遇到过这个?这个变量什么时候被替换为 IAM 规则?它是在传递给 lambda 函数之前被解析(在这种情况下我们希望该值被填充)还是在 lambda 访问 dynamo 时被替换(在这种情况下它没有被解析,因为 lambda 而不是认知用户担任角色)?
有什么办法可以减轻这种情况吗?任何帮助将不胜感激
${cognito-identity.amazonaws.com:sub} 正在引用身份池中的 Cognito 身份 ID。因此,当您的应用程序使用身份池获取 AWS 临时凭证时,这些凭证将包含用户身份 ID。如果您的应用程序随后尝试从数据库中获取一行,则用户只能获取他们的行,即以其身份 ID 作为前导键的行。
因此,不用在 lambda 函数中承担 IAM 角色,而是使用 sts 承担角色,您可以将 Cognito ID 令牌传递给您的 Lambda,然后将 ID 令牌传递给身份池以获取凭证。然后,SDK 可以采用这些凭据,并且向 Dynamo 发出的请求将使用 ${cognito-identity.amazonaws.com:sub}.
关于此方法需要提及的一件事是,从身份池获得的凭据有效期为一个小时,因此我认为有必要实现一个缓存层以重用现有凭据,以避免在每次调用时从身份池请求新凭据.
希望对您有所帮助。