Running Conforma Checks Locally

Overview

Conforma (Enterprise Contract) policy checks run automatically in the Konflux pipeline before release (see Image Pipeline — Stage 5). These checks can also be run locally against any Konflux-built image to validate compliance, test policy changes, or investigate failures.

Prerequisites

Install the Conforma CLI:

curl -sLO https://github.com/conforma/cli/releases/download/snapshot/ec_linux_amd64
chmod 755 ec_linux_amd64
mkdir -p ~/.local/bin
mv ec_linux_amd64 ~/.local/bin/ec

Running All Checks

The full set of Conforma checks (signatures, attestations, SLSA provenance, labels, etc.) can be run against any Konflux-built image using ec validate image with the Konflux signing key.

Public Key

The Konflux signing public key is committed at ci/key.pub. This is the same key stored in the Konflux member cluster at k8s://openshift-pipelines/public-key.

Obtaining the Image Reference

Combine the IMAGE_URL and IMAGE_DIGEST results from a successful build PipelineRun:

<IMAGE_URL>@<IMAGE_DIGEST>

Merge request build images follow the pattern:

quay.io/redhat-user-workloads/hummingbird-tenant/<component>:on-mr-<MR_ID>-<COMMIT_SHA>

Running the Validation

Create a policy file that matches the pipeline policy but with any modifications needed for testing. For example, to run the pipeline policy with label checks enabled (removing the labels.required_labels and labels.optional_labels exclusions):

cat > /tmp/policy.yaml << 'YAML'
sources:
  - name: Release Policies
    config:
      exclude:
        - test.required_tests_passed:sast-snyk-check
        - test.no_skipped_tests:sast-snyk-check
        - test.required_tests_passed:sast-snyk-check-oci-ta
        - test.no_skipped_tests:sast-snyk-check-oci-ta
        - test.no_failed_tests:ecosystem-cert-preflight-checks
        - test.no_erred_tests:ecosystem-cert-preflight-checks
        - test.no_failed_informative_tests
        - test.no_test_warnings:deprecated-image-check
        - trusted_task.current
        - rpm_repos.ids_known
        - buildah_build_task.privileged_nested_param
        - schedule.weekday_restriction
      include:
        - '@redhat'
    data:
      - github.com/release-engineering/rhtap-ec-policy//data
      - oci::quay.io/konflux-ci/tekton-catalog/data-acceptable-bundles:latest
      - oci::quay.io/konflux-ci/konflux-vanguard/data-acceptable-bundles:latest
      - oci::quay.io/konflux-ci/integration-service-catalog/data-acceptable-bundles:latest
    policy:
      - oci::quay.io/enterprise-contract/ec-release-policy:konflux
    ruleData:
      allowed_registry_prefixes:
        - "quay.io/hummingbird-rawhide/"
        - "quay.io/hummingbird-ci/"
        - "quay.io/hummingbird/"
        - "quay.io/redhat-user-workloads/"
YAML

Then validate:

ec validate image \
    --image "quay.io/redhat-user-workloads/hummingbird-tenant/<component>@sha256:<digest>" \
    --policy /tmp/policy.yaml \
    --public-key ci/key.pub \
    --ignore-rekor \
    --strict=false \
    --show-successes \
    --output text

Options

Flag Purpose
--ignore-rekor Required — Konflux does not use a Rekor transparency log
--strict=false Return exit code 0 even on failures (useful for investigation)
--show-successes Include passing checks in output (off by default)
--output json Machine-readable output (also: text, yaml, summary)

Running Label Checks Only

The label checks (labels.required_labels, labels.optional_labels) are the only Conforma rules that can be evaluated without signatures or attestations, because they only read OCI image metadata. This lighter-weight approach does not require the signing key and works against any registry image, including published (non-Konflux-built) images.

Setup

Fetch the policy rego files and upstream rule data (one-time):

ec fetch policy \
    --source oci::quay.io/enterprise-contract/ec-release-policy:konflux \
    --dest /tmp/ec-policy

git clone --depth=1 \
    https://github.com/release-engineering/rhtap-ec-policy.git \
    /tmp/rhtap-ec-policy

Running Checks

ec opa eval \
    --data /tmp/ec-policy/policy/*/policy \
    --data /tmp/rhtap-ec-policy/data/rule_data.yml \
    --input <(echo '{"image":{"ref":"quay.io/hummingbird-rawhide/caddy:latest"}}') \
    '{"deny": data.labels.deny, "warn": data.labels.warn}' \
    --format pretty

This works against any image accessible from a container registry — both Konflux-built and published images. It uses the ec CLI’s embedded OPA engine with ec.oci.* built-in functions to read image config directly from the registry.

Note: The --data flag (not --bundle) must be used for the rego files. Loading the policy as a bundle creates an OPA root conflict that prevents the rule data from being resolved. The ec.oci.* built-in functions are only available in ec opa, not in standalone opa or conftest.

Interpreting Results

For ec validate image:

  • Successes indicate passing policy rules (visible with --show-successes).
  • Violations are failures that block release. Each includes a code (rule name) and msg.
  • Warnings are non-blocking advisories.

For ec opa eval (label checks only):

  • deny entries are failures. Each includes code, msg, and optionally effective_on (a date when the rule becomes enforced — future dates mean the rule is not yet active).
  • warn entries are non-blocking warnings for optional labels.
  • Empty arrays mean the image passes all label checks.

Updating Cached Data

The fetched policy and rule data are point-in-time snapshots. To pick up upstream changes:

# Re-fetch the policy rego files (for ec opa eval)
rm -rf /tmp/ec-policy
ec fetch policy \
    --source oci::quay.io/enterprise-contract/ec-release-policy:konflux \
    --dest /tmp/ec-policy

# Update the rule data (for ec opa eval)
git -C /tmp/rhtap-ec-policy pull

The ec validate image command fetches policy and data bundles on each run based on the policy.yaml references, so no manual update is needed.