---
title: "How to integrate Calico Image Scanner with Argo CI/CD"
source: "https://www.tigera.io/blog/how-to-integrate-calico-image-scanner-with-argo-ci-cd/"
description: "Keep your images safe from CVEs by integrating the Calico Image Scanner into your CI/CD pipeline using Argo."
---

[Technical Blog](https://www.tigera.io/category/technical-blog/)

# How to integrate Calico Image Scanner with Argo CI/CD

By [Rui De Abreu](https://www.tigera.io/blog/author/rui-de-abreu/) on May 12, 2023 • 5 min read

In today’s fast-paced software development environment, developers often use common public libraries and modules to quickly build applications. However, this presents a significant challenge for DevOps teams who must ensure that these applications are safe to use. As organizations move towards dynamic models of software development that rely on Continuous Integration and Continuous Deployment, the responsibility for deploying secure applications has shifted from traditional security teams to development teams.

To address this challenge, I will provide general guidelines on how to integrate the [Calico Image Scanning feature](https://www.tigera.io/tigera-products/compare-products/) into a CI/CD pipeline, using Argo. This will help ensure that images are built safely and free from Common Vulnerabilities and Exposures (CVEs). In this blog post, we will use a Kubernetes validating webhook configuration to attach a Calico Cloud admission controller that can accept or reject certain actions on resources, such as the creation of pods. This will prevent the deployment of images that contain known CVEs, thus strengthening the overall security of your software development process.

## Overall Architecture

The building blocks to use Argo as an example of this integration are below:

![Diagram of Argo integration: Git repo triggers Argo Events, which triggers Argo Workflows, which syncs to ArgoCD for K8s](https://www.tigera.io/app/uploads/2023/05/image1-3.png)

## Relevant Calico configuration

Before even committing changes to our application, we must setup the Calico Admission Controller within our Calico Cloud setup, as detailed in our [Docs page](https://docs.tigera.io/calico-cloud/image-assurance/install-the-admission-controller).

Then an “admissioncontrollerpolicy” resource must be created. In this example, we  will be preventing anything that has a CVSS score of “Failed” to be deployed in our environment (For other operations, please check the relevant [resource doc page](https://docs.tigera.io/calico-cloud/reference/resources/containeradmissionpolicy).

```
`apiVersion: containersecurity.www.tigera.io/v1beta1 kind: ContainerAdmissionPolicy metadata: ... name: reject-failed ... spec: namespaceSelector: all() order: 10 rules: - action: Allow imageScanStatus: operator: IsOneOf values: - Pass - Warn - action: Reject selector: all()`
```

## Sequence of events

To test the above, this will be the sequence of events in our pipeline:

- A webhook in the repo sends any push event done to an ingress controller. ![Webhook delivery details showing request and response headers, status code, and completion time](https://www.tigera.io/app/uploads/2023/05/image3-1.png)

- This specific k8s ingress has a service whose endpoint is an “eventsource” resource in the Argo Events namespace.

- The “eventsource” receives the event, and then triggers a “sensor” resource in Argo Events which creates a corresponding workflow.

```
`{"level":"info","ts":1679935064.284753,"logger":"argo-events.eventsource","caller":"github/start.go:130","msg":"received a request, processing it...","eventSourceName":"github","eventSourceType":"github","eventName":"example","endpoint":"/push","port":"12000","http-method":"POST"} {"level":"info","ts":1679935064.2853296,"logger":"argo-events.eventsource","caller":"github/start.go:164","msg":"dispatching event on route's data channel","eventSourceName":"github","eventSourceType":"github","eventName":"example","endpoint":"/push","port":"12000","http-method":"POST"} {"level":"info","ts":1679935064.2854376,"logger":"argo-events.eventsource","caller":"github/start.go:166","msg":"request successfully processed","eventSourceName":"github","eventSourceType":"github","eventName":"example","endpoint":"/push","port":"12000","http-method":"POST"} {"level":"info","ts":1679935064.2854986,"logger":"argo-events.eventsource","caller":"webhook/webhook.go:187","msg":"new event received, dispatching it...","eventSourceName":"github","eventSourceType":"github","eventName":"example"} {"level":"info","ts":1679935064.2905464,"logger":"argo-events.eventsource","caller":"eventsources/eventing.go:558","msg":"Succeeded to publish an event","eventSourceName":"github","eventName":"example","eventSourceType":"github","eventID":"65313037333131362d346161322d343363622d613833322d303265656563316636333338"} … {"level":"info","ts":1679935064.3465035,"logger":"argo-events.sensor","caller":"sensors/listener.go:417","msg":"Successfully processed trigger 'github-workflow-trigger'","sensorName":"github","triggerName":"github-workflow-trigger","triggerType":"Kubernetes","triggeredBy":["test-dep"],"triggeredByEvents":["65313037333131362d346161322d343363622d613833322d303265656563316636333338"]}`
```

- This workflow will build an image with the required changes, and then a second workflow will create another pod with a binary (the Tigera CLI scanner) which will look for vulnerabilities in this new image. Those scan results will be sent to Calico Cloud, so we will have not just the option of seeing those, but Calico Cloud will report if any running container is using such image in case we did not implement our Admission Controller before they were deployed:

![Screenshot of Calico Cloud's image scanning results, showing a "fail" status and critical CVEs found in a scanned image](https://www.tigera.io/app/uploads/2023/05/image2-2.png)

- Finally, ArgoCD will try to deploy the required applications with the new image based on what is defined in the repo it syncs from.

- Beforehand, we applied an “admissioncontainerpolicy” resource that Calico manages. This webhook will prevent deploying any image that does not meet the criteria outlined in the previous section (“Relevant Calico configuration”). In our example, the applied policy will prevent the image if there is any vulnerability which has a CVSS score above the threshold of what will be considered a “Warn” value. We can see that for a failing test case, we will have a relevant entry in the application controller:

 

```
`% kubectl logs -n argocd argocd-application-controller-0 | grep Reject | tail -1 time="2023-03-29T09:47:20Z" level=info msg="Updating operation state. phase: Running -> Failed, message: 'one or more tasks are running' -> 'one or more objects failed to apply, reason: admission webhook "image-assurance.www.tigera.io" denied the request: Action 'Reject' enforced by ContainerPolicy reject-failed rule index 1'" application=argocd/java-app syncId=00014-WkFyP`
```

And the relevant application will be shown as “Out of sync” in ArgoCD:

![ArgoCD UI showing "java-app" as "OutOfSync" and "Syncing," while "java-client" is "Healthy" and "Synced](https://www.tigera.io/app/uploads/2023/05/image4-1.png)

## Conclusion

Cloud native applications often rely on open source software and libraries, which can pose a significant threat to the security of your Kubernetes environment. The widespread use of these components means that a single vulnerability can quickly spread throughout your system. Fortunately, Calico Cloud offers a solution by preventing dangerous images from being deployed at build time through close integration with your CI/CD pipeline.

If you’re interested in learning more about how Calico Cloud can help secure your Kubernetes environment, we invite you to watch our brief [3-minute video](https://tigera.wistia.com/medias/d4sy2ll2qr). This video will guide you through the necessary steps to integrate Calico Cloud into your CI/CD pipeline.

Ready to get started? [Try a free trial](https://link.tigera.io/ueOp4).

[How-To](https://www.tigera.io/tags/how-to/)

## Related posts

[![Save the Address, Save the Cloud: A Hands-on KubeVirt Live Migration Workshop](https://www.tigera.io/app/uploads/2026/07/Save-the-Address-Save-the-Cloud-A-Hands-on-KubeVirt-Live-Migration-Workshop.png)](https://www.tigera.io/blog/save-the-address-save-the-cloud-a-hands-on-kubevirt-live-migration-workshop/)

#### [Save the Address, Save the Cloud: A Hands-on KubeVirt Live Migration Workshop](https://www.tigera.io/blog/save-the-address-save-the-cloud-a-hands-on-kubevirt-live-migration-workshop/)

By [Reza Ramezanpour](https://www.tigera.io/blog/author/rezar/)
on Jul 9, 2026

In the previous post in this series, we covered why Virtual Machine (VM) Live Migration in Kubernetes is difficult: a VM’s IP is its identity, and the “new” VM on the destination node has to...

[Read more](https://www.tigera.io/blog/save-the-address-save-the-cloud-a-hands-on-kubevirt-live-migration-workshop/)

[![KubeVirt Networking: How to Preserve VM IP Addresses During Migration](https://www.tigera.io/app/uploads/2026/04/KubeVirt-Networking-How-to-Preserve-VM-IP-Addresses-During-Migration-1-1.png)](https://www.tigera.io/blog/kubevirt-networking-how-to-preserve-vm-ip-addresses-during-migration/)

#### [KubeVirt Networking: How to Preserve VM IP Addresses During Migration](https://www.tigera.io/blog/kubevirt-networking-how-to-preserve-vm-ip-addresses-during-migration/)

By [Dillon Barry](https://www.tigera.io/blog/author/dillon-barry/)
on Apr 21, 2026

Organisations are re-evaluating their VM infrastructure. The economics have shifted, the tooling has matured, and the case for running two separate platforms, one for containers, one for VMs, is getting harder to justify. Platform teams...

[Read more](https://www.tigera.io/blog/kubevirt-networking-how-to-preserve-vm-ip-addresses-during-migration/)

[![How to Stub LLMs for AI Agent Security Testing and Governance](https://www.tigera.io/app/uploads/2026/04/How-to-Stub-LLMs-for-AI-Agent-Security-Testing-and-Governance.png)](https://www.tigera.io/blog/how-to-stub-llms-for-ai-agent-security-testing-and-governance/)

#### [How to Stub LLMs for AI Agent Security Testing and Governance](https://www.tigera.io/blog/how-to-stub-llms-for-ai-agent-security-testing-and-governance/)

By [Alister Baroi](https://www.tigera.io/blog/author/alister-baroi/)
on Apr 2, 2026

Note: The core architecture for this pattern was introduced by Isaac Hawley from Tigera. If you are building an AI agent that relies on tool calling, complex routing, or the Model Context Protocol (MCP), you’re...

[Read more](https://www.tigera.io/blog/how-to-stub-llms-for-ai-agent-security-testing-and-governance/)

<!-- plugin=object-cache-pro client=phpredis metric#hits=3173 metric#misses=33 metric#hit-ratio=99.0 metric#bytes=1555153 metric#prefetches=0 metric#store-reads=169 metric#store-writes=18 metric#store-hits=169 metric#store-misses=22 metric#sql-queries=35 metric#ms-total=618.43 metric#ms-cache=41.38 metric#ms-cache-avg=0.2225 metric#ms-cache-ratio=6.7 sample#redis-hits=40859100 sample#redis-misses=11456926 sample#redis-hit-ratio=78.1 sample#redis-ops-per-sec=114 sample#redis-evicted-keys=0 sample#redis-used-memory=93447392 sample#redis-used-memory-rss=92741632 sample#redis-memory-fragmentation-ratio=1.0 sample#redis-connected-clients=1 sample#redis-tracking-clients=0 sample#redis-rejected-connections=0 sample#redis-keys=42198 -->
