Seguridad mediante plantillas
Las comprobaciones en los recursos protegidos son el bloque de creación básico de seguridad para Azure Pipelines. Comprueba el trabajo independientemente de la estructura (las fases y los trabajos) de la canalización. Si varias canalizaciones de su equipo u organización tienen la misma estructura, puede simplificar aún más la seguridad mediante plantillas.
Azure Pipelines ofrece dos tipos de plantillas: incluyey extiende.
Las plantillas incluidas se comportan como en C++: es como si pegara el código de la plantilla directamente en el archivo externo, que #include hace referencia a él.
Para continuar con la metáfora de C++, las plantillas son más como herencia: la plantilla proporciona la estructura externa de la canalización y un conjunto de lugares donde el consumidor de plantillas puede realizar modificaciones extends dirigidas.
Uso de plantillas de extensión
Para las canalizaciones más seguras, se recomienda empezar con extends plantillas.
Al proporcionar la estructura externa, una plantilla puede impedir que el código malintencionado entre en la canalización.
Todavía puede usar , tanto en la plantilla como en la canalización includes final, para factorizaciones comunes de configuración.
Para usar una plantilla de extensión, la canalización podría ser como en el ejemplo siguiente.
# 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
Al configurar extends plantillas, considere la posibilidad de delimitarlos a una rama o etiqueta de Git determinada.
De este modo, si es necesario realizar cambios importantes, las canalizaciones existentes no se verán afectadas.
En los ejemplos anteriores se usa esta característica.
Características de seguridad aplicadas a través de YAML
Hay varias protecciones integradas en la sintaxis de YAML y una plantilla de extensión puede exigir el uso de cualquiera de ellas o de todas ellas.
Destinos de paso
Restrinja algunos pasos para que se ejecuten en un contenedor en lugar del host. Sin acceso al host del agente, los pasos del usuario no pueden modificar la configuración del agente ni dejar código malintencionado para su posterior ejecución. Ejecute primero código en el host para que el contenedor sea más seguro. Por ejemplo, se recomienda limitar el acceso a la red. Sin acceso abierto a la red, los pasos del usuario no podrán acceder a paquetes de orígenes no autorizados ni cargar código y secretos en una ubicación de red.
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
Restricciones de comandos de registro del agente
Restrinja qué servicios proporcionará Azure Pipelines agente a los pasos del usuario. Los pasos solicitan servicios mediante "comandos de registro" (cadenas con formato especial impresas en stdout). En modo restringido, la mayoría de los servicios del agente, como la carga de artefactos y la asociación de resultados de pruebas, no están disponibles.
# 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
Uno de los comandos que todavía se permiten en modo restringido es el setvariable comando . Dado que las variables de canalización se exportan como variables de entorno a tareas posteriores, las tareas que proporcionan datos proporcionados por el usuario (por ejemplo, el contenido de los problemas abiertos recuperados de una API REST) pueden ser vulnerables a ataques por inyección. Este contenido de usuario puede establecer variables de entorno que, a su vez, se pueden usar para aprovechar el host del agente. Para no permitir esto, los autores de canalizaciones pueden declarar explícitamente qué variables se pueden establecer mediante el setvariable comando de registro. Al especificar una lista vacía no se permite establecer todas las variables.
# 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"
Inserción condicional de fases o trabajos
Restrinja las fases y los trabajos para que se ejecuten en condiciones específicas. Las condiciones pueden ayudar, por ejemplo, a garantizar que solo se están creando determinadas ramas.
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
Requerir cierta sintaxis con plantillas de extensión
Las plantillas pueden iterar y modificar o no cualquier sintaxis YAML. La iteración puede forzar el uso de una sintaxis YAML determinada, incluidas las características anteriores.
Una plantilla puede volver a escribir los pasos del usuario y solo permitir que se ejecuten determinadas tareas aprobadas. Por ejemplo, puede evitar la ejecución de scripts en línea.
Advertencia
En el ejemplo siguiente, solo se impide el tipo de paso literal "script". Para el bloqueo completo de scripts ad hoc, también debe bloquear "bash", "pwsh", "powershell" y las tareas que admiten estos pasos.
# template.yml
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ each pair in step }}:
${{ if ne(pair.key, 'script') }}:
${{ pair.key }}: ${{ pair.value }}
# azure-pipelines.yml
extends:
template: template.yml
parameters:
usersteps:
- task: MyTask@1
- script: echo This step will be stripped out and not run!
- task: MyOtherTask@2
Parámetros con seguridad de tipos
Las plantillas y sus parámetros se convierten en constantes antes de que se ejecute la canalización. Los parámetros de plantilla proporcionan seguridad de tipos a los parámetros de entrada. Por ejemplo, puede restringir qué grupos se pueden usar en una canalización al ofrecer una enumeración de opciones posibles en lugar de una cadena de forma libre.
# 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
Establecer las plantillas necesarias
Para requerir que se utilice una plantilla específica, puede establecer la comprobación de plantilla necesaria para un recurso o entorno. La comprobación de plantilla necesaria se puede usar al extender desde una plantilla.
Puede comprobar el estado de una comprobación al ver un trabajo de canalización. Cuando una canalización no se extiende desde la plantilla require, se producirá un error en la comprobación y se detendrá la ejecución. Verá que la comprobación no se pudo realizar.

Cuando se usa la plantilla necesaria, verá que se ha superado la comprobación.

Aquí se requiere params.yml la plantilla con una aprobación en el recurso. Para desencadenar un error en la canalización, comente la referencia a 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'
Pasos adicionales
Una plantilla puede agregar pasos sin que el autor de la canalización tenga que incluirlos. Estos pasos se pueden usar para ejecutar el examen de credenciales o comprobaciones de código estático.
# 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()
Pasos siguientes
A continuación, obtenga información sobre cómo tomar entradas de forma segura a través de variables y parámetros.