Sdílet prostřednictvím


Použití skriptu k aktualizaci nastavení zabezpečení

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022 | Azure DevOps Server 2020

Pomocí rozhraní REST API Azure DevOps můžete automatizovat aktualizace některých nastavení kanálu Azure DevOps na úrovni projektu. Některá nastavení nejsou dostupná prostřednictvím rozhraní REST API. V případě nastavení na úrovni organizace budete muset provést změny konfigurace v uživatelském rozhraní Azure DevOps.

Požadavky

produkt Požadavky
Azure DevOps – Organizace a projekt Azure DevOps. Vytvořte si ho zdarma.
- Oprávnění:
    – Chcete-li spustit tento skript a aktualizovat nastavení zabezpečení kanálu Azure DevOps: Musíte být členem skupiny Správci projektu.
Azure – Účet Azure s přístupem k ověřování pomocí Connect-AzAccount.
Setting Doporučená hodnota Odůvodnění
enforceReferencedRepoScopedToken Pravdivé Zajišťuje, že se pro odkazovaná úložiště používají pouze tokeny s vymezeným oborem, což omezuje obor přístupu.
disableClassicBuildPipelineCreation Pravdivé Zakáže klasické kanály buildu, které nemají moderní funkce zabezpečení a auditování.
disableClassicReleasePipelineCreation Pravdivé Zakáže klasické vývojové kanály s využitím alternativ YAML.
forkProtectionEnabled Pravdivé Umožňuje ochranu sestavení aktivovaných z forků, aby se zabránilo úniku tajných kódů.
buildsEnabledForForks Nepravda Zakáže sestavení z forků, aby se zabránilo provádění nedůvěryhodného kódu.
enforceJobAuthScopeForForks Pravdivé Omezuje autorizaci úloh na aktuální projekt forkovaných sestavení.
enforceNoAccessToSecretsFromForks Pravdivé Zabrání zpřístupnění tajných kódů pro forkované buildy.
isCommentRequiredForPullRequest Pravdivé Přidá ruční bránu před spuštěním sestavení na žádostech o přijetí změn.
requireCommentsForNonTeamMembersOnly Pravdivé Zajišťuje, že pouze důvěryhodní přispěvatelé mohou automaticky spustit sestavení.
requireCommentsForNonTeamMemberAndNonContributors Pravdivé Přidává další vrstvu ochrany pro externí pull requesty.
enableShellTasksArgsSanitizing Pravdivé Zabraňuje injektáži příkazů v úlohách prostředí.
enableShellTasksArgsSanitizingAudit Volitelný Protokoluje porušení bez blokování sestavení; užitečné pro postupné zavedení.
disableImpliedYAMLCiTrigger Pravdivé Zabraňuje nechtěným spouštěčům CI vyvolaným změnami v YAML.
statusBadgesArePrivate Pravdivé Udržuje stav kanálu jako soukromý, aby nedošlo k úniku informací o projektu.
enforceSettableVar Pravdivé Zajišťuje, že za běhu lze nastavit pouze explicitně povolené proměnné.
enforceJobAuthScope Pravdivé Omezuje přístup k úlohám pouze na aktuální projekt.
enforceJobAuthScopeForReleases Pravdivé Stejně jako výše, pro uvolňovací kanály.
publishPipelineMetadata Nepravda Vyhýbá se odhalení metadat, která by se dala použít k průzkumu.

Skript pro automatizaci nastavení

Uložte skript PowerShellu .ps1 jako soubor (příklad: Update-AzureDevOpsSecuritySettings.ps1). Skript můžete spustit s parametry nebo bez parametrů.

Aktualizace všech projektů v organizaci

.\Update-AzureDevOpsSecuritySettings.ps1 -organization "YourOrgName"

Aktualizace konkrétního projektu

.\Update-AzureDevOpsSecuritySettings.ps1 -organization "YourOrgName" -specificProjectName "YourProjectName"

Pokud se zobrazí chyba 403 Zakázáno, ověřte, že máte oprávnění správce projektu nebo správce kolekce.

