Сохранение вашего кода в целости и сохранности
Внедрение секретов в конвейеры CI/CD
Краткое руководство по репозиториям GitHub, Azure DevOps и App Center.
Как вы, надеюсь, уже знаете, никогда не следует включать секреты (например, ключи API, симметричные ключи, сертификаты и т. д.) в свои репозитории. Даже не в частных.
Недавно мне пришлось использовать секреты для личного проекта и для проекта заказчика. Мне нужно было придумать элегантное решение для моих .NET-проектов, и я решил поделиться с вами своими знаниями и лучшими практиками.
Вообще говоря, есть два подхода к реализации секретов в ваших проектах .NET:
Секреты пользователя
Вы включаете секреты в секретный файл. Приложение .NET загрузит их для вас во время выполнения. В рабочей среде вы указываете секреты с помощью других средств (таких как Key Vault и т. д.). Обычно это работает для проектов ASP.NET Core и рабочих служб.
Константы
Вы указываете типизированные секреты в статическом классе и ссылаетесь на класс в своих проектах. Обычно это используется для приложений и тестовых проектов.
В этой статье я сосредоточусь на последнем сценарии для проектов на основе .NET:
- В моем личном проекте мне пришлось добавлять секреты в свое приложение UWP с помощью App Center и GitHub.
- В коммерческом проекте я выбрал TDD так естественно, что мне пришлось предоставить некоторые секреты для моих интеграционных тестов, не перебарщивая, потому что я хотел сохранить KISS. Для этого я использовал Azure DevOps.
Без дальнейших церемоний, поехали.
Первоначальные соображения по проекту
Теперь то, как именно вы включаете секреты, зависит исключительно от вашего проекта. В моем случае я создал частичный статический класс с именем Constants.cs
, в котором я определяю необходимые свойства, и еще один частичный класс Constants.Secret.cs
, содержащий распространяемые значения:
Чтобы дать вам представление, вот как выглядят оба файла:
// Constants.cs public static partial class Constants { public static string ApiKey { get; set; } } // Constants.Secret.cs public static partial class Constants { static Constants() { ApiKey = "verysecretkey!123" } }
Компилятор Rosyln автоматически разрешает оба файла. Чтобы использовать класс, не требуется специальной настройки, и вы можете просто ссылаться на свойство Constants.ApiKey
из любого места.
Теперь, прежде чем что-либо коммитить в Git, убедитесь, что вы добавили секретный файл в свой файл .gitignore:
Constants.Secret.cs
Это будет игнорировать все файлы, которые соответствуют имени в вашем репозитории, поэтому они никогда не будут проверены в вашем удаленном репозитории. Очень удобно, если в вашем решении много разных проектов, у которых есть свой набор секретов.
Давай, предоставьте хорошее сообщение о коммите и нажмите его. После того, как вы это сделаете, мы можем заняться аспектами CI/CD.
CI/CD
Нам требуется некоторая настройка CI/CD, потому что на данный момент все сборки будут просто терпеть неудачу, поскольку компилятор не может найти файл Constants.Secret.cs
в репозитории — в первую очередь потому, что на него есть ссылка в нашем решении, но его нельзя найти в рабочем каталоге удаленного репозитория.
Чтобы решить эту проблему, я покажу три варианта, которые должны работать в большинстве сценариев: GitHub, Azure DevOps и App Center.
Основываясь на этих сценариях, вы должны получить вдохновение и быть в состоянии применить знания к другим сервисам.
Гитхаб
GitHub позволяет хранить секреты в вашем репозитории. Затем на эти секреты можно ссылаться из ваших действий GitHub.
Чтобы управлять своими секретами, перейдите в свой репозиторий и нажмите Настройки › Секреты.
Там создайте новый секрет репозитория и включите в него содержимое файла Constants.Secret.cs
. Дайте ему запоминающееся имя (с этого момента я буду называть его <CONSTANTS>
. Вы должны использовать другое имя) и сохраните секрет.
Теперь пришло время создать файл класса на основе секрета вашего репозитория в файле определения действия, чтобы его можно было создать до того, как произойдет фактическая сборка.
Скрипт может выглядеть так: он просто запишет содержимое секрета в файл.
steps:
- uses: actions/checkout@v2
- name: Create Constants
run: echo ${{secrets.<CONSTANTS>}}
> "./<PATH>/Constants.Secret.cs"
# ...
Убедитесь, что вы вставили этот шаг перед любыми шагами сборки, которые зависят от вашего файла констант, и не забудьте заменить заполнитель именем вашего фактического секрета.
Зафиксируйте обновленный файл действий, и ваша сборка должна завершиться успешно.
Azure DevOps
Azure DevOps позволяет загружать защищенные файлы. Защищенные файлы — хорошее решение для управления вашими секретными файлами в ваших пайплайнах. Это позволяет вам управлять тем, кто может получить доступ к защищенным файлам и какие конвейеры могут их использовать.
Чтобы управлять всеми своими секретами, убедитесь, что вы включили Pipelines для своего проекта. Затем перейдите в раздел Конвейеры › Библиотека. Библиотека позволяет повторно использовать переменные и хранить защищенные файлы.
Там перейдите на вкладку Защищенные файлы, загрузите свой секретный класс констант (Constants.Secret.cs) и убедитесь, что вы дали ему хорошее имя — такое, которое позволит вам отличать константные классы друг от друга. в случае, если у вас есть более чем один из них.
После этого пришло время добавить наш защищенный файл в конвейер сборки. Для использования защищенных файлов используется задача SecureFile. В качестве входных данных требуется имя задачи и имя защищенного файла. имя задачи позволяет ссылаться на файл на всех последовательных шагах сборки:
steps: - task: DownloadSecureFile@1 name: constantsFile displayName: 'Download Constants for Integration Tests' inputs: secureFile: 'Constants.Secret.cs'
После этого нам нужно скопировать файл в то место, где он должен быть. В противном случае наша сборка завершится ошибкой, потому что компилятор не найдет класс, на который ссылается наше решение, как упоминалось ранее:
- script: cp $(constantsFile.secureFilePath) <PATH>/Constants.Secret.cs displayName: Copy constants
И вы сделали! Этот шаг теперь скопирует защищенный файл в место назначения.
Сохраните определение сборки и запустите его. Ваша сборка должна быть успешной.
Центр приложений
Центр приложений позволяет запускать пользовательские сценарии на определенных этапах. Подробнее об этом можно прочитать в Документации App Center.
Вам нужно будет использовать собственный скрипт для ввода ваших констант до начала сборки. Однако, поскольку сценарий сборки содержит распространяемые вами константы и должен быть проверен в вашем удаленном репозитории, рекомендуется либо не включать какие-либо конфиденциальные сведения, либо распространять содержимое из безопасных переменных среды.
Если вы решите использовать первый подход, который я покажу, вам нужно будет убедиться, что ваше приложение будет вести себя правильно даже без каких-либо постоянных значений.
Если вы планируете использовать App Center только для целей CI, все будет в порядке. Однако, если вы планируете распространять пакет своего приложения среди тестировщиков, вам нужно будет найти способы распространения ваших констант.
В этом случае рассмотрите возможность использования переменных среды при создании класса констант или предоставьте способы распространения значений во время выполнения пользователем (например, файлы конфигурации и т. д.).
Я создал приложение UWP, и мне пришлось распространить в нем несколько констант. Чтобы добавить сценарий пост-клонирования, добавьте файл сценария в корневой путь вашего репозитория.
Для сборок на основе Windows, таких как UWP(appcenter-post-clone.ps1)
"namespace <PLACEHOLDER> { public static partial class Constants { static Constants() { } } }" | Out-File -FilePath ".\\<PATH>\\Constants.Secret.cs
Для сборок на базе Mac (appcenter-post-clone.sh)
echo "namespace <PLACEHOLDER>\ {\ public static partial class Constants\ {\ static Constants() { } \ }\ }" > "<PATH>/Constants.Secret.cs.cs"
Оба скрипта записывают внедренное содержимое в файл. Убедитесь, что вы зафиксировали и отправили файл в свой репозиторий, а затем запустили сборку. Если вы боретесь с этим, взгляните на официальные образцы для справки.
Надеюсь, эта статья поможет и вдохновит вас. Дайте мне знать, что вы думаете.
Недавно я стал студенческим послом Microsoft Learn. Если вы хотите, чтобы я публиковал больше статей в будущем, подписывайтесь на меня в Medium и Twitter. Также обратите внимание на другие мои статьи!
Привет, и спасибо за чтение!