您如何管理您假定的角色IAM策略以访问AWS Secret Manager中的机密?

时间:2018-07-12 17:32:40

标签: amazon-web-services aws-secrets-manager

我正在开始将我们的机密从AWS参数存储迁移到AWS机密管理器,目前我面临着一个我无法解决的问题,有人可以提供任何见解吗?

我们有一个AWS帐户(我们称其为身份帐户),该帐户用于管理所有IAM用户和组。我们还有另一个托管我们的基础设施的AWS账户(我们称此基础设施账户)。我们想管理身份帐户中的所有用户,并让用户承担基础帐户中的poweruser角色,以便我们可以在一个地方管理所有用户。

在infra帐户中,我们正在运行RDS,我们希望为开发人员创建DB用户,以便他们可以登录数据库以进行调试,但是我们还想审核他们所做的事情,以防有人对我们进行了不良操作数据库,因此我们需要为每个开发人员创建一个数据库用户。所有这些数据库凭证都使用诸如以下的命名约定保存到AWS Secret中 /dev/rds/mysql/users/foo /dev/rds/mysql/users/bar 所以这是一个问题:我该如何管理用户的IAM策略以限制用户的权限,以便他们只能访问自己的秘密?this AWS doc中我们不能当用户使用假定角色访问AWS时获取aws:username,因此以下策略将永远无效

actions   = [
  "secretsmanager:DescribeSecret",
  "secretsmanager:GetSecretValue",
  "secretsmanager:PutSecretValue",
  "secretsmanager:UpdateSecretVersionStage"
]
resources = [
  "arn:aws:secretsmanager:us-east-1:12345678912:secret:/dev/rds/mysql/users/${aws:username}"
]

我可以用作假定角色的唯一IAM变量是aws:userid,但这将是这样的(假设用户foo在身份帐户中的用户名是foo@emaildomain.com

"AROAJGHLP6KERYI375PJY:foo@emaildomain.com"

看起来role-id(在此示例中为AROAJGHLP6KERYI375PJY)是随机的,前缀为AROA,这意味着我不能使用以下策略(而且,在机密管理器中将AROAJGHLP6KERYI375PJY:foo@emaildomain.com作为机密名称非常难看)

actions   = [
  "secretsmanager:DescribeSecret",
  "secretsmanager:GetSecretValue",
  "secretsmanager:PutSecretValue",
  "secretsmanager:UpdateSecretVersionStage"
]
resources = [
  "arn:aws:secretsmanager:us-east-1:12345678912:secret:/dev/rds/mysql/users/${aws:userid}"
]

目前,我的政策以

结尾
actions   = [
  "secretsmanager:DescribeSecret",
  "secretsmanager:GetSecretValue",
  "secretsmanager:PutSecretValue",
  "secretsmanager:UpdateSecretVersionStage"
]
resources = [
  "arn:aws:secretsmanager:us-east-1:12345678912:secret:/dev/rds/mysql/users/*"
]

这意味着只要用户假设要注册帐户,他们就可以访问其他开发人员的数据库凭据。

我研究了CloudWatch指标,看是否可以设置过滤器以过滤掉用户foo正在调用GetSecretValue API的API调用以获取用户bar的证书,但CloudWatch过滤器不支持用户REGEX从JSON提取某些值。这是CloudTrail日志中的GetSecretValue事件的示例:

{
    "eventVersion": "1.05",
    "userIdentity": {
        "type": "AssumedRole",
        "principalId": "AROAJGHLP6KERYI375PJY:foo@emaildomain.com",
        "arn": "arn:aws:sts::12345678912:assumed-role/poweruser/foo@emaildomain.com",
        "accountId": "12345678912",
        "accessKeyId": "ASIATA5XIF7AFC2CQ7NO",
        "sessionContext": {
            "attributes": {
                "mfaAuthenticated": "true",
                "creationDate": "2018-07-11T21:31:20Z"
            },
            "sessionIssuer": {
                "type": "Role",
                "principalId": "AROAJGHLP6KERYI375PJY",
                "arn": "arn:aws:iam::12345678912:role/poweruser",
                "accountId": "12345678912",
                "userName": "poweruser"
            }
        }
    },
    "eventTime": "2018-07-11T21:32:56Z",
    "eventSource": "secretsmanager.amazonaws.com",
    "eventName": "GetSecretValue",
    "awsRegion": "us-east-2",
    "sourceIPAddress": "1.2.3.4",
    "userAgent": "aws-internal/3",
    "requestParameters": {
        "secretId": "/dev/rds/mysql/users/foo"
    },
    "responseElements": null,
    "requestID": "f98ad2c2-8551-11e8-8a3f-751b0a8a6ca5",
    "eventID": "73b8de89-bc8c-41a3-a172-58dd8d79a026",
    "eventType": "AwsApiCall",
    "recipientAccountId": "12345678912"
}

如果我可以从foo@emaildomain.com提取{ $.userIdentity.principalId }并从foo提取{ $.requestParameters},那么我可以尝试用一些魔术来比较foo@emaildomain.com == foo来触发用户正在尝试获得其他人的证书,但是,我不能...

因此,在这种情况下,如何管理我的策略来锁定用户的权限?

2 个答案:

答案 0 :(得分:0)

在第一个示例中,您可以针对每个用户尝试在其用户iam策略中对秘密进行硬编码吗?

因此对于用户foo,用户策略应类似于

 ...
    actions   = [
  "secretsmanager:DescribeSecret",
  "secretsmanager:GetSecretValue",
  "secretsmanager:PutSecretValue",
  "secretsmanager:UpdateSecretVersionStage"
]
resources = [
  "arn:aws:secretsmanager:us-east-1:12345678912:secret:/dev/rds/mysql/users/foo"
]
 ...

酒吧的结构,...

如果您有很多用户,此解决方案将无法扩展

答案 1 :(得分:0)

问题似乎是您在为所有用户使用一个通用的假定角色。替代方法是在每个秘密上创建资源策略,该资源策略向身份帐户中的所有者授予访问权限。这将使用户无需调用承担即可直接访问机密。这不会阻止他们仍然担任基础帐户超级用户角色并访问机密,因此您要么必须从角色中删除Secrets Manager特权,要么在添加到机密的资源策略中明确拒绝基础用户。< / p>

像这样设置交叉帐户访问权限也意味着您不能使用默认的KMS加密密钥。您将需要设置一个自定义KMS密钥,该密钥将correct access permission授予身份帐户,并使用该新密钥重新加密机密。

由于无法在Secrets Manager控制台中设置资源策略和自定义KMS密钥,因此都需要使用CLI或其中一个SDK。

相关问题