Лучшие практики безопасного управления учетными данными Jenkins

Безопасно храните секреты Jenkins с помощью Credentials Plugin, области видимости папок, withCredentials, RBAC, ротации и внешних хранилищ.

Лучшие практики безопасного управления учетными данными Jenkins

Заданиям Jenkins часто требуются секреты, близкие к производственным: облачные токены, пароли реестров, ключи развертывания, сертификаты подписи и учетные данные API. Если эти секреты окажутся в Jenkinsfile, консольном журнале или параметре задания, ваша система CI/CD станет прямым путем к компрометации.

Используйте Credentials Plugin, ограничивайте область видимости учетных данных и внедряйте их только для того шага, который в них нуждается.

Основа: Jenkins Credentials Plugin

Credentials Plugin — это стандартный механизм, который Jenkins использует для хранения конфиденциальных данных. Он предоставляет централизованное зашифрованное хранилище для учетных данных, гарантируя, что секреты никогда не будут раскрыты в журналах сборки, системе контроля версий или файлах конфигурации.

Когда Jenkins сохраняет учетные данные, он шифрует их, используя ключевой материал на контроллере Jenkins, включая файлы в JENKINS_HOME/secrets. Любой, имеющий широкий доступ к файловой системе контроллера и конфигурации Jenkins, потенциально может восстановить секреты, поэтому доступ к файловой системе и администраторам должен быть строго ограничен.

Ключевые типы учетных данных

Понимание доступных типов учетных данных — первый шаг к безопасной реализации. Выбирайте тип, который наиболее точно соответствует хранимому секрету:

  1. Secret Text (Секретный текст): Используется для общих коротких текстовых значений, таких как токены API, ключи доступа, OAuth-токены или секреты вебхуков.
  2. Username and Password (Имя пользователя и пароль): Стандартная пара для аутентификации в таких сервисах, как репозитории Maven, частные реестры (Docker Hub, Artifactory) или внутренние приложения.
  3. SSH Username with Private Key (SSH-имя пользователя с закрытым ключом): Необходим для доступа к удаленным агентам, клонирования частных Git-репозиториев или выполнения команд на удаленной инфраструктуре. Закрытый ключ можно ввести напрямую, указать путь или управлять им через контроллер Jenkins.
  4. Secret File (Секретный файл): Используется для загрузки целых файлов, которые являются конфиденциальными, таких как хранилища ключей, сертификаты (.pem, .crt) или файлы конфигурации, содержащие секреты.

Совет: Всегда используйте максимально детализированный тип учетных данных. Например, если вам нужен только ключ API, используйте Secret Text, а не пытайтесь вписать его в поля имени пользователя и пароля.

Принцип наименьших привилегий: Область видимости учетных данных

Область видимости учетных данных определяет, где они доступны в среде Jenkins. Применение принципа наименьших привилегий — предоставление только того доступа, который необходим для работы, — имеет решающее значение.

1. Системная область видимости (System Scope)

Учетные данные с системной областью видимости (хранятся в Manage Jenkins > Manage Credentials > Jenkins) доступны глобально для всех заданий, папок и конвейеров в экземпляре Jenkins.

  • Использование: Используйте системную область видимости только для секретов, необходимых для всей работы Jenkins, таких как учетные данные, используемые плагинами глобальной конфигурации, или секреты, необходимые для всех подключений агентов.
  • Предупреждение: Сведите к минимуму использование системной области видимости. Любое скомпрометированное задание потенциально может получить доступ ко всем глобально доступным секретам.

2. Область видимости папки (Folder Scope)

Учетные данные с областью видимости папки определяются в конкретной папке (созданной с помощью плагина Folder или через папки организации). Эти секреты видны и могут использоваться только заданиями, находящимися в этой папке и ее подпапках.

  • Рекомендация: Всегда предпочитайте область видимости папки. Это разделяет доступ и ограничивает радиус поражения в случае компрометации одного проекта.

Безопасное внедрение в декларативные конвейеры

Не жестко кодируйте учетные данные в скриптах конвейера. Переменные окружения приемлемы только тогда, когда Jenkins внедряет их для узкого блока и маскирует известные секретные значения в журналах.

Безопасный метод доступа к учетным данным в декларативном конвейере — использование встроенного шага withCredentials. Этот шаг загружает указанные учетные данные в переменную окружения с ограниченной областью видимости, которая доступна только во время выполнения блока.

Пример 1: Внедрение секретного текста (токен API)

Этот пример безопасно извлекает учетные данные Secret Text (MY_API_TOKEN) и присваивает их значение внутренней переменной SECRET_TOKEN. После завершения блока withCredentials переменная SECRET_TOKEN автоматически удаляется из окружения.

