Menggunakan templat untuk keamanan
Layanan Azure DevOps | Azure DevOps Server 2022 | Azure DevOps Server 2020
Artikel ini menjelaskan bagaimana templat dapat menyederhanakan keamanan untuk Azure Pipelines. Templat dapat menentukan struktur luar alur Anda dan membantu mencegah infiltrasi kode berbahaya. Templat juga dapat secara otomatis menyertakan langkah-langkah untuk melakukan tugas seperti pemindaian kredensial. Jika beberapa alur dalam tim atau organisasi Anda memiliki struktur yang sama, pertimbangkan untuk menggunakan templat.
Memeriksa sumber daya yang dilindungi membentuk kerangka kerja keamanan mendasar untuk Azure Pipelines. Pemeriksaan ini berlaku terlepas dari struktur, tahapan, dan pekerjaan alur. Anda dapat menggunakan templat untuk membantu menerapkan pemeriksaan ini.
Menyertakan dan memperluas templat
Azure Pipelines menyediakan menyertakan dan memperluas templat.
Menyertakan templat menyertakan kode templat langsung di file luar yang mereferensikannya, mirip
#include
dengan C++. Contoh alur berikut menyisipkan templat include-npm-steps.yml ke dalam bagiansteps
.steps: - template: templates/include-npm-steps.yml
Memperluas templat menentukan 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
templat dan alur akhir untuk melakukan bagian konfigurasi umum. Untuk referensi lengkap, lihat Referensi penggunaan templat.
Memperluas templat
Untuk alur yang paling aman, mulailah dengan menggunakan templat perluas. Templat ini menentukan struktur luar alur dan mencegah kode berbahaya menyusup ke alur.
Misalnya, file templat berikut diberi nama template.yml.
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
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
Tip
Saat Anda menyiapkan extends
templat, pertimbangkan untuk menjangkarkannya ke cabang atau tag Git tertentu sehingga jika ada perubahan yang melanggar, alur yang ada tidak terpengaruh. Contoh sebelumnya menggunakan fitur ini.
Fitur keamanan alur YAML
Sintaks alur YAML mencakup beberapa perlindungan bawaan. Memperluas templat dapat memberlakukan penggunaannya. Untuk meningkatkan keamanan alur, Anda dapat menerapkan salah satu batasan berikut.
Target langkah
Anda dapat membatasi langkah-langkah tertentu untuk dijalankan dalam kontainer daripada pada host. Langkah-langkah dalam kontainer tidak memiliki akses ke host agen, mencegah langkah-langkah ini mengubah konfigurasi agen atau meninggalkan kode berbahaya untuk eksekusi nanti.
Misalnya, pertimbangkan untuk membatasi akses jaringan. Tanpa akses jaringan terbuka, langkah-langkah pengguna tidak dapat mengambil paket dari sumber yang tidak sah atau mengunggah kode dan rahasia ke lokasi jaringan eksternal.
Contoh alur berikut menjalankan langkah-langkah pada host agen sebelum menjalankan langkah-langkah di dalam kontainer.
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
Pembatasan perintah pengelogan agen
Anda dapat membatasi layanan yang disediakan agen Azure Pipelines untuk langkah-langkah pengguna. Langkah pengguna meminta layanan dengan menggunakan perintah pengelogan, yang merupakan string yang diformat khusus yang dicetak ke output standar. Dalam mode terbatas, sebagian besar layanan agen, seperti mengunggah artefak dan melampirkan hasil pengujian, tidak tersedia.
Contoh tugas berikut gagal karena propertinya target
menginstruksikan agen untuk tidak mengizinkan penerbitan artefak.
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
Dalam restricted
mode, setvariable
perintah tetap diizinkan, jadi perhatian diperlukan karena variabel alur diekspor sebagai variabel lingkungan ke tugas berikutnya. Jika tugas menghasilkan data yang disediakan pengguna, seperti masalah terbuka yang diambil melalui REST API, tugas tersebut mungkin rentan terhadap serangan injeksi. Konten pengguna berbahaya dapat mengatur variabel lingkungan yang mungkin dieksploitasi untuk membahayakan host agen.
Untuk mengurangi risiko ini, penulis alur dapat secara eksplisit menyatakan variabel mana yang dapat diatur dengan menggunakan perintah pengelogan setvariable
. Saat Anda menentukan daftar kosong, semua pengaturan variabel tidak diizinkan.
Contoh tugas berikut gagal karena tugas hanya diizinkan untuk mengatur expectedVar
variabel atau variabel yang diawali dengan ok
.
- 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. Dalam contoh berikut, kondisi memastikan bahwa kode terbatas hanya dibangun untuk cabang utama.
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, Anda dapat mencegah eksekusi skrip sebaris.
Contoh templat berikut mencegah jenis bash
langkah , , powershell
pwsh
, dan script
berjalan. Untuk penguncian lengkap skrip ad-hoc, 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 alur berikut yang memperluas templat ini, langkah-langkah skrip dilucuti dan tidak dijalankan.
# 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
Parameter jenis aman
Sebelum alur berjalan, templat dan parameternya diubah menjadi konstanta. Parameter templat dapat meningkatkan keamanan jenis untuk parameter input.
Dalam contoh templat berikut, parameter membatasi opsi kumpulan alur yang tersedia dengan memberikan enumerasi pilihan tertentu alih-alih mengizinkan string bentuk bebas.
# 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
Saat alur memperluas templat, alur harus menentukan salah satu pilihan kumpulan yang tersedia.
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Langkah-langkah templat
Templat dapat secara otomatis menyertakan langkah-langkah dalam alur. Langkah-langkah ini dapat melakukan tugas seperti 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
Templat adalah mekanisme keamanan yang berharga, tetapi efektivitasnya 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 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. Eksekusi berhenti dan memberi tahu Anda tentang pemeriksaan yang gagal.
Saat Anda menggunakan templat yang diperlukan, pemeriksaan akan lolos.
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 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'