4/11/2024
Announcing the Witness GitLab Component
Author: Mikhail Swift
Reduce Friction in Your Security Architecture with the Witness GitLab Component
Next week, I will be at the Open Source Summit North America, engaging with community members about attestations and demonstrating how you can OBSERVE, MANAGE, & ACT on software supply chains to align with government baselines using a unified developer and cybersecurity governance experience.
At TestifySec, our mission is to make attestations as frictionless as possible for as many developers and teams as possible. To support this goal, we are excited to introduce two significant initiatives: an official Witness GitLab CI/CD component streamlining the generation of attestations in your GitLab CI/CD pipelines—and our new Judge AWS Marketplace offering. This offering simplifies the setup of essential infrastructure in a self-hosted GitLab environment. If attestations intrigue you, I hope to meet you in Seattle to discuss them further!
Why Do You Need Attestations?
For several years, the security industry has been abuzz with discussions on supply chain security and new guidance such as SSDF - Secure Software Development Framework and NIST 800-204D - Strategies for the Integration of Software Supply Chain Security in DevSecOps CI/CD Pipelines. Supply chain security encompasses two primary concerns: the provenance of a software artifact—our level of assurance about its origins and the integrity of its build and transmission processes—and the somewhat nebulous concept of the trustworthiness or reliability of an artifact—addressing whether the software performs any malicious actions or contains significant vulnerabilities.
These concerns are more closely related than they might seem initially. To ascertain an artifact's trustworthiness or reliability, it must be evaluated through activities such as Static application security testing (SAST) or Dynamic application security testing (DAST), scanning and inspection of its dependency tree for CVEs. This prompts a further question: "How can I be sure that the scans presented to me correspond to the artifact in question?" This question underpins the rationale for an SBOM: it seeks to immutably link a precisely specified list of components to a specific software artifact (also precisely specified via its hash value), providing reliable evidence of the artifact's composition.
An attestation is a signed record of actions performed during a specific stage in the build process. For example, one can "attest" that an SBOM was generated during the build process by documenting the environment's state before and after the SBOM's generation, along with the command used for its creation. All this information, coupled with the SBOM itself, can be interconnected through signing, forming a chain of custody that can be cryptographically verified to prove the SBOM's association with the software artifact. These attestations enable trust in the SBOM as a reliable source of information about the software artifact's contents, facilitating decisions about the artifact's trustworthiness based on its components.
Attestations introduce a level of rigor into the software supply chain process, significantly enhancing software supply chain security. This is particularly relevant for those required to document their supply chain security measures transparently, including entities with high compliance requirements, those working within or alongside the government, or industries under strict regulation. Attestations facilitate compliance through their "chain of custody" feature, offering cryptographic evidence that compliance requirements have been met.
Moreover, attestations can automate cybersecurity requirement enforcement at deployment, allowing tools like admission controllers to verify compliance. The automation and enforcement characteristics create a bond that unifies development and cybersecurity teams. When combined to create attestations predicated upon trusted telemetry, both developers and cybersecurity teams benefit from the high assurance of the software's state in their environments. It concurrently eases the deployment process for developers and yet increases the trust in guardrails defined by cybersecurity policies.
How to Produce Frictionless Attestations with Witness and GitLab CI/CD
Historically, creating attestations has been a complex process. This challenge led us to develop Witness, aiming to enable everyone to generate attestations in the most frictionless manner possible. We are thrilled to further streamline this experience with the introduction of the Witness GitLab CI/CD component
A GitLab CI/CD component represents an advancement of GitLab CI/CD's robust support for repeatable and reusable building blocks, facilitating cross-organizational sharing of CI/CD job templates. By specifying an
include: component
in your .gitlab-ci.yml
, you can import a templated job from a public registry of components, simplifying its implementation in your pipelines.Generating Attestations with Witness and SigStore in GitLab CI/CD
Our Witness component facilitates the creation of attestations within your CI/CD pipeline, integrating seamlessly with Sigstore for the secure and verifiable signing of
artifacts. Here's how to set up a basic job in your
.gitlab-ci.yml
to generate attestations with Sigstore for a go vet
operation, commonly used in Go project pipelines to analyze source code for potential issues:include: - component: gitlab.com/testifysec/cicd-components/witness-run inputs: stage: test step: vet image: registry.gitlab.com/testifysec/test-image:latest command: go vet ./...git
This example showcases the integration of Sigstore for secure attestation signing within a GitLab CI/CD pipeline, thereby enhancing the security and trustworthiness of your software supply chain through verifiable and cryptographically signed attestations.
The
command
variable is used to specify the command Witness should encapsulate to generate the attestation. This should be a single line command; more complex commands ought to be scripted and stored in your repository. Ensure the use of the artifactsFrom
directive in your Witness policy to confirm the script originates from your repository.By default, attestations will be signed using SigStore’s public "keyless" signing workflow, which is suitable for jobs run on public GitLab instances. However, the OIDC handshake enabling this keyless signing may not function on private GitLab instances, especially those without access to the public SigStore. In such scenarios, you have options. One is specifying KMS signing keys like this:
signer-kms-ref: "awskms:///arn:aws:kms:us-east-2:123456789012:key/a5b221b2-1670-4c6d-1234-135cb29a0ad5"
Alternatively, consider deploying your instance of Fulcio (the certificate authority for SigStore) to manage signing with your OIDC infrastructure. TestifySec simplifies this with our Judge AWS Marketplace offering and enterprise support, establishing the keyless signing infrastructure within your AWS environment. Inform Witness of this infrastructure using the
fulcio
variable.By default, attestations output to stdout. You may specify an output file by adding
out: filename
to the job variables. To upload attestations to our public Archivista instance, add Archivista: address
to the include options block, functioning on any GitLab instance with internet access. For self-hosted Archivista storage, use the archivista
variable. Archivista is open-source, with hosting simplified through the Judge AWS marketplace option.What Does the Attestation Look Like?
The attestation includes details like the pipeline URL, job URL, and digests for various elements, structured as follows:
- Subject information with pipeline and job URLs. You can use these to find attestations in Archivista.
- Predicate type indicating the collection version. If the attestors included in Witness do not fit your need, we make it easy to add additional predicate types
- Predicate details, including the step name and attestations related to the environment, Git, command run, and materials with their corresponding SHA256 hashes.
Here is an abridged decoded example, converted to YAML. An attestation in it's DSSE envelope can be viewed here you will need to make heavy use of
jq
and base64 -d
to make sense of it.subjects: - name: "pipelineurl:https://gitlab.com/testifysec/demos/swf/-/pipelines/1245126434" digest: {sha256: "aa2a39c...c92f217"} - name: "joburl:https://gitlab.com/testifysec/demos/swf/-/jobs/6577537216" digest: {sha256: "21d513f...80e89c2"} - name: "commithash:db66461ebc1ef76e1095c337dd6a9bef1093c248" digest: {sha1: "db66461ebc1ef76e1095c337dd6a9bef1093c248"} ... predicateType: "https://witness.testifysec.com/attestation-collection/v0.1" predicate: name: "vet" attestations: - type: "https://witness.dev/attestations/environment/v0.1" attestation: os: "linux" hostname: "runner-..." variables: CI_COMMIT_MESSAGE: "Feature update" ... - type: "https://witness.dev/attestations/git/v0.1" attestation: commithash: "db66461ebc1ef76e1095c337dd6a9bef1093c248" commitmessage: "Feature update" ... - type: "https://witness.dev/attestations/command-run/v0.1" attestation: cmd: ["go", "vet", "./..."] exitcode: 0 - type: "https://witness.dev/attestations/material/v0.1" attestation: ".git/HEAD": {sha256: "28d25bf82af4c0e2b72f50959b2beb859e3e60b9..."} "main.go": {sha256: "37623dc150ac04daec5e2f45ebab25d9f75265ac..."} ...
The next step is to act on this and other attestations created durring the pipeline run by creating a policy that links attestations from multiple steps and enforces their expected claims. The JUDGE platform automates the creation of complex policies to lower compliace and implimentation costs. This policy can be used in conjunction with our Open Policy Agent Data Provider to protect your Kubernetes cluster, or by using
witness verify
as a gating step in your pipeline.Get In Touch
If you find this intriguing and are in Seattle this week for the Open Source Summit North America, I'd love to discuss further. Reach out via email at info@testifysec.com, or contact the TestifySec team through our website at https://testifysec.com/contact.