Použití šablon pro zabezpečení
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
Tento článek popisuje, jak šablony můžou zjednodušit zabezpečení pro Azure Pipelines. Šablony můžou definovat vnější strukturu kanálu a pomáhají zabránit infiltraci škodlivého kódu. Šablony můžou také automaticky zahrnovat kroky pro úlohy, jako je kontrola přihlašovacích údajů. Pokud několik kanálů v rámci vašeho týmu nebo organizace sdílí stejnou strukturu, zvažte použití šablon.
Kontroly chráněných prostředků tvoří základní architekturu zabezpečení pro Azure Pipelines. Tyto kontroly platí bez ohledu na strukturu kanálu, fáze a úlohy. Tyto kontroly můžete vynutit pomocí šablon.
Zahrnuje a rozšiřuje šablony.
Azure Pipelines poskytuje zahrnutí a rozšíření šablon.
Obsahuje šablony, které obsahují kód šablony přímo do vnějšího souboru, který na ni odkazuje, podobně jako
#include
v jazyce C++. Následující příklad kanálu vloží šablonu include-npm-steps.yml do oddílusteps
.steps: - template: templates/include-npm-steps.yml
Rozšiřuje šablony definují vnější strukturu kanálu a nabízejí specifické 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
šablonu i konečný kanál k provedení běžných částí konfigurace. Úplný odkaz najdete v referenčních informacích k použití šablony.
Rozšiřuje šablony
Pro nejbezpečnější kanály začněte použitím rozšiřujících šablon. Tyto šablony definují vnější strukturu kanálu a brání škodlivému kódu v infiltrování kanálu.
Například následující soubor šablony má název template.yml.
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
Následující 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
Tip
Když nastavíte extends
šablony, zvažte jejich ukotvení na konkrétní větev Gitu nebo značku, takže pokud dojde k zásadním změnám, stávající kanály to neovlivní. Předchozí příklad používá tuto funkci.
Funkce zabezpečení kanálů YAML
Syntaxe kanálu YAML zahrnuje několik předdefinovaných ochrany. Rozšíření šablony může vynutit jejich použití. Pokud chcete zvýšit zabezpečení kanálu, můžete implementovat některá z následujících omezení.
Cíle kroku
Určité kroky můžete omezit tak, aby se spouštěly v kontejneru, nikoli v hostiteli. Kroky v kontejnerech nemají přístup k hostiteli agenta, což brání těmto krokům v úpravě konfigurace agenta nebo ponechání škodlivého kódu pro pozdější spuštění.
Zvažte například omezení síťového přístupu. Bez otevřeného síťového přístupu nemůžou kroky uživatelů načítat balíčky z neautorizovaných zdrojů ani nahrávat kód a tajné kódy do externích síťových umístění.
Následující příklad kanálu spustí kroky na hostiteli agenta před spuštěním kroků uvnitř kontejneru.
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
Omezení příkazů protokolování agenta
Služby, které agent Azure Pipelines poskytuje, můžete omezit na kroky uživatelů. Uživatelské kroky požadují služby pomocí příkazů protokolování, které jsou speciálně formátované řetězce vytištěné do standardního výstupu. V omezeném režimu není většina služeb agenta, jako je nahrání artefaktů a připojení výsledků testu, nedostupná.
Následující příklad úlohy selže, protože jeho target
vlastnost dává agent pokyn, aby nepovolil publikování artefaktů.
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
V restricted
režimu setvariable
zůstává příkaz povolený, proto je potřeba opatrnost, protože proměnné kanálu se exportují jako proměnné prostředí do následných úloh. Pokud úkoly vypíše data poskytovaná uživatelem, jako jsou otevřené problémy načtené přes rozhraní REST API, můžou být ohrožené útoky prostřednictvím injektáže. Škodlivý uživatelský obsah může nastavit proměnné prostředí, které by mohly být zneužity k ohrožení hostitele agenta.
Aby se toto riziko omezilo, můžou autoři kanálů explicitně deklarovat, které proměnné jsou nastaveny pomocí setvariable
příkazu protokolování. Když zadáte prázdný seznam, nastavení všech proměnných se nepovolí.
Následující příklad úkol selže, protože úkol je povolen pouze nastavit expectedVar
proměnnou nebo proměnnou s předponou ok
.
- 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. V následujícím příkladu podmínka zajistí, že se omezený kód sestaví pouze pro hlavní větev.
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. Můžete například zabránit spuštění vloženého skriptu.
Následující příklad šablony zabraňuje spuštění typů bash
kroků , powershell
pwsh
, a script
spuštění. K úplnému uzamčení ad hoc 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 kanálu, který tuto šablonu rozšiřuje, se kroky skriptu odstraní a nespustí.
# 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
Parametry bezpečného typu
Před spuštěním kanálu se šablony a jejich parametry transformují na konstanty. Parametry šablony mohou zvýšit bezpečnost typů pro vstupní parametry.
V následující ukázkové šabloně parametry omezují dostupné možnosti fondu kanálů tím, že poskytují výčet konkrétních voleb místo povolení volných řetězců.
# 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
Když kanál rozšíří šablonu, musí zadat jednu z dostupných možností fondu.
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Kroky šablony
Šablona může automaticky zahrnovat kroky v kanálu. Tyto kroky můžou provádět úlohy, jako je kontrola přihlašovacích údajů nebo kontrola statického 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
Šablony jsou cenným mechanismem zabezpečení, ale jejich efektivita spoléhá na vynucování. Klíčové kontrolní body pro vynucování použití šablony jsou chráněné prostředky. Můžete nakonfigurovat schválení a kontroly fondu agentů nebo jiných chráněných prostředků, jako jsou úložiště. Příklad najdete v tématu Přidání kontroly prostředku úložiště.
Požadované šablony
Pokud chcete vynutit použití konkrétní šablony, nakonfigurujte požadovanou kontrolu prostředku. 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ří. Spuštění se zastaví a upozorní vás na neúspěšnou kontrolu.
Když použijete požadovanou šablonu, projde kontrola.
Na následující šablonu params.yml se musí odkazovat v jakémkoli kanálu, 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 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'