Cloud Native Diary #2

Excellent feedback for Cloud Native Spring in Action, supply chain security (SLSA, Sigstore), images (Buildpacks, kpack, Paketo), and platforms.

A container ship sailing at sunset

In Cloud Native Diary, I weekly share my journey working with application development, platform engineering, and cloud native technologies.

This past week has been great! Excellent feedback from the readers of my book, various tasks on supply chain security (SLSA, Sigstore, SBOMs), refinement of image building (Buildpacks, kpack, Paketo), and work on platform engineering.

"Cloud Native Spring in Action" has shipped

In the past few days, people have started receiving the printed copy of my book "Cloud Native Spring in Action," and it's been amazing to receive such great feedback. I'm so thankful for that!

Special thanks to Dan Vega and DaShaun Carter for recommending the book in the latest episode of their Spring Office Hours show. Every week, they "review the current news, demo a Spring related project they find interesting and answer any questions you might have". I've much appreciated them including my book in their news. If you work with Java and Spring, I recommend watching their fantastic show!

๐Ÿƒ
Until December 15th, you can use this code here to get 45% off my book (valid for any format): pbvitale.

SLSA Provenance, Artifact Integrity and GitHub

Imagine you find the perfect service to add specific features to your system in production. You can install the service as an OCI image. How can you be sure that the image is legit and has not been tampered with?

Software artifact integrity is the main problem that SLSA aims to solve. SLSA (Supply chain Levels for Software Artifacts) is a framework for improving the integrity of software packages by adding the necessary controls and safeguards to prevent tampering.

An essential part of the framework is producing provenance data so that it's possible to trace a software artifact back to its source and build process. The community behind SLSA has been working on a SLSA Provenance Generator for GitHub. In particular, they recently released the first GA version of the provenance generator for container images according to SLSA level 3.

This week, I started using that in my projects. You can find an example in my Band Service repository, where several aspects of supply chain security are showcased. After building my Band Service application as an OCI image using Cloud Native Buildpacks, I sign it with Sigstore cosign and finally generate the provenance data using the SLSA generator (as shown in the following snippet).

provenance:
    needs: [sign]
    permissions:
      actions: read
      id-token: write
      packages: write
    uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.4.0
    with:
      image: ${{ needs.sign.outputs.image-name }}
      digest: ${{ needs.sign.outputs.image-digest }}
      registry-username: ${{ github.actor }}
    secrets:
      registry-password: ${{ secrets.GITHUB_TOKEN }}

All OCI images released for my Band Service application are signed and provide provenance data. Using cosign, we can verify both.

Let's consider, for example, the artifact ghcr.io/thomasvitale/band-service@sha256:388e8d292b55a7934bdaf11277ea9f33c3533258de92eb4b12085717dbdbd875. It's been signed using the keyless strategy provided by cosign. Let's verify the signature is authentic.

COSIGN_EXPERIMENTAL=1 cosign verify ghcr.io/thomasvitale/band-service@sha256:388e8d292b55a7934bdaf11277ea9f33c3533258de92eb4b12085717dbdbd875 | jq '.[0]'

Keyless signing is still an experimental feature of cosign, which is why we need to enable it explicitly by setting the COSIGN_EXPERIMENTAL environment variable.

Next, let's verify and retrieve the provenance data attached to the OCI image by the SLSA generator and signed with cosign.

COSIGN_EXPERIMENTAL=1 cosign verify-attestation --type slsaprovenance ghcr.io/thomasvitale/band-service@sha256:388e8d292b55a7934bdaf11277ea9f33c3533258de92eb4b12085717dbdbd875 | jq '.payload |= @base64d | .payload | fromjson'

The provenance data is structured as an in-toto attestation, a standard format representing "authenticated metadata about a set of software artifacts".

I'm currently working on a series of articles about supply chain security, where I'll expand further on SLSA, Sigstore cosign, and more. Feel free to reach out if you'd like me to cover specific topics or tools in this area. You can leave a comment under this article or text me on Twitter, LinkedIn, or Mastodon.

Buildpacks, Kpack and Supply Chain Security

If you have ever followed one of my conference talks, you probably caught me talking about Cloud Native Buildpacks, a CNCF specification to transform application source code into production-ready container images without a Dockerfile.

Some of the main features of Buildpacks are the focus on security, efficiency, compliance, and reproducibility. No matter the language or framework used for your application, you can produce an OCI image with the same exact operation, such as via the pack CLI. No further configuration is needed.