# Define the organization and API version
param(
    [string]$organization = "your-organization",
    [string]$apiVersion = "7.1",
    [string]$specificProjectName = $null # Optional parameter to specify a single project

)

# Check if already authenticated, if not, authenticate
if (-not (Get-AzContext -ErrorAction SilentlyContinue)) {
    Connect-AzAccount
}

# Get the access token for Azure DevOps
$resourceUrl = "499b84ac-1321-427f-aa17-267ca6975798"
$token = (Get-AzAccessToken -ResourceUrl $resourceUrl).Token

# Define the API URL to get projects
$projectsUrl = "https://dev.azure.com/$organization/_apis/projects?api-version=$apiVersion"

# Set up headers for the request
$headers = @{
    Authorization = "Bearer $token"
    "Content-Type"  = "application/json"
}

# Get the list of projects
$response = Invoke-RestMethod -Uri $projectsUrl -Method Get -Headers $headers

# Define the request body for updating settings
$body = @{
    enforceReferencedRepoScopedTokens = $true
    enableShellTasksArgsSanitizing = $true
    disableClassicBuildPipelineCreation = $true
    disableClassicReleasePipelineCreation = $true
    forkProtectionEnabled = $true
    buildsEnabledForForks = $true
    enforceJobAuthScopeForForks = $true
    enforceNoAccessToSecretsFromForks = $true
    isCommentRequiredForPullRequest = $true
    requireCommentsForNonTeamMembersOnly = $true
    requireCommentsForNonTeamMemberAndNonContributors = $true
    disableImpliedYAMLCiTrigger = $true
    statusBadgesArePrivate = $true
    enforceSettableVar = $true
    enforceJobAuthScope = $true 
    enforceJobAuthScopeForReleases = $true
    publishPipelineMetadata = $false
} | ConvertTo-Json -Depth 10

# Check if a specific project name is provided
if ($specificProjectName) {
    # Update the specified project
    Write-Output "Updating project: $specificProjectName"
    $updateUrl = "https://dev.azure.com/$organization/$specificProjectName/_apis/build/generalsettings?api-version=$apiVersion"

    try {
        Invoke-RestMethod -Uri $updateUrl -Method Patch -Headers $headers -Body $body
        Write-Output "Successfully updated settings for project: $specificProjectName"
    }
    catch {
        Write-Output "Failed to update project: $specificProjectName. Error: $($_.Exception.Message)"
    }
} else {
    # Loop through all projects and update each one
    $response.value | ForEach-Object {
        $projectName = $_.name
        Write-Output "Updating project: $projectName"
        $updateUrl = "https://dev.azure.com/$organization/$projectName/_apis/build/generalsettings?api-version=$apiVersion"

        try {
            Invoke-RestMethod -Uri $updateUrl -Method Patch -Headers $headers -Body $body
            Write-Output "Successfully updated settings for project: $projectName"
        }
        catch {
            Write-Output "Failed to update project: $projectName. Error: $($_.Exception.Message)"
        }
    }
}

Výstup pro každý projekt bude vypadat takto.

Updating project: my-project

enforceReferencedRepoScopedToken                  : True
disableClassicBuildPipelineCreation               : True
disableClassicReleasePipelineCreation             : True
forkProtectionEnabled                             : True
buildsEnabledForForks                             : False
enforceJobAuthScopeForForks                       : False
enforceNoAccessToSecretsFromForks                 : False
isCommentRequiredForPullRequest                   : False
requireCommentsForNonTeamMembersOnly              : False
requireCommentsForNonTeamMemberAndNonContributors : False
enableShellTasksArgsSanitizing                    : False
enableShellTasksArgsSanitizingAudit               : False
disableImpliedYAMLCiTrigger                       : True
statusBadgesArePrivate                            : True
enforceSettableVar                                : True
enforceJobAuthScope                               : True
enforceJobAuthScopeForReleases                    : True
publishPipelineMetadata                           : False