Bagikan melalui


Pemeriksaan kebijakan artefak

Azure DevOps

Kebijakan artefak diberlakukan sebelum disebarkan ke lingkungan penting seperti produksi. Kebijakan ini dievaluasi terhadap semua artefak yang dapat disebarkan dalam eksekusi alur yang diberikan dan memblokir penyebaran jika artefak tidak sesuai. Menambahkan pemeriksaan untuk mengevaluasi Artefak mengharuskan kebijakan kustom dikonfigurasi. Panduan ini menjelaskan bagaimana kebijakan kustom dapat dibuat.

Catatan

Saat ini, jenis artefak yang didukung adalah untuk gambar kontainer dan lingkungan Kubernetes

Prasyarat

Gunakan Rego untuk menentukan kebijakan yang mudah dibaca dan ditulis.

Biasakan diri Anda dengan bahasa kueri Rego . Dasar-dasar akan dilakukan.

Untuk mendukung model dokumen terstruktur seperti JSON, Rego memperluas Datalog. Kueri rego adalah pernyataan pada data yang disimpan di OPA. Kueri ini dapat digunakan untuk menentukan kebijakan yang menghitung instans data yang melanggar status sistem yang diharapkan.

Membuat kebijakan kustom

Di bawah ini adalah kebijakan sampel yang dibagikan. Berdasarkan kebutuhan Anda, Anda dapat membangun serangkaian kebijakan Anda sendiri.

Periksa proyek/alur tertentu

Kebijakan ini memeriksa apakah gambar dibangun oleh Azure Pipelines dan Pipeline-foo. Agar ini berfungsi, definisi alur harus mengganti bidang nama menjadi sesuatu seperti: AzureDevOps_$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r). Lihat selengkapnya tentang penamaan eksekusi alur di sini.

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], "/@")
}

Periksa registri yang diizinkan

Kebijakan ini memeriksa apakah gambar hanya berasal dari registri yang diizinkan.

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], "/@")
}

Periksa port terlarang

Kebijakan ini memeriksa port terlarang yang terekspos dalam gambar kontainer.

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], "/@")
}

Periksa penyebaran sebelumnya

Kebijakan ini memeriksa apakah gambar telah disebarkan sebelumnya ke satu/beberapa lingkungan sebelum disebarkan ke lingkungan/sumber daya tertentu dengan Periksa yang dikonfigurasi.

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], "/@")
}