pack build ghcr.io/thomasvitale/band-service

I commonly use the Paketo Buildpacks that provide extended polyglot support and production-grade results.

Several tools provide support for Cloud Native Buildpacks, such as Tekton and Knative. When working with Spring Boot applications, you don't even need to download additional tools because Buildpacks is integrated out-of-the-box in the Spring Boot plugin for Maven and Gradle. If you want to package a Spring Boot application as an OCI image, you can simply run the following command.

./gradlew bootBuildImage

For my personal projects available on GitHub, I commonly use the pack CLI or the Spring Boot plugin when I need to build container images. When working on Kubernetes, others options are available. For example, Tekton could be used to build a continuous delivery pipeline instead of GitHub Actions and rely on the Buildpacks support available through the Tekton Catalog.

A more Kubernetes-native solution is provided by kpack, a container build service based on Cloud Native Buildpacks. Following the Kubernetes resource model, I can provide a declarative configuration about the application I want to build, and kpack starts monitoring the related Git repository. Whenever a new change is submitted to the repository, kpack builds a new container image and pushes it to the configured container registry.

apiVersion: kpack.io/v1alpha2
kind: Image
metadata:
    name: band-service
spec:
    tag: ghcr.io/thomasvitale/band-service
    serviceAccountName: build-sa
    builder:
        kind: ClusterBuilder
        name: paketo
    source:
        git:
            url: https://github.com/ThomasVitale/band-service
            revision: main

One of the benefits of kpack is ensuring a clear separation of concerns between application developers and the platform teams, allowing them to centralize and enforce security and compliance based on the organization's policies while providing a superior developer experience.

Let's talk about supply chain security now. Kpack is already integrated with cosign to sign the container images it builds for the given applications. The missing step is to sign the OCI images built as part of the kpack setup (builders and stacks). There is an open issue on GitHub to add this functionality and a draft pull request. I hope it will be addressed soon.

Earlier I talked about SLSA and how to generate provenance data when software artifacts are built via GitHub Actions. What happens when we use kpack instead? Currently, the project doesn't provide a way to obtain unfalsifiable provenance data and reach SLSA level 3. I have created an issue on the kpack GitHub project to propose adding such a feature and start a conversation to see if it's something that the community would be interested in. Feel free to share your thoughts on the GitHub issue.

Another feature offered by Cloud Native Buildpacks is support for SBOM (Software Bill of Materials) generation. It's common to generate a SBOM after the build process is completed. The risk is to miss out on some libraries or dependencies since the SBOM generation tool doesn't have complete knowledge about how the artifact was built. A better way is generating SBOMs as part of the build process, which is what Buildpacks does.

Let's consider the previous Band Service example. I used the Paketo Buildpacks to containerize my application. Among other things, Paketo takes care of generating a SBOM for each layer of the final OCI image as part of the build process. The SBOMs are included in the image itself and can be extracted using the pack CLI (make sure you pull the image first).

pack sbom download ghcr.io/thomasvitale/band-service --output-dir sboms

Having the SBOMs generated automatically as part of the build process is highly convenient. However, the way they are consumed is specific to Buildpacks and can make it a bit more challenging to integrate with other tools in the supply chain security space (for example, when we need to pass a SBOM to a vulnerability scanner like Trivy). For that reason, I have opened another issue on the kpack project to consider adding a new feature that gathers all the SBOMs generated during the build process and collects them in a standard in-toto attestation which is signed and published, similar to SLSA provenance attestations. Once again, feel free to share your thoughts on the GitHub issue.

I'll conclude this section by mentioning that the Cloud Native Buildpacks project has not yet achieved full support for ARM64 architectures, so it's up to the specific implementations to provide the missing pieces. If you work on an Apple Silicon computer or Raspberry Pi, I recommend following the fantastic work that DaShaun Carter has been doing on top of Paketo to support those architectures.

CNCF Platforms WG

This week, I continued collaborating on the initial document on cloud native platforms with the CNCF Platforms Working Group. We had a quite interesting conversation on platform APIs (user-facing vs. internal), what are the essential categories of capabilities that a platform should offer, and the likely need for more than one platform team in larger organizations. You can follow the work of the group by joining the #wg-platforms channel in the CNCF Slack.

Cover picture by Pexels.