Sicurezza tramite modelli
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2020
I controlli sulle risorse protette sono il blocco predefinito di base della sicurezza per Azure Pipelines. I controlli funzionano indipendentemente dalla struttura, ovvero le fasi e i processi, della pipeline. Se più pipeline nel team o nell'organizzazione hanno la stessa struttura, è possibile semplificare ulteriormente la sicurezza usando i modelli.
Azure Pipelines offre due tipi di modelli: include ed estende.
I modelli inclusi si comportano come #include
in C++: è come se si incollasse il codice del modello direttamente nel file esterno, che vi fa riferimento. Ad esempio, in questo caso viene inserito un modello include (include-npm-steps.yml
) in steps
.
steps:
- template: templates/include-npm-steps.yml
Per continuare la metafora C++, extends
i modelli sono più simili all'ereditarietà: il modello fornisce la struttura esterna della pipeline e un set di posizioni in cui il consumer di modelli può apportare modifiche mirate.
Usare modelli di estensione
Per le pipeline più sicure, è consigliabile iniziare con extends
i modelli.
Fornendo la struttura esterna, un modello può impedire che il codice dannoso entri nella pipeline.
È comunque possibile usare includes
, sia nel modello che nella pipeline finale, per tenere conto delle parti comuni della configurazione.
Per usare un modello esteso, la pipeline potrebbe essere simile all'esempio seguente.
# template.yml
parameters:
- name: usersteps
type: stepList
default: []
steps:
- ${{ each step in parameters.usersteps }}:
- ${{ step }}
# 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
Quando si configurano extends
i modelli, è consigliabile ancorarli a un determinato ramo o tag Git.
In questo modo, se è necessario apportare modifiche di rilievo, le pipeline esistenti non saranno interessate.
Gli esempi precedenti usano questa funzionalità.
Funzionalità di sicurezza applicate tramite YAML
Esistono diverse protezioni integrate nella sintassi YAML e un modello di estensione può imporre l'utilizzo di una o di tutte.
Destinazioni dei passaggi
Limitare alcuni passaggi da eseguire in un contenitore anziché nell'host. Senza l'accesso all'host dell'agente, i passaggi utente non possono modificare la configurazione dell'agente o lasciare il codice dannoso per un'esecuzione successiva. Eseguire prima il codice nell'host per rendere il contenitore più sicuro. Ad esempio, è consigliabile limitare l'accesso alla rete. Senza l'accesso aperto alla rete, i passaggi utente non potranno accedere ai pacchetti da origini non autorizzate o caricare codice e segreti in un percorso di rete.
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
Restrizioni dei comandi di registrazione degli agenti
Limitare i servizi che l'agente di Azure Pipelines fornirà ai passaggi utente. I passaggi richiedono servizi usando "comandi di registrazione" (stringhe in formato speciale stampate in stdout). In modalità con restrizioni, la maggior parte dei servizi dell'agente, ad esempio il caricamento di artefatti e il collegamento dei risultati dei test, non sono disponibili.
# this task will fail because its `target` property instructs the agent not to allow publishing artifacts
- task: PublishBuildArtifacts@1
inputs:
artifactName: myartifacts
target:
commands: restricted
Uno dei comandi ancora consentiti in modalità con restrizioni è il setvariable
comando . Poiché le variabili della pipeline vengono esportate come variabili di ambiente nelle attività successive, le attività che generano dati forniti dall'utente (ad esempio, il contenuto dei problemi aperti recuperati da un'API REST) possono essere vulnerabili agli attacchi injection. Tali contenuti utente possono impostare variabili di ambiente che a loro volta possono essere usate per sfruttare l'host dell'agente. Per impedire questo problema, gli autori della pipeline possono dichiarare in modo esplicito quali variabili sono impostabili tramite il setvariable
comando di registrazione. Se si specifica un elenco vuoto, non è consentito impostare tutte le variabili.
# this task will fail 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"
Inserimento condizionale di fasi o processi
Limitare le fasi e i processi da eseguire in condizioni specifiche. Le condizioni possono essere utili, ad esempio, per assicurarsi di creare solo determinati rami.
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
Richiedere una certa sintassi con i modelli di estensione
I modelli possono scorrere e modificare/impedire qualsiasi sintassi YAML. L'iterazione può forzare l'uso di una particolare sintassi YAML, incluse le funzionalità precedenti.
Un modello può riscrivere i passaggi utente e consentire l'esecuzione di determinate attività approvate. È ad esempio possibile impedire l'esecuzione di script inline.
Avviso
Nell'esempio seguente non è possibile eseguire i passaggi di tipo "bash", "powershell", "pwsh" e "script". Per il blocco completo degli script ad hoc, è anche necessario bloccare "BatchScript" e "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 lines below will 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 }}'
# 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
Parametri indipendenti dai tipi
I modelli e i relativi parametri vengono trasformati in costanti prima dell'esecuzione della pipeline. I parametri del modello forniscono la sicurezza dei tipi ai parametri di input. Ad esempio, può limitare i pool che possono essere usati in una pipeline offrendo un'enumerazione delle opzioni possibili anziché una stringa a mano libera.
# 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
# azure-pipelines.yml
extends:
template: template.yml
parameters:
userpool: private-pool-1
Impostare i modelli obbligatori
Per richiedere l'uso di un modello specifico, è possibile impostare il controllo del modello richiesto per una risorsa o un ambiente. Il controllo del modello richiesto può essere usato durante l'estensione da un modello.
È possibile controllare lo stato di un controllo durante la visualizzazione di un processo della pipeline. Quando una pipeline non si estende dal modello di richiesta, il controllo avrà esito negativo e l'esecuzione verrà arrestata. Si noterà che il controllo non è riuscito.
Quando si usa il modello richiesto, si noterà che il controllo è stato superato.
In questo caso il modello params.yml
è necessario con un'approvazione per la risorsa. Per attivare l'esito negativo della pipeline, impostare come commento il riferimento a params.yml
.
# 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 }}
# azure-pipeline.yml
resources:
containers:
- container: my-container
endpoint: my-service-connection
image: mycontainerimages
extends:
template: params.yml
parameters:
yesNo: true
image: 'windows-latest'
Passaggi aggiuntivi
Un modello può aggiungere passaggi senza che l'autore della pipeline li includa. Questi passaggi possono essere usati per eseguire l'analisi delle credenziali o i controlli del codice statico.
# template to insert a step before and after user steps in every job
parameters:
jobs: []
jobs:
- ${{ each job in parameters.jobs }}: # Each job
- ${{ each pair in job }}: # Insert all properties other than "steps"
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps: # Wrap the steps
- task: CredScan@1 # Pre steps
- ${{ job.steps }} # Users steps
- task: PublishMyTelemetry@1 # Post steps
condition: always()
Applicazione del modello
Un modello è solo un meccanismo di sicurezza se è possibile applicarlo. Il punto di controllo per applicare l'uso dei modelli è una risorsa protetta. È possibile configurare le approvazioni e i controlli nel pool di agenti o in altre risorse protette, ad esempio i repository. Per un esempio, vedere Aggiungere un controllo delle risorse del repository.
Passaggi successivi
Informazioni quindi sull'acquisizione sicura degli input tramite variabili e parametri.
Commenti e suggerimenti
https://aka.ms/ContentUserFeedback.
Presto disponibile: Nel corso del 2024 verranno gradualmente disattivati i problemi di GitHub come meccanismo di feedback per il contenuto e ciò verrà sostituito con un nuovo sistema di feedback. Per altre informazioni, vedereInvia e visualizza il feedback per