Använda mallar för säkerhet
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Den här artikeln beskriver hur mallar kan effektivisera säkerheten för Azure Pipelines. Mallar kan definiera den yttre strukturen för din pipeline och hjälpa till att förhindra skadlig kodinfiltration. Mallar kan också automatiskt innehålla steg för att utföra uppgifter, till exempel genomsökning av autentiseringsuppgifter. Om flera pipelines i ditt team eller din organisation delar samma struktur bör du överväga att använda mallar.
Kontroller av skyddade resurser utgör det grundläggande säkerhetsramverket för Azure Pipelines. Dessa kontroller gäller oavsett pipelinestruktur, steg och jobb. Du kan använda mallar för att framtvinga dessa kontroller.
Innehåller och utökar mallar
Azure Pipelines innehåller och utökar mallar.
Innehåller mallar som innehåller mallens kod direkt i den yttre filen som refererar till
#include
den, ungefär som i C++. Följande exempelpipeline infogar mallen include-npm-steps.yml isteps
avsnittet.steps: - template: templates/include-npm-steps.yml
Utökar mallar definierar pipelinens yttre struktur och erbjuder specifika punkter för riktade anpassningar. I C++-
extends
kontexten liknar mallar arv.
När du använder extends
mallar kan du också använda includes
i både mallen och den slutliga pipelinen för att utföra vanliga konfigurationsdelar. En fullständig referens finns i mallanvändningsreferensen.
Utökar mallar
För de säkraste pipelines börjar du med att använda utökar mallar. Dessa mallar definierar pipelinens yttre struktur och förhindrar att skadlig kod infiltrerar pipelinen.
Följande mallfil heter till exempel template.yml.
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
Följande pipeline utökar mallen 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
Dricks
När du konfigurerar extends
mallar bör du överväga att förankra dem i en viss Git-gren eller tagg, så om det sker icke-bakåtkompatibla ändringar påverkas inte befintliga pipelines. I föregående exempel används den här funktionen.
Säkerhetsfunktioner för YAML-pipeline
YAML-pipelinesyntaxen innehåller flera inbyggda skydd. Utökar mallen kan framtvinga deras användning. För att förbättra pipelinesäkerheten kan du implementera någon av följande begränsningar.
Stegmål
Du kan begränsa vissa steg så att de körs i en container i stället för på värden. Steg i containrar har inte åtkomst till agentens värd, vilket förhindrar att dessa steg ändrar agentkonfigurationen eller lämnar skadlig kod för senare körning.
Överväg till exempel att begränsa nätverksåtkomsten. Utan öppen nätverksåtkomst kan användarsteg inte hämta paket från obehöriga källor eller ladda upp kod och hemligheter till externa nätverksplatser.
Följande exempelpipeline kör steg på agentvärden innan du kör steg i en container.
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
Kommandobegränsningar för agentloggning
Du kan begränsa de tjänster som Azure Pipelines-agenten tillhandahåller till användarsteg. Användarsteg begär tjänster med hjälp av loggningskommandon, som är särskilt formaterade strängar som skrivs ut till standardutdata. I begränsat läge är de flesta av agentens tjänster, till exempel att ladda upp artefakter och koppla testresultat, inte tillgängliga.
Följande exempelaktivitet misslyckas eftersom dess target
egenskap instruerar agenten att inte tillåta publicering av artefakter.
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
I restricted
läge förblir setvariable
kommandot tillåtet, så försiktighet är nödvändigt eftersom pipelinevariabler exporteras som miljövariabler till efterföljande uppgifter. Om uppgifter matar ut användarspecifika data, till exempel öppna problem som hämtats via ett REST-API, kan de vara sårbara för inmatningsattacker. Skadligt användarinnehåll kan ange miljövariabler som kan utnyttjas för att kompromettera agentvärden.
För att minska den här risken kan pipelineförfattare uttryckligen deklarera vilka variabler som kan anges med hjälp setvariable
av loggningskommandot. När du anger en tom lista tillåts inte alla variabelinställningar.
Följande exempelaktivitet misslyckas eftersom aktiviteten endast tillåts ange variabeln expectedVar
eller en variabel med prefixet ok
.
- task: PowerShell@2
target:
commands: restricted
settableVariables:
- expectedVar
- ok*
inputs:
targetType: 'inline'
script: |
Write-Host "##vso[task.setvariable variable=BadVar]myValue"
Villkorsstyrd fas eller jobbkörning
Du kan begränsa faser och jobb så att de endast körs under specifika förhållanden. I följande exempel säkerställer villkoret att begränsad kod endast skapas för huvudgrenen.
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
Syntaxändring
Azure Pipelines-mallar har flexibiliteten att iterera över och ändra YAML-syntax. Genom att använda iteration kan du framtvinga specifika YAML-säkerhetsfunktioner.
En mall kan också skriva om användarsteg, så att endast godkända uppgifter kan köras. Du kan till exempel förhindra körning av infogade skript.
Följande exempelmall förhindrar att stegtyperna bash
, powershell
, pwsh
och script
körs. För fullständig låsning av ad hoc-skript kan du även blockera BatchScript
och 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 }}'
I följande pipeline som utökar den här mallen tas skriptstegen bort och körs inte.
# 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
Typsäkra parametrar
Innan en pipeline körs omvandlas mallar och deras parametrar till konstanter. Mallparametrar kan förbättra typsäkerheten för indataparametrar.
I följande exempelmall begränsar parametrarna de tillgängliga alternativen för pipelinepooler genom att ange en uppräkning av specifika alternativ i stället för att tillåta frihandssträngar.
# 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
När pipelinen utökar mallen måste den ange ett av de tillgängliga poolalternativen.
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Mallsteg
En mall kan automatiskt inkludera steg i en pipeline. De här stegen kan utföra uppgifter som genomsökning av autentiseringsuppgifter eller statiska kodkontroller. Följande mall infogar steg före och efter användarstegen i varje jobb.
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()
Tillämpning av mallar
Mallar är en värdefull säkerhetsmekanism, men deras effektivitet är beroende av tillämpning. De viktigaste kontrollpunkterna för att framtvinga mallanvändning är skyddade resurser. Du kan konfigurera godkännanden och kontroller för din agentpool eller andra skyddade resurser, till exempel lagringsplatser. Ett exempel finns i Lägg till en resurskontroll för lagringsplats.
Nödvändiga mallar
Om du vill framtvinga användningen av en specifik mall konfigurerar du den nödvändiga mallkontrollen för en resurs. Den här kontrollen gäller endast när pipelinen sträcker sig från en mall.
När du visar pipelinejobbet kan du övervaka kontrollens status. Om pipelinen inte sträcker sig från den mall som krävs misslyckas kontrollen. Körningen stoppar och meddelar dig om den misslyckade kontrollen.
När du använder den mall som krävs godkänns kontrollen.
Följande params.yml mall måste refereras till i alla pipelines som utökar den.
# 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 }}
Följande exempelpipeline utökar mallen params.yml och kräver den för godkännande. Om du vill visa ett pipelinefel kommenterar du ut referensen till 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'