Обеспечение безопасности с помощью шаблонов
Azure DevOps Services | Azure DevOps Server 2022 г. | Azure DevOps Server 2020 г.
Проверки защищенных ресурсов — это базовый стандартный блок безопасности для Azure Pipelines. Проверки работают независимо от структуры конвейера (этапов и заданий). Если несколько конвейеров в вашей команде или организации имеют одинаковую структуру, вы можете дополнительно упростить безопасность с помощью шаблонов.
Azure Pipelines предлагает два типа шаблонов: включает и расширяет.
Включенные шаблоны ведут себя так же, как #include
в C++: код шаблона вставляется прямо во внешний файл, который ссылается на него. Например, здесь вставляется шаблон включения (include-npm-steps.yml
) в steps
.
steps:
- template: templates/include-npm-steps.yml
Чтобы продолжить метафору C++, шаблоны больше похожи на наследование: шаблон предоставляет внешнюю структуру конвейера и набор мест, extends
где потребитель шаблона может вносить целевые изменения.
Использование расширений шаблонов
Для наиболее безопасных конвейеров рекомендуется начать с extends
шаблонов.
Предоставляя внешнюю структуру, шаблон может предотвратить попадание вредоносного кода в конвейер.
Вы по-прежнему можете использовать includes
как в шаблоне, так и в конечном конвейере, чтобы учитывать общие элементы конфигурации.
Чтобы использовать шаблон расширения, конвейер может выглядеть так, как показано в приведенном ниже примере.
# template.yml
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
# 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
В синтаксис YAML встроено несколько средств защиты, и в шаблоне расширения могут принудительно применяться любые из них.
Целевые объекты шагов
Ограничьте выполнение некоторых шагов в контейнере, а не на узле. Без доступа к узлу агента пользователь не сможет изменить конфигурацию агента или оставить вредоносный код для последующего выполнения. Сначала выполните код на узле, чтобы сделать контейнер более безопасным. Например, рекомендуется ограничить доступ к сети. Без открытого доступа к сети действия пользователя не смогут получить доступ к пакетам из несанкционированных источников или отправить код и секреты в сетевое расположение.
resources:
containers:
- container: builder
image: mysecurebuildcontainer:latest
steps:
- script: echo This step runs on the agent host, and it could use docker commands to tear down or limit the container's network
- script: echo This step runs inside the builder container
target: builder
Ограничения команд ведения журнала агента
Ограничьте службы, предоставляемые агентом Azure Pipelines, для действий пользователя. Шаги запрашивают службы с помощью команд ведения журнала (специально отформатированные строки, напечатанные в stdout). В режиме ограниченного доступа большинство служб агента, таких как отправка артефактов и присоединение результатов теста, недоступны.
# this task will fail because its `target` property instructs the agent not to allow publishing artifacts
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
Одной из команд, по-прежнему разрешенных в ограниченном режиме setvariable
, является команда . Поскольку переменные конвейера экспортируются в качестве переменных среды для последующих задач, задачи, которые выводят данные, предоставленные пользователем (например, содержимое открытых проблем, полученных из REST API), могут быть уязвимы для атак путем внедрения. Такое пользовательское содержимое может задавать переменные среды, которые, в свою очередь, можно использовать для использования узла агента. Чтобы запретить это, авторы конвейера могут явно объявить переменные, которые можно задать, с помощью setvariable
команды ведения журнала. Указание пустого списка запрещает настройку всех переменных.
# this task will fail because the task is only allowed to set the 'expectedVar' variable, or a variable prefixed with "ok"
- task: PowerShell@2
target:
commands: restricted
settableVariables:
- expectedVar
- ok*
inputs:
targetType: 'inline'
script: |
Write-Host "##vso[task.setvariable variable=BadVar]myValue"
Условная вставка этапов или заданий
Ограничьте этапы и задания для выполнения в определенных условиях. Условия могут помочь, например, убедиться, что вы создаете только определенные ветви.
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
Требовать определенный синтаксис с расширениями шаблонов
Шаблоны могут выполнять итерацию, а также изменять или запрещать любой синтаксис 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 lines below will 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 will be stripped out and not run!
- bash: echo This step will be stripped out and not run!
- powershell: echo "This step will be stripped out and not run!"
- pwsh: echo "This step will be stripped out and not run!"
- script: echo This step will be stripped out and not run!
- task: CmdLine@2
displayName: Test - Will be stripped out
inputs:
script: echo This step will be stripped out and not run!
- task: MyOtherTask@2
Типобезопасные параметры
Шаблоны и их параметры превратятся в константы перед запуском конвейера. Параметры шаблона обеспечивают безопасность типов входных параметров. Например, он может ограничить, какие пулы можно использовать в конвейере, предлагая перечисление возможных параметров, а не строку свободной формы.
# template.yml
parameters:
- name: userpool
type: string
default: Azure Pipelines
values:
- Azure Pipelines
- private-pool-1
- private-pool-2
pool: ${{ parameters.userpool }}
steps:
- script: # ... removed for clarity
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Настройка обязательных шаблонов
Чтобы требовать использования определенного шаблона, можно задать необходимые проверка шаблона для ресурса или среды. Требуемый шаблон проверка можно использовать при расширении из шаблона.
При просмотре задания конвейера можно проверка состояние проверка. Если конвейер не расширяется из шаблона require, проверка завершится сбоем и выполнение остановится. Вы увидите, что проверка завершилась сбоем.
При использовании необходимого шаблона вы увидите, что проверка пройдена.
Здесь требуется шаблон params.yml
с утверждением ресурса. Чтобы запустить сбой конвейера, закомментируйте ссылку на 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 }}
# azure-pipeline.yml
resources:
containers:
- container: my-container
endpoint: my-service-connection
image: mycontainerimages
extends:
template: params.yml
parameters:
yesNo: true
image: 'windows-latest'
Дополнительные действия
Шаблон может добавлять шаги, не добавляя их автору конвейера. Эти действия можно использовать для выполнения проверки учетных данных или статических проверок кода.
# template to insert a step before and after user steps in every job
parameters:
jobs: []
jobs:
- ${{ each job in parameters.jobs }}: # Each job
- ${{ each pair in job }}: # Insert all properties other than "steps"
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps: # Wrap the steps
- task: CredScan@1 # Pre steps
- ${{ job.steps }} # Users steps
- task: PublishMyTelemetry@1 # Post steps
condition: always()
Принудительное применение шаблона
Шаблон является механизмом безопасности только в том случае, если его можно применить. Контрольная точка для принудительного использования шаблонов является защищенным ресурсом. Вы можете настроить утверждения и проверки для пула агентов или других защищенных ресурсов, таких как репозитории. Пример см. в разделе Добавление ресурса репозитория проверка.
Дальнейшие действия
Далее вы узнаете о безопасном приеме входных данных с помощью переменных и параметров.
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по