pipeline {
    agent any
    stages {
        stage('Deploy via API') {
            steps {
                script {
                    withCredentials([string(credentialsId: 'MY_API_TOKEN', variable: 'SECRET_TOKEN')]) {
                        sh "echo 'Calling external API...'"
                        sh '''
                            curl -X POST \
                              -H "Authorization: Bearer $SECRET_TOKEN" \
                              https://api.mycorp.com/deploy
                        '''
                    }
                }
            }
        }
    }
}

Пример 2: Внедрение имени пользователя и пароля

При использовании учетных данных Username and Password шаг withCredentials разделяет секрет на две переменные: одну для имени пользователя и одну для пароля, обычно с суффиксами _USR и _PSW (или пользовательскими именами).

pipeline {
    agent any
    stages {
        stage('Login to Registry') {
            steps {
                withCredentials([usernamePassword(credentialsId: 'DOCKER_REGISTRY_CRED', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
                    sh '''
                        printf '%s' "$DOCKER_PASS" | docker login \
                          --username "$DOCKER_USER" \
                          --password-stdin my.registry.com
                    '''
                }
            }
        }
    }
}

Предупреждение безопасности: Подавление журнала

Jenkins пытается маскировать известные значения учетных данных в журналах сборки, но маскировка не заменяет тщательно написанные скрипты. Не выводите секреты на печать, не передавайте пароли в командной строке и не запускайте трассировку оболочки (set -x) при использовании секретов.

Расширенная интеграция безопасности

Для сред с высокими требованиями к безопасности полагаться только на локальный мастер-ключ Jenkins часто недостаточно. Интеграция с внешней системой управления секретами обеспечивает разделение ответственности, централизованный аудит и расширенные возможности шифрования.

Внешние хранилища учетных данных

Популярные интеграции включают:

  • HashiCorp Vault: Используя плагин Vault, Jenkins может динамически запрашивать секреты из Vault во время выполнения. Это означает, что секреты никогда не хранятся постоянно на контроллере Jenkins, а только временно в памяти во время фазы выполнения.
  • AWS Secrets Manager/Azure Key Vault: Облачные плагины позволяют конвейерам извлекать секреты непосредственно из этих сервисов, используя IAM-роли или субъекты-службы, что сводит к минимуму статическое раскрытие учетных данных.

Использование внешних хранилищ соответствует лучшим практикам безопасности за счет:

  1. Разделения хранения: Инфраструктура секретов отделена от сервера CI/CD.
  2. Динамического доступа: Секреты можно часто ротировать без необходимости ручного обновления конфигурации Jenkins.
  3. Расширенного аудита: Все попытки доступа к секретам регистрируются во внешней системе хранилища.

Управление доступом на основе ролей (RBAC)

Внедрение плагина RBAC (например, Role-based Authorization Strategy) позволяет администраторам контролировать не только то, кто может запускать задание, но и кто может настраивать и просматривать определенные учетные данные.

  • Ограничьте права на настройку заданий, чтобы только доверенные пользователи могли привязывать учетные данные в конвейерах.
  • Ограничьте возможность изменения или создания учетных данных системного уровня небольшой группой администраторов безопасности или платформы.

Лучшие практики управления учетными данными

Практика Описание Преимущество для безопасности
Используйте область видимости папки Ограничьте доступ к учетным данным конкретными заданиями/папками, которым они нужны. Ограничивает раскрытие и радиус поражения.
Избегайте жесткого кодирования Никогда не помещайте секреты в Jenkinsfile, скрипты сборки или систему контроля версий. Устраняет уязвимость исходного кода.
Используйте withCredentials Безопасно внедряйте секреты в шаги конвейера с помощью официального API Jenkins. Обеспечивает автоматическое удаление из журналов и очистку окружения.
Интегрируйте внешнее хранилище Используйте Vault, AWS Secrets Manager или Azure Key Vault для корпоративных развертываний. Разделяет хранение и обеспечивает динамическую ротацию.
Применяйте RBAC Используйте плагины авторизации, чтобы ограничить круг лиц, которые могут настраивать, просматривать и использовать учетные данные. Обеспечивает соблюдение принципа наименьших привилегий среди пользователей.
Регулярная ротация Регулярно меняйте ключи API и пароли (в идеале автоматически через внешнее хранилище). Минимизирует временное окно для использования скомпрометированных секретов.
Защита контроллера Обеспечьте строгие права доступа к файловой системе на контроллере Jenkins для защиты master.key. Защищает основной механизм шифрования.

Относитесь к учетным данным Jenkins как к производственным секретам. Ограничивайте их область видимости, связывайте их ненадолго, регулярно меняйте и ограничивайте доступ к контроллеру только теми, кому разрешено восстанавливать эти секреты.