Send evidence from CI¶
Your pipeline sends build receipts, IaC receipts and other evidence to the console with its own short-lived OpenID Connect identity token. There is no long-lived untrust secret to store in CI for this.
1. Register a CI binding¶
An administrator registers the pipeline under setup's Pipeline step (or Trust a pipeline in the console). A binding pins the exact provider identity untrust will accept:
- GitHub.com: the repository and owner, branch, trigger and workflow.
- GitLab.com: the project and namespace, branch and job configuration.
Copy the exact subject your provider issues rather than constructing it from a repository name. Branch push, manual and scheduled runs are supported.
The saved binding shows its token audience (unique to the binding) and its HTTPS submission endpoint. A token minted for one binding is refused at every other binding.
A new binding accepts build and iac evidence only. An administrator can widen it to
other kinds (runtime, detections, registry, ledger, replay) and narrow it again.
Disabling a binding rejects later submissions immediately, including one already being
verified.
2. Add the gate and the upload to your pipeline¶
The console's pipeline setup generates the configuration for your provider, target, artifact path and threshold, with the Enterprise workspace destination selected. It contains no credentials.
GitHub Actions downloads a reusable workflow. Save it as
.github/workflows/untrust-evidence.yml and call it after your build job:
untrust-evidence:
needs: build
uses: ./.github/workflows/untrust-evidence.yml
permissions:
contents: read
id-token: write
with:
artifact-name: workload-rootfs
endpoint: ${{ vars.UNTRUST_SUBMIT_ENDPOINT }}
The generated workflow also takes the scanner revision to run; pin it to a full, reviewed commit, never a branch.
GitLab CI downloads a pipeline configuration and job templates. Copy the templates into
.gitlab/ before the pipeline is created, and set the submission endpoint and token
audience from the binding as protected CI/CD variables.
In both, the gate job keeps its report even when it fails, a separate delivery step uploads
it, and your deployment must depend on both succeeding. Do not add continue-on-error or
allow_failure to either.
3. Upload directly¶
To upload reports yourself from a job that has an OIDC token:
python -m untrust.enterprise_ci_client --endpoint "$UNTRUST_SUBMIT_ENDPOINT" --github-oidc \
--build .untrust/build.json --iac .untrust/iac.json
On GitLab, omit --github-oidc; the client reads the token from UNTRUST_CI_ID_TOKEN.
Repeat a flag for several reports of one kind. The client accepts --build, --iac,
--runtime, --detections, --registry and --replay.
The client validates the reports before it requests a token, refuses redirects, retries a transient failure at most three times with the same token and payload, and never prints tokens or provider responses. Success prints a receipt ID.
What the service checks¶
- The token's signature against the provider's published keys, its issuer, the binding's audience, and every pinned claim. A mismatch is refused before anything is stored.
- Token lifetime: at most ten minutes, and not expired.
- For
buildandiac, the report's commit and run ID must match the token's. Use the plain workflow run ID (GitHub) or pipeline ID (GitLab), without an attempt suffix. - One token is one submission. Retrying the same token with the same payload returns the stored receipt; changing the payload under the same token is refused.
- A batch holds 1 to 20 documents, at most 6 MiB.
What it does not prove¶
A CI upload is an authenticated submission: untrust knows which pipeline sent it. It does not prove that the scanner ran, that the artifact is the one you deployed, or that a hardware attestation is valid. The console labels CI evidence accordingly, and it never becomes verified hardware posture. The build and IaC gates are recomputed from the findings when they are ingested, against your organization's armed custom rules and rule levels.
See the results¶
Build findings appear under Source analysis, infrastructure findings under IaC scan, and both under Findings. Each submission is retained with its receipt; you can verify a stored receipt offline.