This is the multi-page printable view of this section. Click here to print.
Documentation
- 1: Overview
- 2: Attestors
- 2.1: AWS Instance Identity
- 2.2: Command
- 2.3: Environment
- 2.4: GCP Instance Identity
- 2.5: Git
- 2.6: GitLab
- 2.7: JWT
- 2.8: Material
- 2.9: Maven
- 2.10: OCI
- 2.11: Product
- 3: Config
- 4: Policy
- 5: Reference
- 5.1: Completion
- 5.2: Run
- 5.3: Sign
- 5.4: Verify
- 5.5: Version
1 - Overview
Witness is a pluggable framework for supply chain security
Witness prevents tampering of build materials and verifies the integrity of the build process from source to target. It works by wrapping commands executed in a continuous integration process. Its attestation system is pluggable and offers support out of the box for most major CI and infrastructure providers. Verification of Witness metadata and a secure PKI distribution system will mitigate against many software supply chain attack vectors and can be used as a framework for automated governance.
Witness is an implementation of the in-toto spec including ITE-5, ITE-6, ITE-7 with an embedded rego policy engine.
- Does NOT require elevated privileges.
- Can run in a containerized or non-containerized environment
- Records secure hashes of materials, artifacts, and events occurring during the CI process
- Integrations with cloud identity services
- Keyless signing with SPIFFE/SPIRE
- Support for uploading attestation evidence to rekor server (sigstore)
- Build policy enforcement with Open Policy Agent.
- Alpha support for tracing and process tampering prevention
- Verifies file integrity between CI steps, and across air gap.
- Experimental Windows and ARM Support
Usage
- Run - Runs the provided command and records attestations about the execution.
- Sign - Signs the provided file with the provided key.
- Verify - Verifies a witness policy.
TOC
- Witness Attestors
Getting Started
Download the Binary
curl -LO https://github.com/testifysec/witness/releases/download/${VERSION}/witness_${VERSION}_${ARCH}.tar.gz
tar -xzf witness_${VERSION}_${ARCH}.tar.gz
Create a Keypair
Witness supports keyless signing with SPIRE!
openssl genpkey -algorithm ed25519 -outform PEM -out testkey.pem
openssl pkey -in testkey.pem -pubout > testpub.pem
Create a Witness configuration
- This file generally resides in your source code repository along with the public keys generated above.
.witness yaml
is the default location for the configuration filewitness help
will show all configuration options- command-line arguments overrides configuration file values.
## .witness.yaml
run:
key: testkey.pem
trace: false
verify:
attestations:
- "test-att.json"
policy: policy-signed.json
publickey: testpub.pem
Record attestations for a build step
- The
-a {attestor}
flag allows you to define which attestors run- ex.
-a maven -a was -a gitlab
would be used for a maven build running on a GitLab runner on GCP.- Defining step names is important, these will be used in the policy.
- This should happen as a part of a CI step
witness run --step build -o test-att.json -- go build -o=testapp .
View the attestation data in the signed DSSE Envelope
- This data can be stored and retrieved from rekor!
- This is the data that is evaluated against the Rego policy
cat test-att.json | jq -r .payload | base64 -d | jq
Create a Policy File
Look here for full documentation on Witness Policies.
- Make sure to replace the keys in this file with the ones from the step above (sed command below).
- Rego policies should be base64 encoded
- Steps are bound to keys. Policy can be written to check the certificate data. For example, we can require a step is signed by a key with a specific
CN
attribute.- Witness will require all attestations to succeed
- Witness will evaluate the rego policy against the JSON object in the corresponding attestor
## policy.json
{
"expires": "2023-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 variables in the policy
id=`sha256sum testpub.pem | awk '{print $1}'` && sed -i "s/{{PUBLIC_KEY_ID}}/$id/g" policy.json
pubb64=`cat testpub.pem | base64 -w 0` && sed -i "s/{{B64_PUBLIC_KEY}}/$pubb64/g" policy.json
Sign The Policy File
Keep this key safe, its owner will control the policy gates.
witness sign -f policy.json --key testkey.pem --outfile policy-signed.json
Verify the Binary Meets Policy Requirements
This process works across air-gap as long as you have the signed policy file, correct binary, and public key or certificate authority corresponding to the private key that signed the policy.
witness verify
will return anon-zero
exit and reason in the case of failure. Success will be silent with a0
exit status for policies that require multiple steps, multiple attestations are required.
witness verify -f testapp -a test-att.json -p policy-signed.json -k testpub.pem
Witness Attestors
What is a witness attestor?
Witness attestors are pieces of code that assert facts about a system and store those facts in a versioned schema. Each attestor has a Name
, Type
, and RunType
. The Type
is a versioned string corresponding to the JSON schema of the attestation. For example, the AWS attestor is defined as follows:
Name = "aws"
Type = "https://witness.dev/attestations/aws/v0.1"
RunType = attestation.PreRunType
The attestation types are used when we evaluate policy against these attestations.
Attestor Security Model
Attestations are only as secure as the data that feeds them. Where possible cryptographic material should be validated, evidence of validation should be included in the attestation for out-of-band validation.
Examples of cryptographic validation is found in the GCP, AWS, and GitLab attestors.
Attestor Life Cycle
-
PreRun:
PreRun
attestors run before thematerial
attestor andcommandRun
attestors. These attestors generally collect information about the environment. -
Material Attestor: The
material
attestor is an internal attestor and runs immediately after -
CommandRun Attestor: The CommandRun attestor is an internal attestor. It has experimental tracing support that can be enabled with the
--trace
flag -
Product Attestor: The Product attestor collects the products produced by the
commandRun
attestor and calculates the secure hash, and makes the file descriptor available to thepostRun
attestors.
Attestation Lifecycle
Attestor Types
Pre Run Attestors
- AWS - Attestor for AWS Instance Metadata
- GCP - Attestor for GCP Instance Identity Service
- GitLab - Attestor for GitLab Pipelines
- Git - Attestor for Git Repository
- Maven Attestor for Maven Projects
- Environment - Attestor for environment variables (be careful with this - there is no way to mask values yet)
- JWT - Attestor for JWT Tokens
Internal Attestors
- CommandRun - Records traces and metadata about the actual process being run
- Material - Records secure hashes of files in current working directory
- Product - Records secure hashes of files produced by commandrun attestor (only detects new files)
Post Run Attestors
PostRun attestors collect have access to the files discovered by the product attestor. The purpose of PostRun attestors is to select metadata from the products. For example, in the OCI attestor the attestor examines the tar file and extracts OCI container meta-data.
- OCI - Attestor for tar’d OCI images
AttestationCollection
An attestationCollection
is a collection of attestations that are cryptographically bound together. Because the attestations are bound together, we can trust that they all happened as part of the same attesation life cycle. Witness policy defines which attestations are required.
Attestor Subjects
Attestors define subjects that act as lookup indexes. The attestationCollection can be looked up by any of the subjects defined by the attestors.
Witness Policy
What is a witness policy?
A witness policy is a signed document that encodes the requirements for an artifact to be validated. A witness policy includes public keys for trusted functionaries, which attestations must be found, and rego policy to evaluate against the attestation meta-data.
I witness policy allowers administrators trace the compliance status of an artifact at any point during it’s lifecycle.
Witness Verification
Verification Lifecycle
Using SPIRE for Keyless Signing
Witness can consume ephemeral keys from a SPIRE node agent. Configure witness with the flag --spiffe-socket
to enable keyless signing.
During the verification process witness will use the Rekor integrated time to make a determination on certificate validity. The SPIRE certificate only needs to remain valid long enough for the attestation to be integrated into the Rekor log.
Witness Examples
- Using Witness To Prevent SolarWinds Type Attacks
- Using Witness To Find Artifacts With Hidden Vulnerable Log4j Dependencies
Media
- Blog - What is a supply chain attestation, and why do I need it?
- Talk - Securing the Software Supply Chain with the in-toto & SPIRE projects
- Talk - Securing the Software Supply Chain with SBOM and Attestation
Roadmap
- Attestors for all major platforms
- CaC Card Attestor
- GovCloud Attestor
- OIDC Attestor
- FIDO Attestor
- Vault Key Provider
- Cloud KMS Support
- Kubernetes Admission Controller
- SIEM Collection Agent
- Cosign Signature Validation
- Notary v2 Signature Validation
- Zarf Integration
- IronBank Attestor
Support
TestifySec Provides support for witness and other CI security tools. Contact Us
1.1 -
2 - Attestors
2.1 - AWS Instance Identity
The AWS (Amazon Web Services) Instance Identity Attestor communicates with the AWS Instance Metadata to collect information about the AWS instance Witness on which executing. The document signature is verified with the AWS RSA public certificate available here. This verification method currently does not work for the Hong Kong, Bahrain, Cape Town, Milan, China, or GovCloud regions.
Subjects
Subject | Description |
---|---|
instanceid |
The ID of the AWS instance where Witness was executed |
accountid |
ID of the account that owns the AWS instance |
imageid |
ID of the AMI (Amazon Machine Image) the instance was running at time of execution |
privateip |
IP address of the instance at time of execution |
2.2 - Command
The Command Attestor collects information about a command that TestifySec Witness executes and observes. The command arguments, exit code, stdout, and stderr will be collected and added to the attestation.
Witness can optionally trace the command which will record all subprocesses started by the parent process as well as all files opened by all processes. Please note that tracing is currently supported only on Linux operating systems and is considered experimental.
2.3 - Environment
The Environment Attestor records the OS, hostname, username, and all environment variables set by TestifySec Witness at execution time. Currently there is no means to block specific environment variables so take care to not leak secrets stored in environment variables.
2.4 - GCP Instance Identity
The Google Cloud Platform (GCP) Instance Identity Attestor communicates with the GCP metadata server to collect information about the instance on which TestifySec Witness is being exected. The instance identity JSON Web Token signature is validated against Google’s JWKS (JSON Web Key Set) to ensure authenticity.
Subjects
Subject | Description |
---|---|
instanceid |
ID of the Google Compute instance on which Witness was executed |
instancename |
Name of the Compute instance on which Witness was executed |
projectid |
The ID of the project to which the instance belonged |
projectnumber |
Number of the project to which the instance belonged |
clusteruid |
UID of the cluster if the execution environment was a Google Kubernetes Engine (GKE) cluster |
2.5 - Git
The Git Attestor records the current state of the objects in the git repository, including untracked objects. Both staged and unstaged states are recorded.
Subjects
The attestor returns the SHA1 (Secure Hash Algorithm 1) git commit hash as a subject.
2.6 - GitLab
The GitLab Attestor records information about the GitLab CI/CD job execution in which
TestifySec Witness was run. Witness verifies the JWT (JSON Web Token) provided in CI_JOB_JWT
against the
instance’s JWKS (JSON Web Key Set) to ensure authenticity at execution time.
Subjects
Subject | Description |
---|---|
pipelineurl |
URL of the CI/CD pipeline to which this job belonged |
joburl |
URL of the CI/CD job that this attestor describes |
projecturl |
URL of the project that owns the CI/CD pipeline and job |
2.7 - JWT
The JWT (JSON Web Token) Attestor verifies a JWT against a JWKS (JSON Web Key Set) and records information about the claims of the JWT. The JWK that was used to verify the JWT is also recorded.
2.8 - Material
The Material Attestor records the digests of all files in the working directory of TestifySec Witness at exection time, but before any command is run. This recording provides information about the state of all files before any changes are made by a command.
2.9 - Maven
The Maven Attestor records project and dependency information from a provided pom.xml (Maven Project Object Model).
Subjects
Subject | Description |
---|---|
project:group/artifact@version |
The group, artifact, and version of the project to which the pom.xml belongs |
dependency:group/artifact@version |
The group, artifact, and verion of each dependency in the pom.xml |
2.10 - OCI
The OCI Attestor records information about a provided Open Container Initiative (OCI) image stored on disk as a tarball. Information about the image tags, layers, and manifest are collected and reported in this attestation.
Subjects
Subject | Description |
---|---|
tardigest |
Digest of the tarred image |
imageid |
ID of the image |
layerdiffid |
Layer diff IDs of the image |
2.11 - Product
Product Attestor
The Product Attestor examines materials recorded before a command was run and records all products in the command. Digests and MIME types of any changed or created files are recorded as products.
Subjects
All subjects are reported as subjects.
3 - Config
TestifySec Witness looks for the configuration file .witness.yaml
in the current directory.
Any values in the configuration file will be overridden by the command line arguments.
run:
attestations: stringSlice
certificate: string
intermediates: stringSlice
key: string
outfile: string
rekor-server: string
spiffe-socket: string
step: string
trace: bool
workingdir: string
sign:
certificate: string
datatype: string
intermediates: stringSlice
key: string
outfile: string
spiffe-socket: string
verify:
artifactfile: string
artifacthash: string
attestations: stringSlice
publickey: string
policy: string
4 - Policy
TestifySec Witness policies allow users to make assertions and test attestation collections generated during a Witness run
.
Examples of when a policy could be enforced include
- within a Kubernetes admission controller
- at the end of a CI/CD pipeline
- prior to image promotion, or
- before deployment to an execution environment.
Policies help you ensure that all expected attestations are within a collection and support embedded Rego policies to make determinations about the content of each attestation. Attestation signatures can be linked to trusted functionaries with embedded public keys or X.509 roots of trust.
Combining these powers, Witness policies ultimately allow users to make decisions automatically about the trustworthiness of an artifact. Details of who, how, when, and where an artifact was built can all be considered when evaluating policies.
Verification Process
Witness verify
will evaluate a set of attestation collections against a policy document. If the attestation
collections satisfy the policy, Witness will exit with an exit code of 0. Any other exit code indicates an error or
policy failure.
Evaluating a Witness policy involves a few different steps:
- Verify signatures on collections against public keys and trust roots within the policy. Any collections that fail signature verification will not be used.
- Verify the signer of each collection maps to a trusted functionary for the corresponding step in the policy.
- Verify that materials recorded in each collection are consistent with the artifacts (materials + products) of other collections as configured by the policy.
- Verify all rego policies embedded in the policy evaluate successfully against collections.
Schema
Policies are JSON documents that are signed and wrapped in DSSE envelopes. The DSSE payload type will be
https://witness.testifysec.com/policy/v0.1
.
policy
Object
Key | Type | Description |
---|---|---|
expires |
string | ISO-8601 formatted time. This key defines an expiration time for the policy. Evaluation of expired policies always fails. |
roots |
object | Trusted X.509 root certificates. Attestations that are signed with a certificate that belong to this root will be trusted. Keys of the object are the root certificate’s Key ID, values are a root object. |
publickeys |
object | Trusted public keys. Attestations that are signed with one of these keys will be trusted. Keys of the object are the public key’s Key ID, values are a publickey object. |
steps |
object | Expected steps that must appear to satisfy the policy. Each step requires an attestation collection with a matching name and the expected attestations. Keys of the object are the step’s name, values are a step object. |
root
Object
Key | Type | Description |
---|---|---|
certificate |
string | Base64 encoded PEM block that describes a valid X.509 root certificate. |
intermediates |
array of strings | Array of base64 encoded PEM blocks that describe valid X.509 intermediate certificates belonging to certificate |
publickey
Object
Key | Type | Description |
---|---|---|
keyid |
string | sha256sum of the public key |
key |
string | Base64 encoded public key |
step
Object
Key | Type | Description |
---|---|---|
name |
string | Name of the step. Attestation collections must share this name to be considered. |
functionaries |
array of functionary objects |
Public keys or roots of trust that are trusted to sign attestation collections for this step. |
attestations |
array of attestation objects |
Attestations that are expected to appear in an attestation collection to satisfy this step. |
artifactsFrom |
array of strings | Other steps that this step uses artifacts (materials & products) from. |
functionary
Object
Key | Type | Description |
---|---|---|
type |
string | Type of functionary. Valid values are “root” or “publickey”. |
certConstraint |
certConstraint object |
Object defining constraints upon the signer’s certificate for “root” functionaries. Only valid if type is “root”. |
publickeyid |
string | Key ID of a public key that is trusted to sign this step. Only valid if type is “publickey”. |
certConstraint
Object
Key | Type | Description |
---|---|---|
commonname |
string | Common name that the certifiate’s subject must have |
dnsnames |
array of strings | DNS names that the certificate must have |
emails |
array of strings | Email addresses that the certificate must have |
organizations |
array of strings | Organizations that the certificate must have |
uris |
array of strings | URIs that the certificate must have |
roots |
array of strings | Array of Key IDs the signer’s certificate must belong to to be trusted. |
Every attribute of the certificate must match the attributes defined by the constraint exactly. A certificate must match at least one constraint to pass the policy. Wildcards are allowed if they are the only element in the constraint.
Example of a constraint that would allow use of any certificate, as long as it belongs to a root defined in the policy:
{
"commonname": "*",
"dnsnames": ["*"],
"emails": ["*"],
"organizations": ["*"],
"uris": ["*"],
"roots": ["*"]
}
SPIFFE IDs are defined as URIs on the certificate, so a policy that would enforce a SPIFFE ID may look like:
{
"commonname": "*",
"dnsnames": ["*"],
"emails": ["*"],
"organizations": ["*"],
"uris": ["spiffe://example.com/step1"],
"roots": ["*"]
}
attestation
Object
Key | Type | Description |
---|---|---|
type |
string | Type reference of an attestation that must appear in a step. |
regopolicies |
array of regopolicy objects |
Rego policies that will be run against the attestation. All must pass. |
regopolicy
Object
Key | Type | Description |
---|---|---|
name |
string | Name of the rego policy. Will be reported on failures. |
module |
string | Base64 encoded rego module |
Rego modules are expected to output a data with the name of deny
in the case of a rego policy evaluation failure.
deny
can be a string or an array of strings and should be populated with a human-readable string describing why the
policy was denied. Any other data output by the module will be ignored.
Following is an example output for a valid rego policy:
package commandrun.exitcode
deny[msg] {
input.exitcode != 0
msg := "exitcode not 0"
}
Example
{
"expires": "2022-12-17T23:57:40-05:00",
"steps": {
"clone": {
"name": "clone",
"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": [
{
"type": "publickey",
"publickeyid": "ae2dcc989ea9c109a36e8eba5c4bc16d8fafcfe8e1a614164670d50aedacd647"
}
]
},
"build": {
"name": "build",
"artifactsFrom": ["clone"],
"attestations": [
{
"type": "https://witness.dev/attestations/material/v0.1",
"regopolicies": []
},
{
"type": "https://witness.dev/attestations/command-run/v0.1",
"regopolicies": [
{
"name": "expected command",
"module": "cGFja2FnZSBjb21tYW5kcnVuLmNtZAoKZGVueVttc2ddIHsKCWlucHV0LmNtZCAhPSBbImdvIiwgImJ1aWxkIiwgIi1vPXRlc3RhcHAiLCAiLiJdCgltc2cgOj0gInVuZXhwZWN0ZWQgY21kIgp9Cg=="
}
]
},
{
"type": "https://witness.dev/attestations/product/v0.1",
"regopolicies": []
}
],
"functionaries": [
{
"type": "publickey",
"publickeyid": "ae2dcc989ea9c109a36e8eba5c4bc16d8fafcfe8e1a614164670d50aedacd647"
},
{
"type": "root",
"certConstraint": {
"commonname": "*",
"dnsnames": ["*"],
"emails": ["*"],
"organizations": ["*"],
"uris": ["spiffe://example.com/step1"],
"roots": ["ae2dcc989ea9c109a36e8eba5c4bc16d8fafcfe8e1a614164670d50aedacd647"]
}
}
]
}
},
"publickeys": {
"ae2dcc989ea9c109a36e8eba5c4bc16d8fafcfe8e1a614164670d50aedacd647": {
"keyid": "ae2dcc989ea9c109a36e8eba5c4bc16d8fafcfe8e1a614164670d50aedacd647",
"key": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUNvd0JRWURLMlZ3QXlFQWYyOW9QUDhVZ2hCeUc4NTJ1QmRPeHJKS0tuN01NNWhUYlA5ZXNnT1ovazA9Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQo="
}
},
"roots": {
"949aaab542a02514f27f41ed8e443bb54bbd9b062ca3ce1da2492170d8fffe98": {
"certificate": "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURhekNDQWxPZ0F3SUJBZ0lVSnlobzI5ckorTXZYdGhGZjRncnV3UWhUZVNNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1JURUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2xOdmJXVXRVM1JoZEdVeElUQWZCZ05WQkFvTQpHRWx1ZEdWeWJtVjBJRmRwWkdkcGRITWdVSFI1SUV4MFpEQWVGdzB5TWpBeU1qTXlNalV4TkRoYUZ3MHlOekF5Ck1qSXlNalV4TkRoYU1FVXhDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwVGIyMWxMVk4wWVhSbE1TRXcKSHdZRFZRUUtEQmhKYm5SbGNtNWxkQ0JYYVdSbmFYUnpJRkIwZVNCTWRHUXdnZ0VpTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3VnVnNVYlV1cHB6S3ArOUxyckxLeGFrc0JlVTRiei9lQ0w1ZXo0bEppClFhcm1vcVRDeWI0WlVqVTNTSCsxYVdLSU9aM2kyeUZmL0hYRktNemh5SHFWZnpzbDVJUEo5TzVTR0huK3FldnoKVzBTMVdQeEN4MS9KdlFoUFNaQ21adWhaMmI5NFVYdXhCL2tSWGRiNnhYdnVReVFPMDYybTQrTkZWYVhBWWZjTQprVUlBSnpQTUZUSHhKOUQ1dWdaMWlSV0VHUUQ1d2kwNS9ZRG5yZHR3N2J3V3ZkOW4yL3c1UHUvUU1iVHZ4NWxlCnNFK2U1ZWZZd1NZLzBvT2dWRHBHVG9TVStpeDMrYWVlVjFSL1IvNm81NlJ0LzQ5eG9KWjF5bCtyQ3ByOUswN3AKL0FOSk9HTE5oYlRXVGp1N1lTSUxtbnYreVJwRUdUTnptU1lpNEFFTStZYm5BZ01CQUFHalV6QlJNQjBHQTFVZApEZ1FXQkJRemppS2pzR1NZNjUvNTFlQVJINVpEdXFIOUtEQWZCZ05WSFNNRUdEQVdnQlF6amlLanNHU1k2NS81CjFlQVJINVpEdXFIOUtEQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQmgKUXhBNWExMUJ4VXh6Q1hObDg4ZUxkaDg5NlNudkdwYkNTZVhxQzJKS0w2QkxHVHg4NC9SZmMxNzVyZ2VUTW9YcQpEWjA1Nm9xc1FPZ2czWVRXWEJDMTJJbmVnUW40Wm90L2cydWk3cTJOZ0NZNWNSSG9qZnhQd2JxbS9uU2k1eXNSClFCQTZuMUJ3cUlZclBpVVBvcE9YY1BIQVJ4SEwzUitIOHRpWCtyM1hRM3FZdnNuTUpOL3JlcGJOQjJKVi9TL28KT0llT1U5Y1RJRnRHNWNNd2RHcTdMeVlkK095NkRiNjN5aDNkNS82bEZOVElqdlZXaHhzS280U3dxZlhuOXY4TApia2xTOFB0Mm12MVMxa2thZGhMT1FqaGlBQ1N2UHB6OW5USXdXWTJUYTcvNGpFR0I3ZTF3aU8wZ0dhbFJhVXQyClpmYmt3eXFSQWxXUXNBcDJqZS8wCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
}
}
}
The embedded rego policy above is:
package commandrun.cmd
deny[msg] {
input.cmd != ["go", "build", "-o=testapp", "."]
msg := "unexpected cmd"
}
The above example policy requires that two attestation collections be present, one named “clone” and one named “build”. Both
collections must have a material, command-run, and product attestor within them. The command-run attestor for the
“build” collection must have recorded a command of go build -o=testapp .
to pass the embedded rego policy. The build
step is configured to ensure the materials used are consistent with the artifacts from the clone step, assuring that
files used during the build process are the same that were produced during the clone step.
5 - Reference
5.1 - Completion
witness completion
Generate completion script
Synopsis
To load completions:
Bash:
$ source <(witness completion bash)
# To load completions for each session, execute once:
# Linux:
$ witness completion bash > /etc/bash_completion.d/witness
# macOS:
$ witness completion bash > /usr/local/etc/bash_completion.d/witness
Zsh:
# If shell completion is not already enabled in your environment,
# you will need to enable it. You can execute the following once:
$ echo "autoload -U compinit; compinit" >> ~/.zshrc
# To load completions for each session, execute once:
$ witness completion zsh > "${fpath[1]}/_witness"
# You will need to start a new shell for this setup to take effect.
fish:
$ witness completion fish | source
# To load completions for each session, execute once:
$ witness completion fish > ~/.config/fish/completions/witness.fish
PowerShell:
PS> witness completion powershell | Out-String | Invoke-Expression
# To load completions for every new session, run:
PS> witness completion powershell > witness.ps1
# and source this file from your PowerShell profile.
witness completion [bash|zsh|fish|powershell]
Options
-h, --help help for completion
Options inherited from parent commands
-c, --config string Path to the witness config file (default ".witness.yaml")
-l, --log-level string Level of logging to output (debug, info, warn, error) (default "info")
SEE ALSO
- witness - Collect and verify attestations about your build environments
5.2 - Run
witness run
Runs the provided command and records attestations about the execution
witness run [cmd] [flags]
Options
-a, --attestations strings Attestations to record (default [environment,git])
--certificate string Path to the signing key's certificate
--fulcio string Fulcio address to sign with
--fulcio-oidc-client-id string OIDC client ID to use for authentication
--fulcio-oidc-issuer string OIDC issuer to use for authentication
-h, --help help for run
-i, --intermediates strings Intermediates that link trust back to a root of trust in the policy
-k, --key string Path to the signing key
-o, --outfile string File to which to write signed data. Defaults to stdout
-r, --rekor-server string Rekor server to store attestations
--spiffe-socket string Path to the SPIFFE Workload API socket
-s, --step string Name of the step being run
--trace Enable tracing for the command
-d, --workingdir string Directory from which commands will run
Options inherited from parent commands
-c, --config string Path to the witness config file (default ".witness.yaml")
-l, --log-level string Level of logging to output (debug, info, warn, error) (default "info")
SEE ALSO
- witness - Collect and verify attestations about your build environments
5.3 - Sign
witness sign
Signs a file
Synopsis
Signs a file with the provided key source and outputs the signed file to the specified destination
witness sign [file] [flags]
Options
--certificate string Path to the signing key's certificate
-t, --datatype string The URI reference to the type of data being signed. Defaults to the Witness policy type (default "https://witness.testifysec.com/policy/v0.1")
--fulcio string Fulcio address to sign with
--fulcio-oidc-client-id string OIDC client ID to use for authentication
--fulcio-oidc-issuer string OIDC issuer to use for authentication
-h, --help help for sign
-f, --infile string Witness policy file to sign
-i, --intermediates strings Intermediates that link trust back to a root of trust in the policy
-k, --key string Path to the signing key
-o, --outfile string File to write signed data. Defaults to stdout
--spiffe-socket string Path to the SPIFFE Workload API socket
Options inherited from parent commands
-c, --config string Path to the witness config file (default ".witness.yaml")
-l, --log-level string Level of logging to output (debug, info, warn, error) (default "info")
SEE ALSO
- witness - Collect and verify attestations about your build environments
5.4 - Verify
witness verify
Verifies a witness policy
Synopsis
Verifies a policy provided key source and exits with code 0 if verification succeeds
witness verify [flags]
Options
-f, --artifactfile string Path to the artifact to verify
-a, --attestations strings Attestation files to test against the policy
-h, --help help for verify
-p, --policy string Path to the policy to verify
--policy-ca strings Paths to CA certificates to use for verifying the policy
-k, --publickey string Path to the policy signer's public key
-r, --rekor-server string Rekor server from which to fetch attestations
Options inherited from parent commands
-c, --config string Path to the witness config file (default ".witness.yaml")
-l, --log-level string Level of logging to output (debug, info, warn, error) (default "info")
SEE ALSO
- witness - Collect and verify attestations about your build environments
5.5 - Version
witness version
Prints out the witness version
Synopsis
Prints out the witness version
witness version [flags]
Options
-h, --help help for version
Options inherited from parent commands
-c, --config string Path to the witness config file (default ".witness.yaml")
-l, --log-level string Level of logging to output (debug, info, warn, error) (default "info")
SEE ALSO
- witness - Collect and verify attestations about your build environments