IAM 角色限制 sts:AssumeRole 到一个 AWS Lambda 函数

IAM Role limit sts:AssumeRole to one AWS Lambda function

我担心安全问题。 IAM 角色的创建存在很高的安全风险,而且您只能将 AWS Lambda 指定为可以担任角色的角色这一事实在 IMO 方面还不够好。如果不小心处理,可能会出现特权升级。

如何创建特定于某些 Lambda 函数的 IAM 角色?

我还没有发现任何类似的东西,但我相信这是可能的。

此角色还会附加一些策略:

{
  "Action": "sts:AssumeRole",
  "Principal": {
    "Service": "lambda.amazonaws.com"
  },
  "Effect": "Allow",
  "Sid": ""
}

通常,在其他角色中,您会使用 Principal 子句来决定哪些帐户可以担任该角色。

{
 "Effect": "Allow",
 "Principal": {
   "AWS": "arn:aws:iam::123456789:root"
 },
 "Action": "sts:AssumeRole"
}

根据@Michael 在评论中的说法,我必须说哪些用户可以对哪些角色使用传递角色,因此问题是,我如何确定哪些用户可以传递这个角色?

如果是这样,这个问题的答案将分两步解决。使此角色只能由 Lambda 服务担任(因为它已经是),然后为每个用户制定一个具有 PassRole 限制的策略。

我不认为你能做到这一点。如果您认为需要在创建时将 IAM 角色分配给 AWS::Lambda::Function,则此 IAM 角色需要先于 Lambda 函数存在。但是,要将 AWS::IAM::Role 上的假设限制为单个 Lambda 函数,该函数需要首先存在 - 您不能同时满足这两个条件。

我假设您在此处使用 CloudFormation 创建基础设施。也许有一些方法可以通过在 AWS 控制台中手动创建您的基础设施来实现这一点,但即使这是可能的,为了跨环境/区域的可复制性,这本身也不是最佳实践。

您的安全问题可以通过以下组合来缓解:

  • AWS CloudFormation 漂移检测。
  • 将 CloudFormation 和 IAM 访问限制为一组受限的开发人员(例如团队领导)。
  • 正如@milan 建议的那样,在不同的帐户中保留不同的环境。

唯一的其他选择(对您没有帮助)是将一个 IAM 角色的承担限制为另一个角色的委托人 - 例如:

{
  "Action": "sts:AssumeRole",
  "Principal": {
    "AWS": { "Fn::Sub": "arn:aws:iam::${AWS::AccountId}:role/role-name"}
  },
  "Effect": "Allow"
}

此解决方案只是将问题隐藏了一层 - 您将 sts:AssumeRole 限制在包含您的权限的角色上,但您仍然可以跨不同的 lambda 代入此父角色。

(我知道我又回到了一个老问题,但我一直在研究类似的东西,在从 S3 加载加密对象时将 KMS 密钥资源限制为特定的 Lambda。)

如前所述,您可以为每个环境设置不同的帐户,并控制有权访问生产环境的人员。

让我们深入探讨您的问题:

  1. 如何创建特定于某些 Lambda 函数的 IAM 角色? 您可以定义限制为 Lambda 服务的委托人 and/or 添加条件使用针对特定 lambda 的键 lambda:FunctionArn。缺点是 lambda 必须在角色之前存在,因为您需要它的 arn.

  2. 我如何确定哪些用户可以传递这个角色? 创建不同的组并选择哪些组可以访问:CreateRoleAttach*Policy。为 CreatePolicy 的开发人员提供自由,但要求针对资源 arn(同样, 条件 )的策略或将 IAM 完全限制为仅负责访问控制和访问控制的一组用户用户管理.

我就此询问了 AWS 支持。他们说他们目前*不支持 assume_role/trust 政策中的条件来限制哪些函数可以通过匹配函数名称模式来承担角色。

相反,他们建议向执行策略添加条件(而不是 assume/trust 策略):

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "WhitelistSpecificLambdaFunction",
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringNotLike": {
                    "aws:userid": "AROAUISMSUAFHSJDJURKJ:TestLambda"
                }
            }
        }
    ]
}

-- This policy denies access to all Lambda functions except the specific Lambda function whose name is mentioned in "aws:userid" condition key. Other Lambda functions will be able to assume the role, but they will be denied from performing any action but if they are just printing or returning any variables/data the function would work.

--> NOTE: The condition key "aws:userid" specifies the unique ID for the current role and the corresponding value of this key has the following format: "role-id:role-session-name".

-- IAM role ID is "AROAUISMSUAFHSJDJURKJ" for the sample role I used.

-- In case of Lambda function the role-session-name is same as Lambda function name. In this example case it is "TestLambda", so aws:userid becomes "aws:userid": "AROAUISMSUAFHSJDJURKJ:TestLambda"

* 他们将我的名字添加到添加此功能的现有请求中

为了扩展 Steamer25 提供的答案,确认您仍然不能在 IAM 角色的代入角色信任策略中使用条件,而必须使用附加到的相关 IAM 策略文档中的条件IAM 角色。

经过对其他全局条件键的多次测试,aws:userid 键仍然是实现此目的的最有效方法。不过为了简化steamer25提供的实现,直接使用如下:

"Condition": {
    "StringLike": {
        "aws:userid": "*:<FUNCTION_NAME>"
    }
}

其中 是您的 Lambda 函数的名称。通配符表示 IAM 角色的 ID,但是,就条件而言,通配符可以正常工作。