Policykontroll för artefakter

Azure DevOps Services

Artefaktprinciper framtvingas innan de distribueras till kritiska miljöer, till exempel produktion. Dessa principer utvärderas mot alla distribuerbara artefakter i den angivna pipelinekörningen och blockerar distributionen om artefakterna inte uppfyller kraven. Om du lägger till en kontroll för att utvärdera Artifact måste den anpassade principen konfigureras. Den här guiden beskriver hur anpassade principer kan skapas.

Anteckning

För närvarande är de artefakttyper som stöds för containeravbildningar och Kubernetes-miljöer

Förutsättningar

Använd Rego för att definiera en princip som är lätt att läsa och skriva.

Bekanta dig med Rego-frågespråket . Grunderna kommer att göra.

Rego utökar dataloggen för att stödja strukturerade dokumentmodeller som JSON. Rego-frågor är påståenden om data som lagras i OPA. Dessa frågor kan användas för att definiera principer som räknar upp instanser av data som bryter mot systemets förväntade tillstånd.

Skapa anpassade principer

Nedan visas exempelprinciperna som delas. Baserat på dina krav kan du skapa en egen uppsättning principer.

Kontrollera specifika projekt/pipeline

Den här principen kontrollerar om avbildningarna har skapats av Azure Pipelines och Pipeline-foo. För att detta ska fungera bör pipelinedefinitionen åsidosätta namnfältet till något som: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Läs mer om namngivning av pipelinekörningar här.

allowedBuilder := "AzureDevOps_pipeline-foo"

checkBuilder[errors] {
    trace("Check if images are built by Azure Pipelines")
    resourceUri := values[index].build.resourceUri    
    image := fetchImage(resourceUri)
    builder := values[index].build.build.provenance.builderVersion
    trace(sprintf("%s: builder", [builder]))
    not startswith(builder, "allowedBuilder")
    errors := sprintf("%s: image not built by Azure Pipeline [%s]", [image,builder])
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}

Kontrollera tillåtna register

Den här principen kontrollerar om avbildningarna endast kommer från tillåtna register.

allowlist = {
 "gcr.io/myrepo",
 "raireg1.azurecr.io"
}

checkregistries[errors] {
    trace(sprintf("Allowed registries: %s", [concat(", ", allowlist)]))
    resourceUri := values[index].image.resourceUri
    registry := fetchRegistry(resourceUri)
    image := fetchImage(resourceUri)
    not allowlist[registry]
    errors := sprintf("%s: source registry not permitted", [image]) 
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}

Kontrollera förbjudna portar

Den här principen söker efter alla förbjudna portar som exponeras i containeravbildningen.

forbiddenPorts = {
    "80",
    "22"
}

checkExposedPorts[errors] {
    trace(sprintf("Checking for forbidden exposed ports: %s", [concat(", ", forbiddenPorts)]))
    layerInfos := values[index].image.image.layerInfo
    layerInfos[x].directive == "EXPOSE"
    resourceUri := values[index].image.resourceUri
    image := fetchImage(resourceUri)
    ports := layerInfos[x].arguments
    trace(sprintf("exposed ports: %s", [ports]))
    forbiddenPorts[ports]
    errors := sprintf("%s: image exposes forbidden port %s", [image,ports])
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}

Kontrollera tidigare distributioner

Den här principen kontrollerar om avbildningen har fördistribuerats till en/flera av miljöerna innan den distribueras till specifika miljöer/resurser med Check konfigurerad.

predeployedEnvironments = {
    "env/resource1",
    "env2/resource3"
}

checkDeployedEnvironments[errors] {
    trace(sprintf("Checking if the image has been pre-deployed to one of: [%s]", [concat(", ", predeployedEnvironments)]))
    deployments := values[index].deployment
    deployedAddress := deployments[i].deployment.address
    trace(sprintf("deployed to : %s",[deployedAddress]))
    resourceUri := deployments[i].resourceUri
    image := fetchImage(resourceUri)
    not predeployedEnvironments[deployedAddress]
    trace(sprintf("%s: fails pre-deployed environment condition. found %s", [image,deployedAddress]))
    errors := sprintf("image %s fails pre-deployed environment condition. found %s", [image,deployedAddress])
}

fetchRegistry(uri) = reg {
    out := regex.find_n("//.*/", uri, 1)
    reg = trim(out[0], "/")
}

fetchImage(uri) = img {
    out := regex.find_n("/.*@", uri, 1)
    img := trim(out[0], "/@")
}