Обработка секретов времени выполнения и времени сборки в AWS CodePipeline
Мы имеем дело с проблемой предоставления секретов времени сборки и времени выполнения нашим приложениям, построенным с использованием AWS CodePipeline и развертываемым в ECS.
В конечном счете, наше видение заключается в создании универсального конвейера для каждого из наших приложений, который достигает следующих целей:
- полное разделение доступа
- службы в конвейере app-a не могут получить доступ к каким-либо учетным данным или использовать какие-либо ключи, используемые в конвейере app-b и visa-versa
- секретное управление назначенными разработчиками
- Только разработчики, ответственные за app-a, могут читать и писать секреты для app-a
Вот основные вопросы:
- Некоторые из наших приложений требуют доступа к частным репозиториям для разрешения зависимостей во время сборки.
Например, для успешного построения наших java-приложений требуется доступ к частному репозиторию maven - Некоторые из наших приложений требуют базы данных учетные данные доступа во время выполнения
Например, контейнер сервлета, выполняющий наше приложение, требует .xml-файл конфигурации, содержащий учетные данные для поиска и доступа к базам данных
Вместе с некоторыми оговорками:
- Наша кодовая база находится в публичном хранилище. Мы не хотим раскрывать секреты, помещая либо открытый текст, либо зашифрованный текст секрета в наше хранилище
- мы не хотим испечь секреты времени выполнения в наших образах Docker, созданных в CodeBuild, даже если доступ к ECR ограничено
- шаблон Cloudformation для ресурсов ECS и связанный с ним файл параметров находятся в открытом хранилище в открытом виде. Это исключает возможность передачи секретов среды выполнения шаблону ECS Cloudformation через параметры (насколько я понимаю)
Мы рассматривали использование таких инструментов, какcredstash , чтобы помочь с управлением учетными данными. Это решение требует, чтобы экземпляры задач CodeBuild и ECS имели возможность использовать AWS Кли. Чтобы избежать перетасовки дополнительных учетных данных, мы решили, что лучше всего назначить привилегированные роли экземплярам, которые требуют использования AWS CLI. Таким образом, CLI может выводить учетные данные из роли в метаданных экземпляров
Мы пытались разработать способ управления нашими секретами, учитывая эти ограничения. Для каждого приложения мы создаем конвейер. Используя шаблон Cloudformation, мы создаем:
4 ресурсы:
- учетные данные DynamoDB таблица
- KMS credential key
- ECR repo
- CodePipeline (Build, deploy, etc)
3 роли:
- CodeBuildRole
Доступ на чтение к таблице учетных данных DynamoDB
Расшифровать разрешение с помощью ключа KMS
Написать в ECR repo - Экстаскрол
Доступ на чтение к таблице учетных данных DynamoDB
Расшифровать разрешение с помощью ключа KMS
Чтение из ECR repo - DeveloperRole
Доступ на чтение и запись к таблице учетных данных DynamoDB
Разрешение на шифрование и расшифровку с помощью KMS ключ
- CodeBuildRole
Шаг CodeBuild CodePipeline предполагает, что CodeBuildRole позволяет ему считывать секреты времени сборки из таблицы учетных данных. CodeBuild затем строит проект и генерирует образ Docker, который он отправляет в ECR. В конечном счете, на этапе развертывания создается служба ECS с использованием шаблона Cloudformation и сопутствующего файла параметров, присутствующего в публичном репозитории проектов определение задачи ECS включает предположение, что ECSTaskRole позволяет задачам читать секреты среды выполнения Из таблицы учетных данных и извлечь требуемый образ из ECR.
Вот простая схема ресурсов AWS и их взаимосвязей, как указано выше
Наше текущее предлагаемое решение имеет следующие проблемы:
- роль тяжелая
- Создание ролей-это привилегированное действие в нашей организации. Не все разработчики, которые пытаются создать вышеупомянутый конвейер, будут иметь разрешение на создание необходимых ролей
- в нынешнем виде разработчикам потребуется вручную взять на себя роль разработчика. Мы поиграли с идеей передать в качестве параметра шаблона pipeline Cloudformation список пользовательских ARNs разработчика. Есть ли у Cloudformation механизм назначения роли или политики определенному пользователю?
Есть ли более устоявшийся способ передавать секреты в CodePipeline, который мы могли бы упустить, или это лучшее, что мы можем получить?
2 ответов:
Три мысли:
AWS Secret ManagerAWS Secrets Manager помогает защитить секреты доступа к приложениям, сервисам и ИТ-ресурсам. С его помощью вы можете вращать, управлять и извлекать учетные данные базы данных, ключи API и другие секреты на протяжении всего их жизненного цикла.
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Если ваш ServiceRole, предоставленный задаче CodeBuild, имеет доступ к использованию ключа хранилища параметров, вы должны быть готовы.
Счастливой охоты и надеюсь, что это поможет
На высоком уровне можно либо изолировать приложения в одном аккаунте AWS с детализированными разрешениями (это похоже на то, что вы пытаетесь сделать), либо использовать несколько аккаунтов AWS. Ни то, ни другое не является правильным или неправильным само по себе, но я предпочитаю отдельные учетные записи AWS управлению гранулярными разрешениями, потому что ваше начальное место-полная изоляция.
Comments