# Running Conforma Checks Locally

LLMS index: [llms.txt](https://hummingbird-project.io/llms.txt) | Full content: [llms-full.txt](https://hummingbird-project.io/llms-full.txt)

---

## Overview

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

[conforma]: https://conforma.dev/
[stage5]: https://hummingbird-project.io/l/image-pipeline#stage-5-enterprise-contract-validation

## Prerequisites

Install the [Conforma CLI][ec-releases]:

```bash
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
```

[ec-releases]: https://github.com/conforma/cli/releases

## 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`][key-pub]. This is the same key
stored in the Konflux member cluster at `k8s://openshift-pipelines/public-key`.

[key-pub]: https://gitlab.com/redhat/hummingbird/containers/-/blob/main/ci/key.pub

### Obtaining the Image Reference

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

```text
<IMAGE_URL>@<IMAGE_DIGEST>
```

Merge request build images follow the pattern:

```text
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][policy-macro] 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):

```bash
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
        - cve.cve_blockers
        - schedule.date_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-ci/"
YAML
```

Then validate:

```bash
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
```

[policy-macro]: https://gitlab.com/redhat/hummingbird/containers/-/blob/main/konflux-templates/macros/policy.yml.j2

### 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):

```bash
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

```bash
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:

```bash
# 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.
