Securing CI/CD Images with Cosign and OPA
Tags: kubernetes, containers, security, devops
Published: 2023-11-15 14:01:27

With the growing adoption of containers in modern development, ensuring the integrity of container images has become central to application deployment strategies. Rapid deployment offers agility, but it also presents security challenges. Container image signing addresses these challenges, allowing engineering teams to verify that the deployed images are authentic and unchanged.

However, an authentic image is just one piece of the puzzle. Making sure these images meet organizational standards is important, and policy engine tools are crucial for that. By establishing and enforcing clear guidelines, these tools pave the way for a secure and streamlined deployment workflow.

In essence, container image signing involves adding a digital stamp to an image, affirming its authenticity. This digital assurance guarantees that the image is unchanged from creation to deployment. In this blog, I'll explain how to sign container images for Kubernetes using [Cosign](https://github.com/sigstore/cosign) and the [Open Policy Agent](https://www.openpolicyagent.org/). I will also share a tutorial that demonstrates these concepts.

## Choosing the Right Tools for Image Signing and Verification

Choosing the right tools for container image signing and verification is important in CI/CD pipeline security. Let's walk through the available options to find the one that best meets your needs for securing container images.

### Image Signing and Verification Tools:

Notary v1, previously know as Docker Content Trust, uses [The Update Framework (TUF)](https://theupdateframework.io/) but has some issues with signature portability and storage. Though it established a solid foundation in image signing, it lacks some of the enhanced security features found in more recent tools.

[Grafeas](https://grafeas.io/): While Grafeas offers a comprehensive solution for the software development lifecycle, it is not designed for public or open-source software (OSS) image verification. It's better suited for first-party integration, particularly with Google Kubernetes Engine (GKE).

[Notary v2](https://github.com/notaryproject/notation): The evolution to Notary v2 brought improvements in signature portability and integration with third-party key management solutions. However, it does not provide a certificate authority, leaving public key discovery for open-source image verification as an unresolved issue.

[The Update Framework (TUF)](https://theupdateframework.io/): TUF is a framework, not a tool, designed to enhance the security of software update systems. It focuses on resilience against key compromises and attacks, employing verifiable records to verify the authenticity of update files. TUF's flexibility and integration ease make it a foundational element in securing software updates, though it's not a direct image signing tool like the others.

[Cosign](https://github.com/sigstore/cosign): In this context, Cosign from the Sigstore project offers a compelling solution. Its simplicity, registry compatibility, and effective link between images and their signatures provide a user-friendly and versatile approach. The integration of Fulcio for certificate management and Rekor for secure logging enhances Cosign's appeal, making it particularly suitable for modern development environments that prioritize security and agility.

Cosign's strength lies in its verification process, which is vital in the CI/CD pipeline. When integrated with policy engines like the Open Policy Agent (OPA), Cosign ensures not only the authenticity of container images but also their compliance with organizational standards. Additionally, Cosign provides enhanced support for SPIFFE, GitHub Actions, or service account identities, and it includes warnings for signing OCI images by tag, highlighting the risks associated with tag mutability.

### Policy Enforcement Options:

Open Policy Agent (OPA): OPA's strength lies in its ability to define fine-grained policies as code, offering granular control over policy enforcement. Integrated seamlessly with Kubernetes, it enforces policies in real-time, preventing unauthorized image deployments.

Kubernetes Admission Controllers: These controllers are a native part of the Kubernetes ecosystem, making them a straightforward choice for Kubernetes users. They excel at validating and enforcing policies for various Kubernetes resources, including pods, making them scalable for large deployments.

When choosing tools for container image signing and policy enforcement, it's important to balance functionality, scalability, and community support. Among the options discussed, Cosign and OPA (Open Policy Agent) stand out for their effectiveness in securing containerized applications.

Cosign simplifies the process of image signing and verification. It offers a user-friendly approach that caters to developers and security teams alike. With a growing user community and easy integration, it's a practical choice for securing container images.

OPA, on the other hand, excels in policy enforcement within Kubernetes environments. It enables you to define and enforce policies as code, granting you fine-grained control over image deployments.

In the upcoming section, let's delve into architectural diagrams and explore how the combination of Cosign and OPA offers a practical approach to sign and verify container images while enforcing them using a general policy engine.

## Architectural Diagrams: Securing Container Images and Deployment

Traditional cryptography uses public-private key pairs for signing and verifying images. However, modern practices, like cosign, prefer keyless signing. In this approach, an OIDC (OpenID Connect) provider is utilized, making the process more streamlined and secure, as it removes the complexities of key management.

The process starts with an architect selecting a trusted public base image as the foundation for their application. Let's dive into two distinct but interconnected flows that demonstrate how container image signing with Cosign and policy enforcement using Open Policy Agent (OPA) play a crucial role in ensuring a secure deployment pipeline.


![An architect is building a Secure Base Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fihn5p2rjnt1l2fwq9xz.png)

The process starts with an architect who selects a trusted Public Base Image as the foundation for their application. To ensure the image's integrity, the architect runs a vulnerability scanning process. This step identifies and addresses any security vulnerabilities within the base image.

Next, any unnecessary or unused components are removed from the image, minimizing potential attack vectors. The architect adds the necessary libraries, dependencies, and software packages required for the application to run efficiently. Then, the image undergoes rigorous security testing to ensure that it meets security standards and aligns with organizational policies.

The final step involves image signing with Cosign, a tool specifically designed for image signing. Cosign adds a digital stamp to the image, affirming its authenticity. This signature plays a crucial role in verifying the image's integrity during deployment. The signed image is then pushed to an artifact registry as a new, secure base image.


![A developer gets a YES/NO deployment decision based on `cosign verify` and OPA rules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ck6yhlgqlj5m8umc273p.png)

In the deployment phase, a developer selects a base image for their application, either an Unsigned Public Base Image or a Signed Public Base Image. If the developer chooses an Unsigned Public Base Image, the deployment process checks the image's signature and evaluates it against predefined policies using Open Policy Agent (OPA). Due to the lack of a valid signature, the image is Denied For Deployment.

On the other hand, if the developer opts for a Signed Public Base Image, the same verification and policy enforcement process is applied using OPA. This time, since the image has a valid signature, it is Allowed For Deployment.

## Hands-On: Deploying Secure Containers with Cosign and OPA

Having explored the strengths of Cosign and OPA for container image signing, you're now ready to apply these tools in a practical scenario. To get a real-world feel for how these technologies can enhance the security of your Kubernetes deployments, [follow this hands-on tutorial](https://developer.harness.io/tutorials/cd-pipelines/kubernetes/cosign-opa?utm_campaign=cd-devrel). It will guide you through the process of securely deploying container images using the combined capabilities of Cosign and OPA in your Kubernetes cluster. The Harness Software Supply Chain Assurance (SSCA) module addresses the challenges of securing your software supply chain, including image signing and verification. To explore how SSCA can enhance your pipeline security, [check it out](https://www.harness.io/products/software-supply-chain-assurance?utm_campaign=cd-devrel).