How to Integrate Trivy 0.50 with ArgoCD 2.12 to Block Vulnerable Container Images
Container image vulnerabilities remain a top attack vector for Kubernetes workloads. ArgoCD 2.12 is the leading GitOps tool for Kubernetes deployment automation, while Trivy 0.50 is a lightweight, comprehensive vulnerability scanner for containers, Kubernetes, and cloud environments. Integrating the two allows you to automatically block vulnerable container images during the ArgoCD sync process, enforcing security policies without manual intervention.
Prerequisites
- Kubernetes cluster (v1.27 or later)
- ArgoCD 2.12 installed and configured, with
argocdCLI authenticated -
kubectlconfigured to access your cluster - Trivy 0.50 CLI installed locally (or in-cluster Trivy server deployed)
- Helm v3.13+ (optional, for Trivy deployment)
Step 1: Deploy Trivy 0.50 In-Cluster
For reliable integration with ArgoCD, deploy Trivy as a server-side component in your cluster. Use the official Trivy Helm chart to install version 0.50.0:
helm repo add trivy https://aquasecurity.github.io/helm-charts/
helm repo update
helm install trivy trivy/trivy --version 0.50.0 \
--namespace trivy --create-namespace \
--set server.enabled=true \
--set server.service.type=ClusterIP
Verify the Trivy server is running:
kubectl get pods -n trivy
# Expected output: trivy-xxx-yyy 1/1 Running
Port-forward the Trivy service to test connectivity:
kubectl port-forward -n trivy svc/trivy 8080:8080
curl http://localhost:8080/v1/healthz
# Expected output: ok
Step 2: Define Trivy Scan Policies
Create a policy to specify which vulnerabilities trigger a deployment block. This example blocks images with any HIGH or CRITICAL severity vulnerabilities:
apiVersion: v1
kind: ConfigMap
metadata:
name: trivy-scan-policy
namespace: argocd
data:
policy.json: |
{
"vulnerability": {
"ignore": [],
"failOnSeverity": "HIGH"
}
}
Apply the policy to the ArgoCD namespace:
kubectl apply -f trivy-scan-policy.yaml
Step 3: Create ArgoCD PreSync Hook for Trivy Scanning
ArgoCD supports lifecycle hooks that run before, during, or after syncing an application. A PreSync hook runs before the application manifests are applied. We will create a Kubernetes Job that runs Trivy to scan the target container image, failing the sync if vulnerabilities are detected.
Save the following manifest as trivy-presync-hook.yaml:
apiVersion: batch/v1
kind: Job
metadata:
name: trivy-vulnerability-scan
annotations:
argocd.argoproj.io/hook: PreSync
argocd.argoproj.io/hook-delete-policy: HookSucceeded,HookFailed
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: trivy-scanner
image: aquasec/trivy:0.50.0
env:
- name: TRIVY_SERVER
value: "http://trivy.trivy.svc.cluster.local:8080"
- name: TARGET_IMAGE
value: "nginx:1.21.6" # Replace with dynamic image reference in production
command:
- /bin/sh
- -c
- |
trivy image --server $TRIVY_SERVER --severity HIGH,CRITICAL --exit-code 1 --policy /policy/policy.json $TARGET_IMAGE
volumeMounts:
- name: policy-volume
mountPath: /policy
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
volumes:
- name: policy-volume
configMap:
name: trivy-scan-policy
Apply the hook manifest to your cluster. Ensure it is stored in the same Git repository as your application manifests, so ArgoCD includes it during sync.
Step 4: Configure ArgoCD Application
Create an ArgoCD Application that references your application manifests (including the PreSync hook). Example application manifest:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: vulnerable-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/your-org/your-app-manifests.git
targetRevision: main
path: manifests
destination:
server: https://kubernetes.default.svc
namespace: default
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
Apply the application manifest:
argocd app create -f vulnerable-app.yaml
Step 5: Test the Integration
Trigger a sync for the application using a vulnerable image (e.g., nginx:1.21.6, which has known HIGH severity vulnerabilities):
argocd app sync vulnerable-app
ArgoCD will run the PreSync hook first. Trivy will scan the image, detect HIGH vulnerabilities, exit with code 1, and the Job will fail. ArgoCD will mark the sync as failed, blocking the vulnerable image from deploying.
Check the sync status:
argocd app get vulnerable-app
You will see a failed sync status with an error message referencing the failed PreSync job.
Step 6: Tune and Enforce Policies
Adjust your Trivy policies to fit your organization's needs:
- Set
failOnSeveritytoCRITICALto only block the most severe vulnerabilities - Add CVE IDs to the
ignorelist to exclude false positives or accepted risks - Configure Trivy to cache vulnerability databases using a persistent volume to speed up scans
- Integrate Trivy scan reports with your SIEM or monitoring tools for audit trails
Conclusion
Integrating Trivy 0.50 with ArgoCD 2.12 automates container image vulnerability scanning and blocking as part of your GitOps workflow. This ensures only compliant, low-risk images are deployed to your Kubernetes cluster, reducing your attack surface without slowing down your deployment pipeline. Always test policy changes in staging environments first, and keep both Trivy and ArgoCD updated to the latest patch versions to maintain security and compatibility.
Top comments (0)