Šablony pro zabezpečení

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

Šablony Azure Pipelines umožňují definovat opakovaně použitelný obsah, logiku a parametry v kanálech YAML. Tento článek popisuje, jak šablony můžou pomoct vylepšit zabezpečení kanálů:

  • Definování vnější struktury kanálu, která pomáhá zabránit infiltraci škodlivého kódu.
  • Automatické zahrnutí kroků k úkolům, jako je kontrola přihlašovacích údajů.
  • Pomáhá vynucovat kontroly chráněných prostředků, které tvoří základní architekturu zabezpečení pro Azure Pipelines a vztahují se na všechny struktury a komponenty kanálů.

Tento článek je součástí série, která vám pomůže implementovat bezpečnostní opatření pro Azure Pipelines. Další informace najdete v tématu Zabezpečení služby Azure Pipelines.

Požadavky

Kategorie Požadavky
Azure DevOps – Implementujte doporučení v Make your Azure DevOps secure a Secure Azure Pipelines.
– Základní znalost YAML a Azure Pipelines. Další informace najdete v části Vytvoření prvního pipeline.
Oprávnění - Úprava oprávnění kanálů: Člen skupiny Správci projektu.
- Úprava oprávnění organizace: Člen skupiny Správci kolekce projektů.

Zahrnuje a rozšiřuje šablony.

Azure Pipelines poskytuje vkládací a rozšiřující šablony.

  • Šablona includes obsahuje kód šablony přímo ve vnějším souboru, který odkazuje na šablonu, podobně jako #include v jazyce C++. Následující příklad potrubí vloží šablonu include-npm-steps.yml do oddílu steps.

      steps:
      - template: templates/include-npm-steps.yml 
    
  • Šablona extends definuje vnější strukturu kanálu a nabízí konkrétní body pro cílené přizpůsobení. V kontextu jazyka C++ extends se šablony podobají dědičnosti.

Když používáte extends šablony, můžete také použít includes pro provádění běžných konfiguračních částí jak v šabloně, tak ve finálním pipeline. Další informace najdete v tématu Použití šablon YAML v kanálech pro opakovaně použitelné a zabezpečené procesy.

Rozšiřuje šablony

Pro nejbezpečnější kanály začněte používat extends šablony. Tyto šablony definují vnější strukturu kanálu a pomáhají zabránit infiltraci škodlivého kódu.

Následující příklad ukazuje soubor šablony s názvem template.yml.

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

Následující ukázkový kanál rozšiřuje šablonu 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

Návod

Když nastavíte extends šablony, zvažte jejich ukotvení na konkrétní větev Gitu nebo značku, takže všechny zásadní změny neovlivní stávající kanály. Předchozí příklad používá tuto funkci.

Funkce zabezpečení kanálu

Syntaxe pipeline YAML zahrnuje několik předdefinovaných ochran. Extends šablony mohou vynutit jejich použití k vylepšení zabezpečení potrubí. Můžete implementovat některá z následujících omezení.

Cíle kroku

Zadané kroky můžete omezit tak, aby se spouštěly v kontejneru, nikoli v hostiteli. Kroky v kontejnerech nemají přístup k hostiteli agenta, takže nemůžou upravit konfiguraci agenta nebo nechat škodlivý kód pro pozdější spuštění.

Můžete například spustit kroky uživatele v kontejneru, abyste jim zabránili v přístupu k síti, aby nemohli načítat balíčky z neautorizovaných zdrojů nebo nahrávat kód a tajné kódy do externích umístění.

Následující ukázkové potrubí spustí krok na hostiteli agenta, který by mohl potenciálně změnit síť hostitele, následovaný krokem uvnitř kontejneru, který omezuje síťový přístup.

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

Parametry bezpečného typu

Před spuštěním potrubí se šablony a jejich parametry transformují do konstantních hodnot. Parametry šablony mohou zvýšit bezpečnost typů pro vstupní parametry.

V následující ukázkové šabloně parametry omezují dostupné možnosti kanálového fondu tím, že uvádějí konkrétní volby místo povolení jakéhokoli řetězce.

# 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

Aby bylo možné šablonu rozšířit, musí pipeline zadat jednu z dostupných možností fondu.

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

