Seguridad mediante plantillas
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Las comprobaciones en los recursos protegidos son el bloque de creación básico de seguridad en Azure Pipelines. Las comprobaciones funcionan con independencia 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: inclusiones y extensiones.
Las plantillas incluidas se comportan como #include
en C++: como si pegara el código de la plantilla directamente en el archivo externo, que hace referencia a él. Por ejemplo, aquí una plantilla de inclusiones (include-npm-steps.yml
) se inserta en steps
.
steps:
- template: templates/include-npm-steps.yml
Para continuar con la metáfora de C++, las plantillas extends
son más parecidas a la herencia: la plantilla proporciona la estructura externa de la canalización y un conjunto de lugares donde el consumidor de la plantilla puede realizar modificaciones específicas.
Uso de plantillas de extensiones
En el caso de las canalizaciones más seguras, se recomienda empezar con plantillas extends
.
Al proporcionar la estructura externa, una plantilla puede impedir que el código malintencionado entre en la canalización.
De todos modos, podrá seguir usando includes
, tanto en la plantilla como en la canalización final, para factorizar partes comunes de la configuración.
Para usar una plantilla de extensiones, la canalización podría tener un aspecto similar al del 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 plantillas extends
, considere la posibilidad de anclarlas 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 mediante YAML
Hay varias protecciones integradas en la sintaxis YAML y una plantilla de extensión puede aplicar el uso de cualquiera o todos ellos.
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 de usuario no pueden modificar la configuración del agente ni dejar código malintencionado para su ejecución posterior. Ejecute el código en el host primero 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 o 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 de agentes
Restrinja los servicios que proporcionará el agente de Azure Pipelines a los pasos del usuario. Los pasos solicitan servicios mediante "comandos de registro" (cadenas con formato especial impresas en stdout). En el modo restringido, la mayoría de los servicios del agente, como cargar artefactos y asociar 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 todavía permitidos en modo restringido es setvariable
. Dado que las variables de canalización se exportan como variables de entorno a tareas posteriores, las tareas que generan datos proporcionados por el usuario (por ejemplo, el contenido de 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 evitar esto, los autores de canalizaciones pueden declarar explícitamente qué variables se pueden establecer a través del comando de registro setvariable
. Especificar una lista vacía no 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 asegurarse de que solo compila 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
Exigencia de cierta sintaxis con plantillas de extensiones
Las plantillas pueden recorrer en iteración cualquier sintaxis YAML y modificarla o rechazarla. La iteración puede forzar el uso de una sintaxis YAML determinada, incluidas las características anteriores.
Una plantilla puede volver a escribir pasos de usuario y permitir que solo se ejecuten determinadas tareas aprobadas. Por ejemplo, puede evitar la ejecución de scripts insertados.
Advertencia
En el ejemplo siguiente, se impide que se ejecuten los pasos "bash", "powershell", "pwsh" y "script". Para el bloqueo completo de scripts ad hoc, también tendría que bloquear "BatchScript" y "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
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, se puede restringir qué grupos se pueden usar en una canalización ofreciendo una enumeración de posibles opciones en lugar de una cadena de formato 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
Establecimiento de las plantillas necesarias
Para exigir que se use una plantilla específica, puede establecer la comprobación de plantilla necesaria para un recurso o entorno. La comprobación de la plantilla necesaria se puede usar al realizar extensiones 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 necesaria, se producirá un error en la comprobación y la ejecución se detendrá. Verá que se produjo un error en la comprobación.
Cuando se use la plantilla necesaria, verá que se ha superado la comprobación.
Aquí se requiere la plantilla params.yml
con una aprobación en el recurso. Para desencadenar un error en la canalización, convierta en comentario 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()
Aplicación de plantillas
Una plantilla es solo un mecanismo de seguridad si puede aplicarla. El punto de control para aplicar el uso de plantillas es un recurso protegido. Puede configurar aprobaciones y comprobaciones en el grupo de agentes u otros recursos protegidos, como repositorios. Para ver un ejemplo, consulte Adición de una comprobación de recursos de repositorio.
Pasos siguientes
A continuación, aprenda a tomar entradas de forma segura mediante variables y parámetros.
Comentaris
https://aka.ms/ContentUserFeedback.
Properament: al llarg del 2024 eliminarem gradualment GitHub Issues com a mecanisme de retroalimentació del contingut i el substituirem per un nou sistema de retroalimentació. Per obtenir més informació, consulteu:Envieu i consulteu els comentaris de