Blog

Signing Open Container Initiative (OCI) Images Using Github Actions

Ensuring the authenticity and integrity of your container images is crucial to prevent security breaches. In this tutorial, we will guide you through the process of signing Docker containers using GitHub Actions and Cosign - a Sigstore tool designed for signing and verifying container images.

Author: Yolanda Robla
/
5 mins read
/
Aug 17, 2023

Container security is a critical priority in modern software development. The widespread adoption of containers offers higher flexibility and efficiency in deploying applications, but it also introduces potential security vulnerabilities that need to be addressed proactively. As more applications are packaged and distributed as containers, securing these containers becomes essential to prevent security breaches, data leaks, and unauthorized access to sensitive information.

Ensuring the authenticity and integrity of your container images is crucial to prevent security breaches. In this tutorial, we will guide you through the process of signing Docker containers using GitHub Actions and osign - a Sigstore tool designed for signing and verifying container images. In a follow-up post, we will take the next step and guide you through the process of validating the signature of OCI images using cosign and tracking the signatures using rekor transparency log.

What You'll Learn

In this tutorial, you'll learn how to configure GitHub Actions to automatically sign your container images upon pushing changes.

The only prerequisite is to have a valid GitHub repository containing a Dockerfile, in order to trigger a GitHub action to sign it and publish it to the GitHub registry.

You can see the overall flow here:

About the Sigstore Project

Sigstore is an initiative championed by the Linux Foundation and OpenSSF, which is designed to bring openness, accountability, and trust to software supply chains. It addresses the challenges of securing software artifacts by leveraging cryptographic verification and open standards to ensure provenance and transparency. Stacklok is a key contributor and supporter of the Sigstore project.

Sigstore consists of various components and functionalities, each contributing to its overarching mission, including:

Cosign: a component of Sigstore that provides the tooling necessary for container image signing and verification, employing cryptographic signatures to guarantee that image contents remain unaltered, fostering trust and security in deployed images. By integrating cosign into the software development pipeline, the process of signing images can be automated, fortifying the authenticity of your images and reinforcing your software security strategy.

Rekor: another key component of Sigstore that serves as an open, tamper-evident, and verifiable transparency log. Rekor is designed to store metadata about software artifacts, acting as a secure record for signed images. This transparency data facilitates tracking the lineage and authenticity of software artifacts over time. When an image is signed using Cosign, Rekor becomes the repository for vital information about the signed images, recording metadata such as signer’s identity and signature timestamp. This creates an audit trail that facilitates tracking and validation of the authenticity of signed images, ensuring that signed images are traceable, accountable and not altered. For more details on Rekor, check out this blog post from Stacklok’s CTO Luke Hinds.

Fulcio CA: component that serves as a Certificate Authority designed to enhance security and trust within software supply chains. It specializes in issuing X.509 certificates to developers, validating their identities and enabling them to sign container images securely.

Signing OCI images with Github Actions

GitHub Actions is an integrated platform within GitHub that enables developers to automate various tasks directly from their repositories, allowing users to create custom workflows defined in YAML files. These workflows can be triggered by events like pushes, pull requests, and releases.

GitHub Actions provides a wide range of pre-built actions, one of them being the Publish Docker Container action, that allows users to build, test and push Docker images to GitHub packages. The action can be enabled either via the GitHub user interface, or by creating the needed workflow file:

This will generate a docker-publish.yml under .github/workflows, that will contain the necessary actions to build, sign and publish images into Github Container Registry using cosign:

JavaScript
name: Docker

on:
...

env:
  # Use docker.io for Docker Hub if empty
  REGISTRY: ghcr.io
  # github.repository as...
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
      # This is used to complete the identity challenge
      # with sigstore/fulcio when running outside of PRs.
      id-token: write

    steps:
... 

      # Sign the resulting Docker image digest except on PRs.
      # This will only write to the public Rekor transparency log when the Docker
      # repository is public to avoid leaking data.  If you would like to publish
      # transparency data even for private images, pass --force to cosign below.
      # https://github.com/sigstore/cosign
      - name: Sign the published Docker image
        if: ${{ github.event_name != 'pull_request' }}
        env:
          # https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
          TAGS: ${{ steps.meta.outputs.tags }}
          DIGEST: ${{ steps.build-and-push.outputs.digest }}
        # This step uses the identity token to provision an ephemeral certificate
        # against the sigstore community Fulcio instance.
        run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}

As you can see from the workflow there is no key specified, because the signature is actually a keyless one. The container images are signed with a short-validity certificate from Fulcio, using a GitHub-provided OIDC token to authorize Fulcio to issue the cert, which removes the need to manage your own private key.

In the keyless signing process all the information from the GitHub workflow (e.g., username, organization name, repository) will be published into the Rekor public transparency log.

Following there is a sample run of the GitHub action, actually reflecting the procedure of signing the image and publishing into Rekor:

Conclusions

In this tutorial, we explored the process of securing container images using GitHub Actions and cosign. By signing images, we ensure their authenticity and integrity, preventing security breaches. This process is streamlined with GitHub Actions, eliminating manual intervention.

Some key points to remember:

  • · Image signing: Signing images is crucial for security. It guarantees that images are untampered and authentic, reducing the risk of breaches.

  • · Automated workflow: GitHub Actions automates image signing, seamlessly integrating it into your development pipeline. No manual intervention is required.

  • · Keyless signing: GitHub's OIDC issuer is used for signing, eliminating the need for private key management.

By following these steps, you can boost your container security, ensuring the trustworthiness of images in your software supply chain.

This Month in Minder - September 2024

This Month in Minder: September 2024

Stacklok /
Sep 26, 2024
Continue Reading
Flexible policy enforcement with Minder profile selectors

Flexible policy enforcement with Minder profile selectors

Dan Barr /
Sep 19, 2024
Continue Reading

Dependency hijacking: Dissecting North Korea’s new wave of DeFi-themed open source attacks targeting developers

Poppaea McDermott /
Sep 10, 2024
Continue Reading