Using the Enterprise Contract command line
Installation
Downloading a binary
Visit the releases page, scroll and expand "Assets". Find the appropriate binary for your system, download it and copy it to somewhere in your path.
For example:
$ curl -sLO https://github.com/enterprise-contract/ec-cli/releases/download/snapshot/ec_linux_amd64
$ chmod 755 ec_linux_amd64
$ sudo mv ec_linux_amd64 /usr/local/bin/ec
$ ec version
$ ec --help
Running with docker or podman
If you have docker or podman installed you can also run ec like this:
$ docker pull quay.io/enterprise-contract/ec-cli:snapshot
$ docker run quay.io/enterprise-contract/ec-cli:snapshot
Substitute podman
for docker
in the above command if you’re using podman.
For convenience you could create an alias. For example:
$ alias ec="docker run quay.io/enterprise-contract/ec-cli:snapshot"
$ ec version
$ ec --help
There might be some extra work needed to mount files inside the container, for example, if your public key is in a file, you would need to mount it when running docker. |
$ docker run -v ./key.pub:/tmp/key.pub:Z quay.io/enterprise-contract/ec-cli:snapshot validate image ...
Validating an image
To run ec against a particular container image built by Konflux, we use the
ec validate image
command. To see the command options you can use the
--help
flag, e.g.:
$ ec validate image --help
When validating an image we need to provide three things:
-
The image reference
-
The public key for verifying signatures
-
A policy configuration file which determines what policies are to be applied
For these examples I’m going to use a particular image with a known signing key.
Actually the public key can be provided via the policy configuration, but
for these examples we’ll provide it separately using the --public-key flag.
|
For the sake of more readable examples, let’s create some environment variables
and some files for the three pieces of information. For the policy.yaml
we’ll
download one of the predefined examples.
$ export IMAGE="quay.io/konflux-ci/ec-golden-image:latest"
$ echo '-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZP/0htjhVt2y0ohjgtIIgICOtQtA
naYJRuLprwIv6FDhZ5yFjYUEtsmoNcW7rx2KM6FOXGsCX3BNc7qhHELT+g==
-----END PUBLIC KEY-----' > key.pub
$ wget -q https://github.com/enterprise-contract/config/raw/main/slsa3/policy.yaml
Now we can run the ec like this:
$ ec validate image --image "$IMAGE" --public-key key.pub --policy policy.yaml --ignore-rekor --output yaml
NOTE:The image used in this example was signed and attested without using Rekor. This is why the --ignore-rekor
flag is needed. You may not need this if you’re using a different image
Finding the public key
If you’ve run EC at least once using an integration test, as described in Getting started…, the public key is visible in the logs for the pipeline run.
In the future there should be a better way to find the public key file for the signing secret used by Tekton Chains in the Konflux build system. |
You can now modify the policy.yaml
file and re-run the ec validate image
command to try different policy configurations. See
the configuration docs for more information on the
policy.yaml
file, or take a look at the examples
here.
See also the how-to on reproducing the Enterprise Contract output from a Konflux integration test.
Validating arbitrary inputs
The ec validate input
command line can be be used to validate arbitrary
structured data, specifically in JSON or YAML formats. The subcommand ec
validate input
allows for checking the compliance of arbitrary number of files,
provided via --file
parameter, to a set policy,
provided via --policy
parameter.
For example let’s consider a YAML file containing a set of sign-offs for a release, and a policy mandating that a release must be signed-off by at least two persons from each relevant department.
---
image: registry.io/repository/image:tag # the image that is signed-off on
quality_assurance: # QA sign-offs
- Elena Harper
- Calvin Bean
product_development: # product sign-offs
- Lennon Bradford
- Kate Levy
engineering: # engineering sign-offs
- Zayn Simmons
description: ACME & co sign-off policy
sources:
- name: default-sign-off
policy:
- "git::https://github.com/acme/policy.git//policy?ref=prod"
github.com/acme/policy.git
repository at policy/signoff.rego
#
# METADATA
# title: ACME & co Sign-off policy
# description: >-
# Mandates the compliance of sign-offs within ACME & co
#
package signoff
import rego.v1
# METADATA
# title: Each department needs to provide two sign-offs
# description: >-
# Makes sure that each relevant department provided two sign-offs
# custom:
# short_name: two_signoffs
#
deny contains result if {
some department in {"quality_assurance", "product_development", "engineering"}
count(input[department]) < 2
result := sprintf("Missing required sign-offs from the %s department", [department])
}
With this, running the CLI shows that there is a policy violation, one sign-off from the engineering department is missing:
$ ec validate input --file data.yaml --policy policy.yaml --output yaml
ec-version: v0.4.2
effective-time: "2024-04-25T11:07:35.025505232Z"
filepaths:
- filepath: data.yaml
success: false
success-count: 1
successes: null
violations:
- msg: Missing required sign-offs from the engineering department
warnings: []
policy:
description: ACME & co sign-off policy
sources:
- name: default-sign-off
policy:
- git::https://github.com/acme/policy.git//policy?ref=prod
success: false
Error: success criteria not met
Validating policy configuration
As a convention, the
policy_data
collection
includes rules that check the conformance of rule data.
When customizing the rule data this can be used to validate that the data is
well formed.
For this a policy as in the following example can be used:
description: Custom rule data validation
sources:
- policy:
- github.com/enterprise-contract/ec-policies//policy/lib
- github.com/enterprise-contract/ec-policies//policy/release
data:
- /path/to/rule_data.yml
- /path/to/required_tasks.yml
config:
include:
- '@policy_data'
Given that the policy already includes all the data needed for the validation no
input needs to be provided on the ec validate input
command, an empty input
can be provided for the --file
parameter with: --file='{}'
.