Dela via


Mallar för säkerhet

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020

Med Azure Pipelines-mallar kan du definiera återanvändbart innehåll, logik och parametrar i YAML-pipelines. Den här artikeln beskriver hur mallar kan förbättra pipelinesäkerheten genom att:

  • Definiera den yttre strukturen för en pipeline för att förhindra infiltrering av skadlig kod.
  • Inkludera automatiskt steg för att utföra uppgifter, till exempel genomsökning av autentiseringsuppgifter.
  • Hjälpa till att framtvinga kontroller av skyddade resurser, som utgör det grundläggande säkerhetsramverket för Azure Pipelines och gäller för alla pipelinestrukturer och komponenter.

Den här artikeln är en del av en serie som hjälper dig att implementera säkerhetsåtgärder för Azure Pipelines. Mer information finns i Skydda Azure Pipelines.

Förutsättningar

Kategori Krav
Azure DevOps – Implementera rekommendationerna i Gör dina Azure DevOps säkra och Gör dina Azure Pipelines säkra.
– Grundläggande kunskaper om YAML och Azure Pipelines. Mer information finns i Skapa din första pipeline.
behörigheter – Ändra pipelinebehörigheter: Medlem i gruppen Projektadministratörer.
– Ändra organisationsbehörigheter: Medlem i gruppen Projektsamlingsadministratörer.

Innehåller och utökar mallar

Azure Pipelines innehåller och utökar mallar.

  • En includes mall innehåller mallens kod direkt i den yttre filen som refererar till #include mallen, ungefär som i C++. Följande exempelpipeline infogar mallen include-npm-steps.yml i steps avsnittet.

      steps:
      - template: templates/include-npm-steps.yml 
    
  • En extends mall 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 för att utföra vanliga konfigurationsdelar i både mallen och den slutliga pipelinen. Mer information finns i Använda YAML-mallar i pipelines för återanvändbara och säkra processer.

Utökar mallar

Börja med att använda extends mallar för de säkraste pipelines. Dessa mallar definierar den yttre strukturen för pipelinen och hjälper till att förhindra skadlig kodinfiltration.

I följande exempel visas en mallfil med namnet template.yml.

parameters:
- name: usersteps
  type: stepList
  default: []
steps:
- ${{ each step in parameters.usersteps }}:
  - ${{ step }}

Följande exempelpipeline bygger vidare på template.yml-mallen.

# 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å att eventuella icke-bakåtkompatibla ändringar inte påverkar befintliga pipelines. I föregående exempel används den här funktionen.

Säkerhetsfunktioner för pipelinesystem

YAML-pipelinesyntax innehåller flera inbyggda skydd. Extends mallar kan framtvinga deras användning för att förbättra pipelinesäkerheten. Du kan implementera någon av följande begränsningar.

Stegmål

Du kan begränsa att angivna steg körs i en container i stället för på värden. Steg i containrar kan inte komma åt agentens värd, så de kan inte ändra agentkonfigurationen eller lämna skadlig kod för att utföra senare körning.

Du kan till exempel köra användarsteg i en container för att hindra dem från att komma åt nätverket, så att de inte kan hämta paket från obehöriga källor eller ladda upp kod och hemligheter till externa platser.

Följande exempelpipeline kör ett steg på agentvärden som potentiellt kan ändra värdnätverket, följt av ett steg i en container som begränsar nätverksåtkomsten.

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

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 räkna upp specifika alternativ i stället för att tillåta valfri sträng.

# 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

Om du vill utöka mallen måste pipelinen ange något av de tillgängliga poolalternativen.

# azure-pipelines.yml
extends:
  template: template.yml
  parameters:
    userpool: private-pool-1

Kommandobegränsningar för agentloggning

Användarsteg begär tjänster med hjälp av loggningskommandon, som är särskilt formaterade strängar som skrivs ut till standardutdata. Du kan begränsa de tjänster som loggningskommandon tillhandahåller för användarsteg. I restricted läget är de flesta agenttjänster som att ladda upp artefakter och koppla testresultat inte tillgängliga för loggningskommandon.

I följande exempel instruerar egenskapen target agenten att begränsa publiceringen av artefakter, så att artefaktpubliceringsuppgiften misslyckas.

- task: PublishBuildArtifacts@1
  inputs:
    artifactName: myartifacts
  target:
    commands: restricted

Variabler i loggningskommandon

Kommandot setvariable är fortfarande tillåtet i restricted läge, så uppgifter som matar ut användarangivna data, till exempel öppna ärenden som hämtats via ett REST-API, kan vara sårbara för injekteringsattacker. Skadligt användarinnehåll kan ange variabler som exporteras som miljövariabler till efterföljande uppgifter och kan kompromettera agentvärden.

För att minska den här risken kan du uttryckligen deklarera de variabler som kan anges med hjälp setvariable av loggningskommandot. Om du anger en tom lista i settableVariablestillåts inte alla variabelinställningar.

I följande exempel begränsas settableVariables till expectedVar och alla variabelprefix med ok. Aktiviteten misslyckas eftersom den försöker ange en annan variabel med namnet BadVar.

- 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 ser du till att begränsad kod endast skapas för grenen 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

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. Mallen kan till exempel förhindra körning av inbäddade skript.

Följande exempelmall förhindrar att skriptstegstyperna bash, powershell, pwshoch script körs. För fullständig låsning av 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 exempelpipeline som utökar föregående mall tas skriptstegen bort och körs inte.

# 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

Mallsteg

En mall kan automatiskt inkludera steg i en pipeline, till exempel att göra 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

Mallarnas effektivitet som en säkerhetsmekanism ä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

För att framtvinga användningen av en specifik mall konfigurerar du kontrollen för nödvändig mall på tjänstanslutningen 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.

Skärmbild som visar en misslyckad godkännandekontroll.

När du använder den mall som krävs godkänns kontrollen.

Skärmbild som visar en godkänd godkännandekontroll.

Följande params.yml mall måste till exempel 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 extends 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'