Beveiliging via sjablonen

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

Controles van beveiligde resources vormen de basisbouwsteen van beveiliging voor Azure Pipelines. Controles werken ongeacht de structuur (de fasen en taken) van uw pijplijn. Als verschillende pijplijnen in uw team of organisatie dezelfde structuur hebben, kunt u de beveiliging verder vereenvoudigen met behulp van sjablonen.

Azure Pipelines biedt twee soorten sjablonen: omvat en breidt uit. Opgenomen sjablonen gedragen zich als #include in C++: het is alsof u de code van de sjabloon rechtstreeks in het buitenste bestand plakt, dat ernaar verwijst. Hier wordt bijvoorbeeld een includes-sjabloon (include-npm-steps.yml) ingevoegd in steps.

  steps:
  - template: templates/include-npm-steps.yml 

Om de C++-metafoor voort te zetten, extends lijken sjablonen meer op overname: de sjabloon biedt de buitenste structuur van de pijplijn en een set plaatsen waar de gebruiker van de sjabloon gerichte wijzigingen kan aanbrengen.

Uitbreidingssjablonen gebruiken

Voor de veiligste pijplijnen raden we u aan te beginnen met extends sjablonen. Door de buitenste structuur op te geven, kan een sjabloon voorkomen dat schadelijke code in uw pijplijn komt. U kunt nog steeds , zowel in de sjabloon als in de uiteindelijke pijplijn, gebruiken includesom algemene configuratieonderdelen te voorkomen. Als u een uitbreidingssjabloon wilt gebruiken, ziet uw pijplijn er mogelijk uit zoals in het onderstaande voorbeeld.

# 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

Wanneer u sjablonen instelt extends , kunt u overwegen deze te verankeren aan een bepaalde Git-vertakking of -tag. Op die manier worden bestaande pijplijnen niet beïnvloed als er wijzigingen moeten worden aangebracht die fouten veroorzaken. In de bovenstaande voorbeelden wordt deze functie gebruikt.

Beveiligingsfuncties afgedwongen via YAML

Er zijn verschillende beveiligingen ingebouwd in de YAML-syntaxis en met een uitbreidingssjabloon kan het gebruik van een of elk ervan worden afgedwongen.

Stapdoelen

Beperk het uitvoeren van bepaalde stappen in een container in plaats van de host. Zonder toegang tot de host van de agent kunnen gebruikersstappen de configuratie van de agent niet wijzigen of schadelijke code achterlaten voor latere uitvoering. Voer eerst code uit op de host om de container veiliger te maken. We raden u bijvoorbeeld aan de toegang tot het netwerk te beperken. Zonder open toegang tot het netwerk hebben gebruikersstappen geen toegang tot pakketten van niet-geautoriseerde bronnen en kunnen ze geen code en geheimen uploaden naar een netwerklocatie.

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

Opdrachtbeperkingen voor agentlogboekregistratie

Beperk de services die de Azure Pipelines-agent biedt aan gebruikersstappen. Stappen vragen services aan met behulp van 'logboekregistratieopdrachten' (speciaal opgemaakte tekenreeksen die worden afgedrukt op stdout). In de beperkte modus zijn de meeste services van de agent, zoals het uploaden van artefacten en het toevoegen van testresultaten, niet beschikbaar.

# 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

Een van de opdrachten die nog steeds zijn toegestaan in de beperkte modus, is de setvariable opdracht. Omdat pijplijnvariabelen worden geëxporteerd als omgevingsvariabelen naar volgende taken, kunnen taken die door de gebruiker verstrekte gegevens uitvoeren (bijvoorbeeld de inhoud van openstaande problemen die zijn opgehaald uit een REST API) kwetsbaar zijn voor injectieaanvallen. Dergelijke gebruikersinhoud kan omgevingsvariabelen instellen die op hun beurt kunnen worden gebruikt om de agenthost te misbruiken. Als u dit wilt weigeren, kunnen pijplijnauteurs expliciet declareren welke variabelen zijn ingesteld via de setvariable opdracht logboekregistratie. Als u een lege lijst opgeeft, staat het instellen van alle variabelen niet toe.

# 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"

Voorwaardelijke invoeging van fasen of taken

Beperk fasen en taken om onder specifieke omstandigheden te worden uitgevoerd. Voorwaarden kunnen bijvoorbeeld helpen om ervoor te zorgen dat u alleen bepaalde vertakkingen bouwt.

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

Bepaalde syntaxis vereisen met uitbreidingssjablonen

Sjablonen kunnen elke YAML-syntaxis herhalen en wijzigen/weigeren. Iteratie kan het gebruik van een bepaalde YAML-syntaxis afdwingen, inclusief de bovenstaande functies.

Met een sjabloon kunnen gebruikersstappen worden herschreven en kunnen alleen bepaalde goedgekeurde taken worden uitgevoerd. U kunt bijvoorbeeld de uitvoering van inlinescripts voorkomen.

Waarschuwing

In het onderstaande voorbeeld kunnen de stappen 'bash', 'powershell', 'pwsh' en 'script' niet worden uitgevoerd. Voor volledige vergrendeling van ad-hocscripts moet u ook 'BatchScript' en 'ShellScript' blokkeren.

# 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

Typeveilige parameters

Sjablonen en hun parameters worden omgezet in constanten voordat de pijplijn wordt uitgevoerd. Sjabloonparameters bieden typeveiligheid voor invoerparameters. Het kan bijvoorbeeld beperken welke pools in een pijplijn kunnen worden gebruikt door een opsomming van mogelijke opties aan te bieden in plaats van een vrije-vormtekenreeks.

# 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

Vereiste sjablonen instellen

Als u wilt vereisen dat een specifieke sjabloon wordt gebruikt, kunt u de vereiste sjablooncontrole instellen voor een resource of omgeving. De vereiste sjablooncontrole kan worden gebruikt bij het uitbreiden vanuit een sjabloon.

U kunt de status van een controle controleren wanneer u een pijplijntaak bekijkt. Wanneer een pijplijn niet wordt uitgebreid vanaf de vereiste sjabloon, mislukt de controle en wordt de uitvoering gestopt. U ziet dat de controle is mislukt.

goedkeuringscontrole mislukt

Wanneer de vereiste sjabloon wordt gebruikt, ziet u dat de controle is geslaagd.

goedkeuringscontrolepassen

Hier is de sjabloon params.yml vereist met een goedkeuring voor de resource. Als u wilt dat de pijplijn mislukt, markeert u de verwijzing naar 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'

Aanvullende stappen

Een sjabloon kan stappen toevoegen zonder dat de auteur van de pijplijn deze hoeft op te nemen. Deze stappen kunnen worden gebruikt om referenties te scannen of statische codecontroles uit te voeren.

# 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()

Sjabloon afdwingen

Een sjabloon is alleen een beveiligingsmechanisme als u deze kunt afdwingen. Het controlepunt voor het afdwingen van het gebruik van sjablonen is een beveiligde resource. U kunt goedkeuringen en controles configureren voor uw agentgroep of andere beveiligde resources, zoals opslagplaatsen. Zie Een opslagplaatsresourcecontrole toevoegen voor een voorbeeld.

Volgende stappen

Vervolgens leert u hoe u invoer veilig kunt gebruiken via variabelen en parameters.