从 CloudFormation AccessKey Creation 安全地获取访问密钥/秘密

Securely Get Access Key / Secret from CloudFormation AccessKey Creation

我创建了一个 CloudFormation 模板,它成功地创建了一个 IAM 用户和一个 AccessKey,并将该 AccessKey 分配给 IAM 用户。现在我通过在 CloudFormation 模板的 Outputs 部分输出它来获取 AccessKey 的秘密。

我想知道是否有更安全的方法来创建 AccessKey 并获取其相应的秘密,而无需在 Outputs 部分以纯文本形式吐出。

我对此感到有点困惑,因为 AWS 没有太多关于这样做的信息,而且它确实有一些直接相互矛盾的小文档。 Here AWS suggests doing what I've described above "One way to retrieve the secret key is to put it into an Output value". This seems like a security issue, and is confirmed by another AWS doc Here 上面写着“我们强烈建议您不要使用此部分输出敏感信息,例如密码或秘密”。

我是误解了他们的文档还是直接矛盾?我看到 S/O 评论 建议使用 AWS secrets manager 但我无法弄清楚如何将 AccessKey secret 放入 Secrets Manager 中,在那里可以更安全地存储和获取它通过类似 boto3 的东西。任何这样的例子都会非常有帮助。我的 CloudFormation 模板在下面供参考。

{
    "Description": "My CloudFormation Template",
    "Outputs": {
        "UserAccessKeyId": {
            "Description": "The value for the User's access key id.",
            "Value": {
                "Ref": "UserAccessKey"
            }
        },
        "UserSecretKey": {
            "Description": "The value for the User's secret key.",
            "Value": {
                "Fn::GetAtt": [
                    "UserAccessKey",
                    "SecretAccessKey"
                ]
            }
        }
    },
    "Resources": {
        "User": {
            "Properties": {
                "UserName": "myNewUser"
            },
            "Type": "AWS::IAM::User"
        },
        "PrimaryUserAccessKey": {
            "DependsOn": "User",
            "Properties": {
                "Status": "Active",
                "UserName": "myNewUser"
            },
            "Type": "AWS::IAM::AccessKey"
        }
    }
}

我建议将它放在 Secret 中。您可以让 CloudFormation 将值写入堆栈中的 Secrets Manager,然后您可以通过代码访问它。这让您拥有一个秘密,任何人都必须看到或触摸才能使用它。

我认为这样的事情应该可行(注意:我还没有实际尝试过)。


AccessKey:
  Type: AWS::IAM::AccessKey
  Properties: 
    Serial: 1
    Status: Active
    UserName: 'joe'

  AccessKeySecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: JoeAccessKey
      Description: Joes Access Key
      SecretString: !Sub '{"AccessKeyId":"${AccessKey}","SecretAccessKey":"${AccessKey.SecretAccessKey}"}'