Templat untuk keamanan

Layanan Azure DevOps | Azure DevOps Server | Azure DevOps Server 2022

Templat Azure Pipelines memungkinkan Anda menentukan konten, logika, dan parameter yang dapat digunakan kembali dalam alur YAML. Artikel ini menjelaskan bagaimana templat dapat membantu meningkatkan keamanan alur dengan:

  • Menentukan struktur luar alur untuk membantu mencegah infiltrasi kode berbahaya.
  • Secara otomatis menyertakan langkah-langkah untuk melakukan tugas seperti pemindaian kredensial.
  • Membantu memberlakukan pemeriksaan pada sumber daya yang dilindungi, yang membentuk kerangka kerja keamanan dasar untuk Azure Pipelines dan berlaku untuk semua struktur dan komponen alur.

Artikel ini adalah bagian dari seri yang membantu Anda menerapkan langkah-langkah keamanan untuk Azure Pipelines. Untuk informasi selengkapnya, lihat Mengamankan Azure Pipelines.

Prasyarat

Kategori Persyaratan
Azure DevOps - Terapkan rekomendasi di Membuat Azure DevOps Anda aman dan Alur Azure Aman.
- Pengetahuan dasar tentang YAML dan Azure Pipelines. Untuk informasi selengkapnya, lihat Buat pipa pertama Anda.
Izin - Untuk mengubah izin alur: Anggota grup Administrator Proyek.
- Untuk mengubah izin organisasi: Anggota grup Administrator Koleksi Proyek.

Menyertakan dan memperluas templat

Azure Pipelines menyediakan menyertakan dan memperluas templat.

  • includes Templat menyertakan kode templat langsung di file luar yang mereferensikan templat, seperti dalam C++ #include. Contoh alur berikut menyisipkan templat include-npm-steps.yml ke dalam bagian steps .

      steps:
      - template: templates/include-npm-steps.yml 
    
  • extends Templat mendefinisikan struktur luar alur dan menawarkan titik tertentu untuk kustomisasi yang ditargetkan. Dalam konteks C++, extends templat menyerupai warisan.

Saat Anda menggunakan extends templat, Anda juga dapat menggunakan includes untuk melakukan potongan konfigurasi umum di templat dan alur akhir. Untuk informasi selengkapnya, lihat Menggunakan templat YAML dalam alur untuk proses yang dapat digunakan kembali dan aman.

Memperluas templat

Untuk alur yang paling aman, mulailah dengan menggunakan extends templat. Templat ini menentukan struktur luar alur dan membantu mencegah infiltrasi kode berbahaya.

Contoh berikut menunjukkan file templat bernama template.yml.

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

Contoh alur berikut memperluas templat 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

Petunjuk / Saran

Saat Anda menyiapkan extends templat, pertimbangkan untuk menjangkarkannya ke cabang atau tag Git tertentu sehingga perubahan yang mengganggu tidak memengaruhi pipeline yang ada. Contoh sebelumnya menggunakan fitur ini.

Fitur keamanan alur

Sintaks alur YAML mencakup beberapa perlindungan bawaan. Extends templat dapat memberlakukan penggunaannya untuk meningkatkan keamanan alur. Anda dapat menerapkan salah satu batasan berikut.

Target langkah

Anda dapat membatasi langkah-langkah yang ditentukan untuk dijalankan dalam kontainer daripada pada host. Langkah-langkah dalam kontainer tidak dapat mengakses host agen, sehingga mereka tidak dapat memodifikasi konfigurasi agen atau meninggalkan kode berbahaya untuk eksekusi nanti.

Misalnya, Anda dapat menjalankan langkah-langkah pengguna dalam kontainer untuk mencegah mereka mengakses jaringan, sehingga mereka tidak dapat mengambil paket dari sumber yang tidak sah atau mengunggah kode dan rahasia ke lokasi eksternal.

Contoh alur berikut menjalankan langkah pada host agen yang berpotensi mengubah jaringan host, diikuti dengan langkah di dalam kontainer yang membatasi akses jaringan.

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

Parameter jenis aman

Sebelum alur berjalan, templat dan parameternya berubah menjadi konstanta. Parameter templat dapat meningkatkan keamanan jenis untuk parameter input.

Dalam contoh templat berikut, parameter membatasi opsi kumpulan alur yang tersedia dengan menghitung pilihan tertentu alih-alih mengizinkan string apa pun.

# 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

