4 min read

Project Copacetic: Quick and efficient container image patching

Maintaining secure container images is a major supply chain challenge due to the need to address new vulnerabilities quickly. As security threats evolve, it is crucial to keep container images up to date. 

When it comes to patching images, users currently face two main options. The first is to wait for updates from third-party authors. This process can be slow, particularly for images that have multiple publishers involved. The second option involves performing a full image rebuild. While this approach allows for more immediate control over the update process, it comes with its own set of challenges. Rebuilding images from scratch is not only time-consuming but also demands significant computational resources. 

Project Copacetic (Copa), a Cloud Native Computing Foundation (CNCF) sandbox project, enhances the image patching process, reducing turnaround time and complexity. It integrates easily into existing build infrastructure, giving users greater control over their patching timeline and reducing costs. Copa is a CLI tool written in Go and based on BuildKit (Docker’s default builder) that can be used to directly patch container images by upgrading all outdated packages or performing targeted updates given the vulnerability scanning results from popular tools like Trivy

Graph showing the architecture overview of the workflow of Project Copacetic, starting with the container image, generating and parsing a vulnerability report, and then outputting patched image.

If choosing the targeting patching route over upgrading all packages, Copa uses vulnerability reports generated by scanning tools. It extends its capabilities through support for custom plug-ins through scanner templates. This flexibility allows Copa to integrate with a variety of scanners beyond the default Trivy.  

By parsing the scan reports, or by checking for all outdated packages, Copa identifies essential operating system (OS) level package updates and applies them directly to the target image using BuildKit. This process creates a new patch layer on top of the original image. Copa can even patch distro-less images by leveraging external tooling.

Until recently, Copa could be used locally, called in custom pipelines, or integrated in GitHub Workflows using the Copa GitHub Action. However, one of our primary goals is to make Copa accessible to as many people as possible. We’ve taken a significant step towards this by introducing the Copa Docker Desktop extension, which allows you to scan, tag, and patch new images without needing any command line experience.

Project Copacetic

Directly patch container image vulnerabilities quickly without going upstream for a full rebuild.

Developer looking at code

Copa Extension

Homepage of Copa Docker Extension, with the Copa logo and an input for image to be patched.

The Copa Extension utilizes Docker Desktop, a graphical user interface (GUI) for managing containers and images directly from your machine, and Docker Desktop Extensions, which allows you to integrate third-party tools into Docker Desktop. The only requirement to use this extension is Docker Desktop. After installing it, simply search for the extension on Docker Marketplace to install the extension. 

How do you use the extension?  

When you open the extension, you’ll see an input field for an image and a combo box for selecting a scanner. If you have any locally stored images that need patching, they will be automatically pulled and listed in the dropdown to autofill the input. (Note: in order to patch local images, you must have the containerd image store feature enabled within Docker.) You can also supply custom remote images stored in a registry. Next, choose a scanner and click the “scan” button to start scanning the selected image. The scan results will be displayed in a simple, user-friendly format inspired by the Docker Scout vulnerability display. 

Based on the scan results, you can decide whether to patch the image. If you choose to proceed, click the “patch” button to initiate a Copa scan. You’ll see a loading screen, where you can optionally view the command line output of the Trivy scan and Copa patch operations. If the scan fails, you will see an error screen that describes what went wrong during the patching operation. Additionally, you can still view the command line output to determine the error. If the patch succeeds, you will see a success screen along with the name of the new patched image. You can optionally run another scan on the new patched image to ensure all fixable OS-level vulnerabilities have been resolved. 

How does it work? 

Under the hood, the extension is a front end written in React with the Material UI component library. It utilizes the extension API client, a tool that allows full interaction with the Docker CLI from the front end, to manage three image containers throughout the lifetime of the extension. It creates a Trivy container to perform scans of images, a BusyBox container to send the scan info to the front end, and a Copa container to run the patching operation. During the loading screen, the user can optionally view the command line output of the containers by clicking an arrow next to the loading text. This is achieved by streaming the output of the containers to a callback function that updates a React state variable each time new output is generated. 

Get involved 

You can try out the Copa extension right now on the Docker marketplace. We value your feedback and welcome any suggestions from the community. If you’re interested in contributing, please review our contribution document to set up the correct development environment. Additionally, our GitHub issues page offers various ways to get involved, such as adding support for no-scanner inputs or displaying Copa’s vex outputs. 

For any questions about Copa, you can reach out to us on the CNCF Slack or attend our on-demand bi-weekly community meetings. We encourage all contributions and suggest starting with issues labeled “good first issue” on GitHub if you’re new to the project. We look forward to your involvement.


Authorship note: This blog post was co-authored by Jackson Greer (LinkedIn, GitHub), who was an intern on the team. Thanks to Jackson for his work!