Verwenden von Vorlagen zur Sicherheit
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
In diesem Artikel wird beschrieben, wie Vorlagen die Sicherheit für Azure-Pipelines optimieren können. Vorlagen können die äußere Struktur Ihrer Pipeline definieren und bösartigen Code infiltration verhindern. Vorlagen können auch automatisch Schritte zum Ausführen von Aufgaben wie der Überprüfung von Anmeldeinformationen enthalten. Wenn mehrere Pipelines innerhalb Ihres Teams oder Ihrer Organisation dieselbe Struktur gemeinsam nutzen, sollten Sie Vorlagen verwenden.
Prüfungen auf geschützte Ressourcen bilden das grundlegende Sicherheitsframework für Azure-Pipelines. Diese Prüfungen gelten unabhängig von Pipelinestruktur, Phasen und Aufträgen. Sie können Vorlagen verwenden, um diese Prüfungen zu erzwingen.
Enthält und erweitert Vorlagen
Azure-Pipelines enthält und erweitert Vorlagen.
Enthält Vorlagen, die den Code der Vorlage direkt in der äußeren Datei enthalten, die darauf verweist, ähnlich
#include
wie in C++. Die folgende Beispielpipeline fügt die include-npm-steps.yml Vorlage in densteps
Abschnitt ein.steps: - template: templates/include-npm-steps.yml
Erweitert Vorlagen definieren die äußere Struktur der Pipeline und bieten spezifische Punkte für gezielte Anpassungen. Im Kontext von C++
extends
ähneln Vorlagen der Vererbung.
Wenn Sie Vorlagen verwenden extends
, können Sie auch sowohl in der Vorlage als auch includes
in der endgültigen Pipeline verwenden, um allgemeine Konfigurationselemente zu erledigen. Eine vollständige Referenz finden Sie in der Vorlagenverwendungsreferenz.
Erweitert Vorlagen
Für die sichersten Pipelines verwenden Sie zunächst erweiterte Vorlagen. Diese Vorlagen definieren die äußere Struktur der Pipeline und verhindern, dass bösartiger Code die Pipeline infiltriert.
Beispielsweise heißt die folgende Vorlagendatei template.yml.
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
Die folgende Pipeline erweitert die template.yml Vorlage.
# 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
Tipp
Wenn Sie Vorlagen einrichten extends
, sollten Sie diese an einer bestimmten Git-Verzweigung oder einem bestimmten Tag verankern, sodass vorhandene Pipelines nicht betroffen sind, wenn änderungen unterbrochen werden. Im vorherigen Beispiel wird dieses Feature verwendet.
YaML-Pipelinesicherheitsfeatures
Die YAML-Pipelinesyntax enthält mehrere integrierte Schutzmaßnahmen. Erweitert die Vorlage kann ihre Verwendung erzwingen. Um die Pipelinesicherheit zu verbessern, können Sie eine der folgenden Einschränkungen implementieren.
Schrittziele
Sie können bestimmte Schritte einschränken, die in einem Container und nicht auf dem Host ausgeführt werden sollen. Schritte in Containern haben keinen Zugriff auf den Host des Agents, wodurch verhindert wird, dass diese Schritte die Agentkonfiguration ändern oder bösartigen Code für die spätere Ausführung verlassen.
Erwägen Sie beispielsweise das Einschränken des Netzwerkzugriffs. Ohne geöffneten Netzwerkzugriff können Benutzerschritte keine Pakete von nicht autorisierten Quellen abrufen oder Code und geheime Schlüssel an externe Netzwerkspeicherorte hochladen.
Die folgende Beispielpipeline führt Schritte auf dem Agenthost aus, bevor Sie Schritte in einem Container ausführen.
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
Einschränkungen für Agent-Protokollierungsbefehle
Sie können die Dienste einschränken, die der Azure Pipelines-Agent für Benutzerschritte bereitstellt. Benutzerschritte fordern Dienste mithilfe von Protokollierungsbefehlen an, die speziell formatierte Zeichenfolgen sind, die in die Standardausgabe gedruckt werden. Im eingeschränkten Modus sind die meisten Dienste des Agents, z. B. das Hochladen von Artefakten und das Anfügen von Testergebnissen, nicht verfügbar.
Die folgende Beispielaufgabe schlägt fehl, da die target
Eigenschaft dem Agent anweist, Veröffentlichungsartefakte nicht zuzulassen.
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
Im restricted
Modus bleibt der setvariable
Befehl zulässig, daher ist Vorsicht erforderlich, da Pipelinevariablen als Umgebungsvariablen in nachfolgende Aufgaben exportiert werden. Wenn Aufgaben vom Benutzer bereitgestellte Daten ausgeben, z. B. offene Probleme, die über eine REST-API abgerufen wurden, sind sie möglicherweise anfällig für Einfügungsangriffe. Böswillige Benutzerinhalte könnten Umgebungsvariablen festlegen, die möglicherweise ausgenutzt werden, um den Agenthost zu kompromittieren.
Um dieses Risiko zu minimieren, können Pipelineautoren explizit deklarieren, welche Variablen mithilfe des setvariable
Protokollierungsbefehls festgelegt werden können. Wenn Sie eine leere Liste angeben, ist alle Variableneinstellung unzulässig.
The following example task fails 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"
Ausführung einer bedingten Phase oder eines Auftrags
Sie können Stufen und Aufträge so einschränken, dass sie nur unter bestimmten Bedingungen ausgeführt werden. Im folgenden Beispiel stellt die Bedingung sicher, dass eingeschränkter Code nur für die Hauptzweigung erstellt wird.
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änderung
Azure Pipelines-Vorlagen haben die Flexibilität, die YAML-Syntax zu durchlaufen und zu ändern. Mithilfe der Iteration können Sie bestimmte YAML-Sicherheitsfeatures erzwingen.
Eine Vorlage kann auch Benutzerschritte neu schreiben, sodass nur genehmigte Aufgaben ausgeführt werden können. Sie können beispielsweise die Inlineskriptausführung verhindern.
Die folgende Beispielvorlage verhindert, dass die Schritttypen bash
, powershell
, , pwsh
und script
die Ausführung ausgeführt werden. Für die vollständige Sperrung von Ad-hoc-Skripts können Sie auch blockieren BatchScript
und 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 }}'
In der folgenden Pipeline, die diese Vorlage erweitert, werden die Skriptschritte entfernt und nicht ausgeführt.
# 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
Typsichere Parameter
Bevor eine Pipeline ausgeführt wird, werden Vorlagen und deren Parameter in Konstanten umgewandelt. Vorlagenparameter können die Typsicherheit für Eingabeparameter verbessern.
In der folgenden Beispielvorlage beschränken die Parameter die verfügbaren Pipelinepooloptionen, indem eine Aufzählung bestimmter Auswahlmöglichkeiten bereitgestellt wird, anstatt Freihandformzeichenfolgen zuzulassen.
# 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
Wenn die Pipeline die Vorlage erweitert, muss sie eine der verfügbaren Pooloptionen angeben.
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Vorlagenschritte
Eine Vorlage kann automatisch Schritte in eine Pipeline einschließen. Diese Schritte können Aufgaben wie die Überprüfung von Anmeldeinformationen oder statische Codeüberprüfungen ausführen. Die folgende Vorlage fügt Die Schritte vor und nach den Schritten des Benutzers in jeden Auftrag ein.
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()
Erzwingung von Vorlagen
Vorlagen sind ein wertvoller Sicherheitsmechanismus, aber ihre Effektivität basiert auf der Durchsetzung. Die wichtigsten Kontrollpunkte zum Erzwingen der Vorlagenverwendung sind geschützte Ressourcen. Sie können Genehmigungen konfigurieren und nach Ihrem Agentpool oder anderen geschützten Ressourcen wie Repositorys suchen. Ein Beispiel finden Sie unter Hinzufügen einer Repositoryressourcenüberprüfung.
Erforderliche Vorlagen
Um die Verwendung einer bestimmten Vorlage zu erzwingen, konfigurieren Sie die erforderliche Vorlagenüberprüfung für eine Ressource. Diese Überprüfung gilt nur, wenn sich die Pipeline von einer Vorlage erstreckt.
Wenn Sie den Pipelineauftrag anzeigen, können Sie den Status der Überprüfung überwachen. Wenn die Pipeline nicht über die erforderliche Vorlage erweitert wird, schlägt die Überprüfung fehl. Die Ausführung stoppt und benachrichtigt Sie über die fehlgeschlagene Überprüfung.
Wenn Sie die erforderliche Vorlage verwenden, wird die Überprüfung bestanden.
Auf die folgende params.yml Vorlage muss in jeder Pipeline verwiesen werden, die sie erweitert.
# 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 }}
Die folgende Beispielpipeline erweitert die params.yml Vorlage und erfordert eine Genehmigung. Um einen Pipelinefehler zu veranschaulichen, kommentieren Sie den Verweis auf params.yml aus.
# azure-pipeline.yml
resources:
containers:
- container: my-container
endpoint: my-service-connection
image: mycontainerimages
extends:
template: params.yml
parameters:
yesNo: true
image: 'windows-latest'