Untuk memperluas template, pipeline harus menentukan salah satu pilihan kumpulan yang tersedia.

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

Pembatasan perintah pengelogan agen

Langkah pengguna meminta layanan dengan menggunakan perintah pengelogan, yang merupakan string yang diformat khusus yang dicetak ke output standar. Anda dapat membatasi layanan yang disediakan perintah pengelogan untuk langkah-langkah pengguna. Dalam restricted mode, sebagian besar layanan agen seperti mengunggah artefak dan melampirkan hasil pengujian tidak tersedia untuk perintah pengelogan.

Dalam contoh berikut, properti target menginstruksikan agen untuk membatasi penerbitan artefak, sehingga tugas penerbitan artefak gagal.

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

Variabel dalam perintah pengelogan

Perintah setvariable tetap diizinkan dalam restricted mode, sehingga tugas yang menghasilkan data yang disediakan pengguna, seperti masalah terbuka yang diambil melalui REST API, mungkin rentan terhadap serangan injeksi. Konten pengguna berbahaya dapat mengatur variabel yang diekspor ke tugas berikutnya sebagai variabel lingkungan dan dapat membahayakan host agen.

Untuk mengurangi risiko ini, Anda dapat secara eksplisit mendeklarasikan variabel yang dapat diatur dengan menggunakan perintah pengelogan setvariable . Jika Anda menentukan daftar kosong di settableVariables, semua pengaturan variabel tidak diizinkan.

Contoh berikut membatasi settableVariables hanya pada expectedVar dan di variabel apa pun yang diawali dengan ok. Tugas gagal karena mencoba mengatur variabel lain yang disebut BadVar.

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

Tahap kondisi atau eksekusi pekerjaan

Anda dapat membatasi tahapan dan pekerjaan untuk dijalankan hanya dalam kondisi tertentu. Contoh berikut memastikan bahwa kode terbatas hanya dibuat untuk cabang 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

Modifikasi sintaks

Templat Azure Pipelines memiliki fleksibilitas untuk melakukan iterasi dan memodifikasi sintaks YAML. Dengan menggunakan iterasi, Anda dapat menerapkan fitur keamanan YAML tertentu.

Templat juga dapat menulis ulang langkah-langkah pengguna, yang hanya memungkinkan tugas yang disetujui untuk dijalankan. Misalnya, templat dapat mencegah eksekusi skrip sebaris.

Contoh templat berikut mencegah jenis langkah skrip bash, powershell, pwsh, dan script berjalan. Untuk penguncian lengkap skrip, Anda juga dapat memblokir BatchScript dan 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 }}'

Dalam contoh alur berikut yang memperluas templat sebelumnya, langkah-langkah skrip dilucuti dan tidak dijalankan.

# 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

Langkah-langkah templat

Templat dapat secara otomatis menyertakan langkah-langkah dalam alur, misalnya untuk melakukan pemindaian kredensial atau pemeriksaan kode statis. Templat berikut menyisipkan langkah-langkah sebelum dan sesudah langkah-langkah pengguna di setiap pekerjaan.

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

Penegakan templat

Efektivitas templat sebagai mekanisme keamanan bergantung pada penegakan. Titik kontrol utama untuk memberlakukan penggunaan templat adalah sumber daya yang dilindungi.

Anda dapat mengonfigurasi persetujuan dan pemeriksaan untuk kumpulan agen anda atau sumber daya lain yang dilindungi seperti repositori. Misalnya, lihat Menambahkan pemeriksaan sumber daya repositori.

Templat yang diperlukan

Untuk menerapkan penggunaan templat tertentu, konfigurasikan pemeriksaan templat yang diperlukan pada koneksi layanan untuk sumber daya. Pemeriksaan ini hanya berlaku ketika alur meluas dari templat.

Saat Anda melihat pekerjaan alur, Anda dapat memantau status pemeriksaan. Jika alur tidak diperluas dari templat yang diperlukan, pemeriksaan gagal.

Cuplikan layar memperlihatkan pemeriksaan persetujuan yang gagal.

Saat Anda menggunakan templat yang diperlukan, pemeriksaan akan lolos.

Cuplikan layar memperlihatkan pemeriksaan persetujuan yang diteruskan.

Misalnya, templat params.yml berikut harus dirujuk dalam alur apa pun yang memperluasnya.

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

Contoh alur berikut memperluas templat params.yml dan memerlukannya untuk disetujui. Untuk menunjukkan kegagalan alur, komentari extends referensi ke 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'