Using Witness for Software Supply Chain Security in Non‑GitHub Environments
This article explains how to generate and verify software artifact provenance with the Witness framework in non‑GitHub ecosystems, covering installation, key creation, configuration, running, signing, and policy verification to achieve higher SLSA levels.
What is Witness
Witness is a pluggable supply‑chain security framework that creates provenance evidence for the entire software development lifecycle (SDLC), ensuring integrity from source code to final artifact. It integrates with most CI and infrastructure providers and enhances security through PKI‑based metadata distribution and verification.
What Witness Can Do
Verify who built the software, how it was built, and which tools were used.
Detect potential tampering or malicious activity.
Ensure that only authorized users or machines can perform each step of the process.
Distribute attestations and policies.
How to Use Witness
The workflow consists of three main commands:
witness run – Execute a command and record an attestation.
witness sign – Sign the generated files with a private key.
witness verify – Verify the attestation against a policy.
Quick Start
Install Witness and clone the demo repository:
bash <(curl -s https://raw.githubusercontent.com/in-toto/witness/main/install-witness.sh)
Latest version of Witness is 0.1.14
Downloading for linux amd64 from https://github.com/in-toto/witness/releases/download/v0.1.14/witness_0.1.14_linux_amd64.tar.gz
expected checksum: f9b67ca04cb391cd854aec3397eb904392ff689dcd3c38305d38c444781a5a67
file checksum: f9b67ca04cb391cd854aec3397eb904392ff689dcd3c38305d38c444781a5a67
witness v0.1.14-aa35c1f
Witness v0.1.14 has been installed at /usr/local/bin/witness
git clone https://github.com/shenxianpeng/witness-demo.gitCreate an Ed25519 key pair for signing:
openssl genpkey -algorithm ed25519 -outform PEM -out witness-demo-key.pem
openssl pkey -in witness-demo-key.pem -pubout > witness-demo-pub.pemPrepare the Witness Configuration File (.witness.yaml)
run:
signer-file-key-path: witness-demo-key.pem
trace: false
verify:
attestations:
- "witness-demo-att.json"
policy: policy-signed.json
publickey: witness-demo-pub.pemRecord Build Steps as Attestations
witness run --step build -o witness-demo-att.json -- python3 -m pip wheel --no-deps -w dist .
INFO Using config file: .witness.yaml
INFO Starting environment attestor...
INFO Starting git attestor...
INFO Starting material attestor...
INFO Starting command-run attestor...
Processing /tmp/witness-demo
Building wheels for collected packages: witness-demo
Running setup.py bdist_wheel for witness-demo: started
Running setup.py bdist_wheel for witness-demo: finished with status 'done'
Stored in directory: /tmp/witness-demo/dist
Successfully built witness-demo
INFO Starting product attestor...Insert witness run into any build command to capture its provenance.
View the Signed Attestation
Attestation data is base64‑encoded; decode it to inspect:
cat witness-demo-att.json | jq -r .payload | base64 -d | jq
# Sample output (truncated)
{
"type": "https://witness.dev/attestations/command-run/v0.1",
"attestation": {
"cmd": ["python3","-m","pip","wheel","--no-deps","-w","dist","."],
"stdout": "Processing /tmp/witness-demo\n...\nSuccessfully built witness-demo\n",
"exitcode": 0
},
"starttime": "2023-11-29T05:15:19.227943473-05:00",
"endtime": "2023-11-29T05:15:20.078517025-05:00"
},
{ ... product attestation ... }Create a Policy File (policy.json)
The policy defines required attributes for each step, such as an expiration time:
{
"expires": "2033-12-17T23:57:40-05:00",
"steps": {
"build": {
"name": "build",
"attestations": [
{"type": "https://witness.dev/attestations/material/v0.1", "regopolicies": []},
{"type": "https://witness.dev/attestations/command-run/v0.1", "regopolicies": []},
{"type": "https://witness.dev/attestations/product/v0.1", "regopolicies": []}
],
"functionaries": [{"publickeyid": "{{PUBLIC_KEY_ID}}"}]
}
},
"publickeys": {
"{{PUBLIC_KEY_ID}}": {"keyid": "{{PUBLIC_KEY_ID}}", "key": "{{B64_PUBLIC_KEY}}"}
}
}Replace the placeholders with the actual public‑key ID and base64‑encoded key:
id=$(sha256sum witness-demo-pub.pem | awk '{print $1}') && \
sed -i "s/{{PUBLIC_KEY_ID}}/$id/g" policy.json
pubb64=$(cat witness-demo-pub.pem | base64 -w 0) && \
sed -i "s/{{B64_PUBLIC_KEY}}/$pubb64/g" policy.jsonSign the Policy
witness sign -f policy.json --signer-file-key-path witness-demo-key.pem --outfile policy-signed.json
INFO Using config file: .witness.yamlVerify an Artifact Against the Policy
witness verify -f dist/witness_demo-1.0.0-py3-none-any.whl -a witness-demo-att.json -p policy-signed.json -k witness-demo-pub.pem
INFO Using config file: .witness.yaml
INFO Verification succeeded
INFO Evidence:
INFO 0: witness-demo-att.jsonConclusion
The steps above demonstrate how to apply Witness for supply‑chain provenance in projects that are not hosted on GitHub. For GitHub‑hosted projects, the most common approach is to use the slsa‑github‑generator and slsa‑verifier tools provided by the SLSA Framework.
DevOps Engineer
DevOps engineer, Pythonista and FOSS contributor. Created cpp-linter, commit-check, etc.; contributed to PyPA.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.