Boosting DevOps Security DEVSECOPS: A Beginner’s Guide to Integrating Trivy, OPA, and Kubesec with Jenkins for Kubernetes

NHAILA Achraf
4 min readMay 16, 2024

In this article, we’ll explore how to enhance the security of your DevOps pipeline by integrating various vulnerability scans into Jenkins.

NHAILA Achraf

We’ll focus on the Kubernetes environment and show you how to set up a Jenkins stages to perform OPA, Kubesec, and Trivy scans.

Don’t worry, we’ll keep things simple

In the world of cybersecurity, finding and fixing vulnerabilities is like putting on your detective hat and preventing bad things from happening. It’s a crucial task to identify and address security risks before they get taken advantage of.

So get ready to level up your security game with Trivy, OPA, and Kubesec in Jenkins. Let’s dive in and make vulnerability testing an easy and effective part of your DevOps journey, especially for Kubernetes deployments! 💪

Why Trivy, OPA, and Kubesec?

We use Trivy, OPA (Open Policy Agent), and Kubesec to perform vulnerability scans and policy checks in our CI/CD pipeline.
Before deploying a new image to our Kubernetes system, it’s important to ensure there are no security weaknesses or outdated packages that hackers could exploit.

About the Tools:

  • Trivy: Scans for vulnerabilities in OS packages and software dependencies.
  • OPA: Checks Kubernetes configurations against security policies.
  • Kubesec: Analyzes Kubernetes resource files for security risks.

How to Integrate These Tools in Jenkins? 📝

Let’s integrate Trivy, OPA, and Kubesec into a Jenkins pipeline to automate security scans for Kubernetes deployments. Here’s a simple guide:

Jenkinsfile Stage

pipeline {
agent any

stages {

stage('Vulnerability Scan - Kubernetes') {
steps {
parallel(
"OPA Scan": {
sh 'sudo docker run --rm -v $(pwd):/project openpolicyagent/conftest test --policy opa-k8s-security.rego k8s_deployment_service.yaml'
},
"Kubesec Scan": {
sh "sudo bash kubesec-scan.sh"
},
"Trivy Scan": {
sh "sudo bash trivy-k8s-scan.sh"
}

)
}
}

}
}

This Jenkins pipeline stage runs three scans in parallel: OPA, Kubesec, and Trivy, specifically focusing on Kubernetes resources.

opa-k8s-security.rego

The file opa-k8s-security.rego is a policy file written in Rego, the policy language used by the Open Policy Agent (OPA). This file typically contains rules and policies that are used to evaluate configurations, such as Kubernetes manifests, to ensure they meet specific security and compliance requirements.

package main

deny[msg] {
input.kind = "Service"
not input.spec.type = "NodePort"
msg = "Service type should be NodePort"
}

deny[msg] {
input.kind = "Deployment"
not input.spec.template.spec.containers[0].securityContext.runAsNonRoot = true
msg = "Containers must not run as root - use runAsNonRoot wihin container security context"
}

trivy-k8s-scan.sh

#!/bin/bash
#trivy-k8s-scan

echo $imageName #getting Image name from env variable

docker run --rm -v $WORKSPACE:/root/.cache/ aquasec/trivy:0.17.2 -q image --exit-code 0 --severity LOW,MEDIUM,HIGH --light $imageName
docker run --rm -v $WORKSPACE:/root/.cache/ aquasec/trivy:0.17.2 -q image --exit-code 1 --severity CRITICAL --light $imageName

# Trivy scan result processing
exit_code=$?
echo "Exit Code : $exit_code"

# Check scan results
if [[ ${exit_code} == 1 ]]; then
echo "Image scanning failed. Vulnerabilities found"
exit 1
else
echo "Image scanning passed. No vulnerabilities found"
fi

k8s_deployment_service.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: devsecops
name: devsecops
spec:
replicas: 2
selector:
matchLabels:
app: devsecops
strategy: {}
template:
metadata:
labels:
app: devsecops
spec:
volumes:
- name: vol
emptyDir: {}
serviceAccountName: default
containers:
- image: replace
name: devsecops-container
volumeMounts:
- mountPath: /tmp
name: vol
securityContext:
runAsNonRoot: true
runAsUser: 100
readOnlyRootFilesystem: true
---
apiVersion: v1
kind: Service
metadata:
labels:
app: devsecops
name: devsecops-svc
spec:
ports:
- port: 9001
protocol: TCP
targetPort: 9001
selector:
app: devsecops
type: NodePort

kubesec-scan.sh

#!/bin/bash

#kubesec-scan.sh

# using kubesec v2 api
scan_result=$(curl -sSX POST --data-binary @"k8s_deployment_service.yaml" https://v2.kubesec.io/scan)
scan_message=$(curl -sSX POST --data-binary @"k8s_deployment_service.yaml" https://v2.kubesec.io/scan | jq .[0].message -r)
scan_score=$(curl -sSX POST --data-binary @"k8s_deployment_service.yaml" https://v2.kubesec.io/scan | jq .[0].score)

# Kubesec scan result processing
echo "Scan Score : $scan_score"

if [[ "${scan_score}" -ge 5 ]]; then
echo "Score is $scan_score"
echo "Kubesec Scan $scan_message"
else
echo "Score is $scan_score, which is less than or equal to 5."
echo "Scanning Kubernetes Resource has Failed"
exit 1
fi

Running the Pipeline

When we execute this pipeline, here is the outcome/result:

As you can see, the script runs three different security scans in parallel, making sure our Kubernetes resources are secure before deploying.

This is done to ensure that we don’t proceed with potentially insecure code until the vulnerabilities are fixed.

It’s like having a security checkpoint that no bad code can pass through! 🚫🔍

Hope this helps you secure your CI/CD pipeline for Kubernetes!

If you liked my article, share it and spread the knowledge! 😊

Photo by Zac Durant on Unsplash

--

--