Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020
Шаблоны Azure Pipelines позволяют определять повторное использование содержимого, логики и параметров в конвейерах YAML. В этой статье описывается, как шаблоны помогают повысить безопасность конвейера, выполнив следующие действия.
- Определение внешней структуры конвейера для предотвращения проникновения вредоносного кода.
- Автоматическое включение шагов для выполнения таких задач, как сканирование учетных данных.
- Помогая применять проверки защищенных ресурсов, которые образуют фундаментальную платформу безопасности для Azure Pipelines и применяются ко всем структурам конвейеров и компонентам.
Эта статья является частью серии, которая помогает реализовать меры безопасности для Azure Pipelines. Дополнительные сведения см. в статье "Защита Azure Pipelines".
Предпосылки
| Категория | Требования |
|---|---|
| Azure DevOps | — Реализуйте рекомендации в "Обеспечьте безопасность Azure DevOps" и "Защита Azure Pipelines". — Базовые знания о YAML и Azure Pipelines. Дополнительные сведения см. в статье "Создание первого конвейера". |
| Разрешения | — Чтобы изменить разрешения конвейеров: член группы "Администраторы проектов". Чтобы изменить разрешения организации, необходимо быть членом группы администраторов коллекции проектов. |
Включает и расширяет шаблоны
Azure Pipelines предоставляет шаблоны, которые включают и расширяют.
Шаблон
includesсодержит код шаблона непосредственно в файле верхнего уровня, который ссылается на шаблон, аналогично#includeв C++. В следующем примере конвейер вставляет шаблон include-npm-steps.yml в разделsteps.steps: - template: templates/include-npm-steps.ymlШаблон
extendsопределяет внешнюю структуру конвейера и предлагает определенные точки для целевых настроек. В контексте C++extendsшаблоны похожи на наследование.
При использовании extends шаблонов можно также использовать includes для выполнения общих частей конфигурации как в шаблоне, так и в окончательном конвейере. Дополнительные сведения см. в разделе "Использование шаблонов YAML в конвейерах для повторного использования и безопасных процессов".
Расширение шаблонов
Для наиболее безопасных конвейеров начните с шаблонов extends . Эти шаблоны определяют внешнюю структуру конвейера и помогают предотвратить проникновение вредоносного кода.
В следующем примере показан файл шаблона с именем template.yml.
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
В следующем примере конвейер расширяет шаблон template.yml .
# azure-pipelines.yml
resources:
repositories:
- repository: templates
type: git
name: MyProject/MyTemplates
ref: refs/tags/v1
extends:
template: template.yml@templates
parameters:
usersteps:
- script: echo This is my first step
- script: echo This is my second step
Совет
При настройке extends шаблонов рекомендуется привязать их к определенной ветви Git или тегу, чтобы любые критические изменения не влияли на существующие конвейеры. В предыдущем примере эта функция используется.
Функции безопасности конвейера
Синтаксис конвейера YAML включает несколько встроенных защит.
Extends шаблоны могут быть использованы для повышения безопасности пайплайна. Вы можете реализовать любое из следующих ограничений.
Целевые объекты шага
Вы можете ограничить указанные шаги для выполнения в контейнере, а не на узле. Шаги в контейнерах не могут получить доступ к узлу агента, поэтому они не могут изменить конфигурацию агента или оставлять вредоносный код на будущее выполнение.
Например, можно выполнить действия пользователя в контейнере, чтобы предотвратить доступ к сети, чтобы они не могли получать пакеты из несанкционированных источников или отправлять код и секреты во внешние расположения.
В следующем примере конвейер выполняет шаг на узле агента, который может изменить сеть узла, а затем шаг внутри контейнера, который ограничивает доступ к сети.
resources:
containers:
- container: builder
image: mysecurebuildcontainer:latest
steps:
- script: echo This step runs on the agent host
- script: echo This step runs inside the builder container
target: builder
Типобезопасные параметры
Перед запуском конвейера шаблоны и их параметры преобразуются в константы. Параметры шаблона могут повысить безопасность типов для входных параметров.
В следующем примере шаблона параметры ограничивают доступные параметры пула конвейеров, перечисляя определенные варианты вместо того, чтобы разрешить любую строку.
# template.yml
parameters:
- name: userpool
type: string
default: Azure Pipelines
values:
- Azure Pipelines
- private-pool-1
- private-pool-2
pool: ${{ parameters.userpool }}
steps:
- script: echo Hello world
Чтобы расширить шаблон, конвейер должен указать один из доступных вариантов пула.
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Ограничения команд ведения журнала агента
Шаги пользователя запрашивают службы с помощью команд ведения журнала, которые специально отформатированы строки, напечатанные в стандартные выходные данные. Вы можете ограничить службы, предоставляемые командами ведения журнала для действий пользователя. В restricted режиме большинство служб агентов, таких как отправка артефактов и присоединение результатов теста, недоступны для команд ведения журнала.
В следующем примере свойство target инструктирует агента ограничить публикацию артефактов, поэтому задача публикации артефактов завершается сбоем.
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
Переменные в командах ведения журналирования
Команда setvariable остается допустимой в restricted режиме, поэтому задачи, которые выводят предоставленные пользователем данные, такие как открытые проблемы, полученные через REST API, могут быть уязвимы для атак внедрения. Содержимое, созданное злоумышленником, может установить переменные, которые экспортируются в последующие задачи как переменные среды, и может скомпрометировать хост-агента.
Чтобы устранить этот риск, можно явно объявить переменные, которые задаются с помощью setvariable команды ведения журнала. Если вы укажете пустой список в settableVariables, установка всех переменных будет запрещена.
Следующий пример ограничивает использование settableVariables и expectedVar, а также любой переменной с префиксом ok. Задача завершается ошибкой, так как она пытается задать другую переменную BadVar.
- task: PowerShell@2
target:
commands: restricted
settableVariables:
- expectedVar
- ok*
inputs:
targetType: 'inline'
script: |
Write-Host "##vso[task.setvariable variable=BadVar]myValue"
Условный этап или выполнение задания
Этапы и задания можно ограничить только в определенных условиях. Следующий пример гарантирует, что сборки ограниченного кода создаются только для main ветви.
jobs:
- job: buildNormal
steps:
- script: echo Building the normal, unsensitive part
- ${{ if eq(variables['Build.SourceBranchName'], 'refs/heads/main') }}:
- job: buildMainOnly
steps:
- script: echo Building the restricted part that only builds for main branch
Изменение синтаксиса
Шаблоны Azure Pipelines имеют гибкость для итерации и изменения синтаксиса YAML. С помощью итерации можно применить определенные функции безопасности YAML.
Шаблон также может переписать пользовательские шаги, позволяя выполнять только утвержденные задачи. Например, шаблон может предотвратить встроенное выполнение скрипта.
В следующем примере шаблона предотвращается выполнение типов шагов скрипта bash, powershell, pwsh и script. Для полной блокировки сценариев можно также заблокировать BatchScript и ShellScript.
# template.yml
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ if not(or(startsWith(step.task, 'Bash'),startsWith(step.task, 'CmdLine'),startsWith(step.task, 'PowerShell'))) }}:
- ${{ step }}
# The following lines replace tasks like Bash@3, CmdLine@2, PowerShell@2
- ${{ else }}:
- ${{ each pair in step }}:
${{ if eq(pair.key, 'inputs') }}:
inputs:
${{ each attribute in pair.value }}:
${{ if eq(attribute.key, 'script') }}:
script: echo "Script removed by template"
${{ else }}:
${{ attribute.key }}: ${{ attribute.value }}
${{ elseif ne(pair.key, 'displayName') }}:
${{ pair.key }}: ${{ pair.value }}
displayName: 'Disabled by template: ${{ step.displayName }}'
В следующем примере конвейера, расширяющего предыдущий шаблон, шаги скрипта удаляются и не выполняются.
# azure-pipelines.yml
extends:
template: template.yml
parameters:
usersteps:
- task: MyTask@1
- script: echo This step is stripped out and not run
- bash: echo This step is stripped out and not run
- powershell: echo "This step is stripped out and not run"
- pwsh: echo "This step is stripped out and not run"
- script: echo This step is stripped out and not run
- task: CmdLine@2
displayName: Test - stripped out
inputs:
script: echo This step is stripped out and not run
- task: MyOtherTask@2
Шаги шаблона
Шаблон может автоматически включать шаги в конвейер, например для проверки учетных данных или статических проверок кода. Следующий шаблон вставляет шаги до и после действий пользователя в каждом задании.
parameters:
jobs: []
jobs:
- ${{ each job in parameters.jobs }}:
- ${{ each pair in job }}:
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps:
- task: CredScan@1
- ${{ job.steps }}
- task: PublishMyTelemetry@1
condition: always()
Принудительное применение шаблона
Эффективность шаблонов в качестве механизма безопасности зависит от принудительного применения. Основные контрольные точки для соблюдения использования шаблона - это защищённые ресурсы.
Вы можете настроить утверждения и проверки для вашего пула агентов или других защищенных ресурсов, таких как репозитории. Пример см. в разделе "Добавление проверки ресурса репозитория".
Обязательные шаблоны
Чтобы применить использование определенного шаблона, настройте необходимую проверку шаблона для подключения службы к ресурсу. Эта проверка применяется только в том случае, если конвейер расширяется из шаблона.
При просмотре задания конвейера можно отслеживать состояние проверки. Если конвейер не расширяется из требуемого шаблона, проверка завершается ошибкой.
При использовании обязательного шаблона проверка проходит.
Например, в любом конвейере, расширяющем его, необходимо ссылаться на следующий шаблон params.yml.
# params.yml
parameters:
- name: yesNo
type: boolean
default: false
- name: image
displayName: Pool Image
type: string
default: ubuntu-latest
values:
- windows-latest
- ubuntu-latest
- macOS-latest
steps:
- script: echo ${{ parameters.yesNo }}
- script: echo ${{ parameters.image }}
В следующем примере конвейер расширяет шаблон params.yml и требует его утверждения. Чтобы продемонстрировать сбой конвейера, закомментируйте ссылку extends на params.yml.
# azure-pipeline.yml
resources:
containers:
- container: my-container
endpoint: my-service-connection
image: mycontainerimages
extends:
template: params.yml
parameters:
yesNo: true
image: 'windows-latest'