Omezení příkazů protokolování agenta

Uživatelé požadují služby pomocí příkazů protokolování, které jsou speciálně formátované řetězce odeslané na standardní výstup. Můžete omezit služby, které příkazy protokolování poskytují pro kroky uživatele. V restricted režimu není většina služeb agentů, jako je nahrávání artefaktů a připojení výsledků testů, k dispozici pro protokolování příkazů.

V následujícím příkladu vlastnost target obsahuje instrukce pro agenta, aby omezil publikování artefaktů, takže úloha publikace artefaktů selže.

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

Proměnné v příkazech protokolování

Příkaz setvariable zůstává povolený v režimu restricted, takže úlohy, které vypisují data poskytovaná uživatelem, jako jsou otevřené problémy načtené přes rozhraní REST API, mohou být ohroženy útoky injektáží. Škodlivý uživatelský obsah by mohl nastavit proměnné, které se exportují do následných úloh jako proměnných prostředí a mohly by ohrozit hostitele agenta.

Pokud chcete toto riziko zmírnit, můžete explicitně deklarovat proměnné, které jsou nastavené pomocí setvariable příkazu protokolování. Pokud zadáte prázdný seznam v settableVariables, není povoleno nastavení žádných proměnných.

Následující příklad omezuje settableVariables na expectedVar a libovolnou proměnnou s předponou ok. Úkol selže, protože se pokusí nastavit jinou proměnnou s názvem BadVar.

- task: PowerShell@2
  target:
    commands: restricted
    settableVariables:
    - expectedVar
    - ok*
  inputs:
    targetType: 'inline'
    script: |
      Write-Host "##vso[task.setvariable variable=BadVar]myValue"

Podmíněná fáze nebo spuštění úlohy

Fáze a úlohy můžete omezit tak, aby běžely pouze za určitých podmínek. Následující příklad zajišťuje, že kód se sestavuje pouze pro větev 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

Úprava syntaxe

Šablony Azure Pipelines mají flexibilitu iterovat a upravovat syntaxi YAML. Pomocí iterace můžete vynutit konkrétní funkce zabezpečení YAML.

Šablona může také přepsat kroky uživatele, což umožňuje spouštět jenom schválené úkoly. Šablona může například zabránit spuštění vloženého skriptu.

Následující příklad šablony zabraňuje spuštění typů kroků skriptu bash, powershell, pwsh a script. Pro úplné uzamčení skriptů můžete také blokovat BatchScript a 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 }}'

V následujícím ukázkovém pipeline, který rozšiřuje předchozí šablonu, se scriptové kroky odstraní a nespustí.

# 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

Kroky šablony

Šablona může automaticky zahrnovat kroky v potrubí, například provádět skenování přihlašovacích údajů nebo statickou kontrolu kódu. Následující šablona vloží kroky před a za kroky uživatele v každé úloze.

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

Vynucení šablony

Efektivita šablon jako mechanismu zabezpečení závisí na vynucování. Klíčové body kontroly pro prosazování použití šablon jsou chráněné prostředky.

Můžete nastavit schválení a kontroly pro fond agentů nebo jiné chráněné prostředky, jako jsou úložiště. Jako příklad viz Přidání kontroly zdroje úložiště.

Požadované šablony

Pokud chcete vynutit použití konkrétní šablony, nakonfigurujte požadovanou kontrolu připojení služby pro prostředek. Tato kontrola platí pouze v případě, že kanál rozšiřuje šablonu.

Když zobrazíte úlohu kanálu, můžete monitorovat stav kontroly. Pokud kanál nepochází z požadované šablony, kontrola se nezdaří.

Snímek obrazovky znázorňující neúspěšnou kontrolu schválení

Když použijete požadovanou šablonu, projde kontrola.

Snímek obrazovky znázorňující úspěšnou kontrolu schválení

Například následující šablona params.yml musí být odkazována v jakémkoli potrubí, které ji rozšiřuje.

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

Následující ukázkový kanál rozšiřuje šablonu params.yml a vyžaduje ji ke schválení. Pokud chcete předvést selhání kanálu, zakomentujte extends odkaz na 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'