Teilen über


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 den steps 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, , pwshund 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.

Screenshot einer fehlgeschlagenen Genehmigungsprüfung.

Wenn Sie die erforderliche Vorlage verwenden, wird die Überprüfung bestanden.

Screenshot einer bestandenen Genehmigungsprüfung.

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'