Analyze and secure Dockerfiles in CI/CD with OPA
This guide will describe how you can use OPA (Open Policy Agent) to analyze Dockerfiles in your CI/CD pipelines to enforce best practices and security. I will be using Jenkins in the examples; however, any CI/CD service out there that uses Docker for building will apply.
OPA uses a rule files written in the Rego language and is easily readable to build off of examples.
Here are some basic rules for best practices and security:
1package main
2
3# Looking for latest docker image used
4deny[msg] {
5 input[i].Cmd == "from"
6 val := split(input[i].Value[0], ":")
7 contains(lower(val[1]), "latest")
8 msg = sprintf("Line %d: do not use 'latest' tag for base images", [i])
9}
10
11# Looking for base image name
12deny[msg] {
13 input[i].Cmd == "from"
14 val := split(input[i].Value[0], ":")[0]
15 val != "python"
16 msg = "Use only official python image"
17}
18
19# Looking for ADD command instead using COPY command
20deny[msg] {
21 input[i].Cmd == "add"
22 val := concat(" ", input[i].Value)
23 msg = sprintf("Use COPY instead of ADD: %s", [val])
24}
25
26# sudo usage
27deny[msg] {
28 input[i].Cmd == "run"
29 val := concat(" ", input[i].Value)
30 contains(lower(val), "sudo")
31 msg = sprintf("Avoid using 'sudo' command: %s", [val])
32}
Here I’m strictly requiring a specific base image, but you could use this rule to look for only base images:
1deny[msg] {
2 input[i].Cmd == "from"
3 val := split(input[i].Value[0], "/")
4 count(val) > 1
5 msg = sprintf("Line %d: use a trusted base image", [i])
6}
Adding this to your CI/CD pipeline is very easy using the Conftest docker image. Below is a snippet from a Jenkinsfile but could be applied to any CI/CD service that uses Docker images for its build steps. Conftest looks for any rego files in a directory and will apply those rules to the file you point it at.
1stage('Conftest') {
2 steps {
3 script {
4 docker.image("openpolicyagent/conftest").inside("--entrypoint=") {
5 sh "conftest test -p ./.jenkins/policy ./Dockerfile"
6 }
7 }
8 }
9}
For added security, I add the Devops group as owners of the rules and build files in the CODEOWNERS file. We’re notified if any changes are made in any project repo.