2017-03-27 23 views
4

我们正在处理向使用AWS CodePipeline构建并部署到ECS的应用程序提供构建时间和运行时机密的问题。在AWS CodePipeline中处理运行时间和构建时间机密

归根结底,我们的目标是为每一个我们的应用程序的通用流水线实现以下目标:

  • 访问的完全分离
    • 在App-A-管道服务无法在访问凭据的任何或使用任何在App-b-管道使用的按键,反之亦然
  • 秘密管理由开发商指定
    • 只负责开发的应用程序 - 一个可以读取和写入的秘密的应用程序,一个

以下是手头上的问题:

  • 我们的一些应用程序需要访问私有例如,我们的Java应用程序需要访问专用的Maven存储库才能成功构建
  • 我们的一些应用程序lications需要在运行时 例如数据库访问权限,运行我们的应用程序servlet容器需要包含凭据查找和访问数据库

随着一些警告的.xml配置文件:

  • 我们的代码库所在在公共存储库中。我们不希望通过把任何明文或在我们的资料库的秘密密文揭露秘密
  • 我们不想烘烤运行时秘密到我们在CodeBuild创建泊坞的图像即使ECR访问限制
  • 的Cloudformation ECS资源的模板及其关联的参数文件以明文形式驻留在公共存储库中。这消除了通过运行时通过秘密参数到ECS Cloudformation模板的可能性(据我所知)

我们已经使用类似credstash工具来帮助管理凭据考虑。此解决方案要求CodeBuild和ECS任务实例都能够使用AWS CLI。为了避免洗牌更多证书,我们决定最好将特权角色分配给需要使用AWS CLI的实例。这样,CLI可以根据实例元数据中的角色推断凭据。

我们试图设计一种方法来管理我们的秘密,给出这些限制。对于每个应用程序,我们创建一个管道。使用Cloudformation模板,我们创建:

  • 4资源:

    • DynamoDB凭证表
    • KMS凭据项
    • ECR回购
    • CodePipeline(构建,部署等)
  • 3个角色:

    • CodeBuildRole 读访问DynamoDB凭证表 解密使用KMS密钥 写入ECR回购
    • ECSTaskRole 读访问DynamoDB凭证表 解密与ECR回购阅读KMS密钥 许可权限
    • DeveloperRole 对DynamoDB凭证表的读写权限 使用KMS密钥加密和解密权限

CodePipeline的CodeBuild步骤假定CodeBuildRole允许它从凭证表读取构建时间秘密。 CodeBuild然后构建该项目并生成一个Docker Image,将其推送到ECR。最终,部署步骤将使用Cloudformation模板和项目公共存储库中随附的参数文件创建ECS服务。ECS任务定义包括假定ECSTaskRole允许任务从凭证表读取运行时秘密并提取所需的映像来自ECR。

Here is a simple diagram of the AWS resources and their relationships as stated above

我们目前提出的解决方案具有以下问题:

  • 角色重
    • 创建的角色是在我们的组织特权操作。不是谁试图创建上述管道中的所有开发者将有权创建必要的角色
  • 手册DeveloperRole的假设:
    • 既然这样,开发人员就需要手动承担DeveloperRole。我们玩弄了将开发人员用户ARN列表作为参数传递给管道Cloudformation模板的想法。 Cloudformation是否具有将角色或策略分配给指定用户的机制?

有没有更完善的方式在CodePipeline通过周围的秘密,我们可能会远眺,或者是这一点,我们可以得到的最好?

回答

3

两个想法:

AWS Parameter Store可以保护与细粒度的访问控制访问键。此访问可以基于ServiceRoles。

ECS提供了通过这种模式获得了ServiceRole:

build: 
    commands: 
     - curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI | jq 'to_entries | [ .[] | select(.key | (contains("Expiration") or contains("RoleArn")) | not) ] | map(if .key == "AccessKeyId" then . + {"key":"AWS_ACCESS_KEY_ID"} else . end) | map(if .key == "SecretAccessKey" then . + {"key":"AWS_SECRET_ACCESS_KEY"} else . end) | map(if .key == "Token" then . + {"key":"AWS_SESSION_TOKEN"} else . end) | map("export \(.key)=\(.value)") | .[]' -r > /tmp/aws_cred_export.txt 
     - chmod +x /tmp/aws_cred_export.txt 
     - /aws_cred_export.txt && YOUR COMMAND HERE 

如果提供给CodeBuild任务的ServiceRole访问使用你要善于去参数存储键。

快乐的狩猎和希望这有助于

+1

埃里克的建议使用参数存储(另一个AWS服务)是一个伟大的。有一篇关于AWS网站的博客文章,通过一个示例将它用于容器以特定角色运行的ECS应用程序的秘密管理:https://aws.amazon.com/blogs/compute/managing-secrets- for-amazon-ecs-applications-using-parameter-store-and-iam-roles-for-tasks/ 你的脚本/应用程序可以通过API(或者使用SDK或者不使用)或者通过API访问参数存储CLI。 – Kirkaiya

0

在较高层次上,您可以使用精细权限(这听起来像是您想要执行的操作)或使用多个AWS账户来隔离单个AWS账户中的应用程序。本身既不是对错,但我倾向于单独的AWS账户,而不是管理细化的权限,因为您的起始位置是完全隔离的。