The problem
A typical CI workflow uses two Kosli flows:| Flow | Triggered by | Trail name | What it records |
|---|---|---|---|
app-pr | Pull request builds | PR number or branch commit | Tests, scans, code review |
app-main | Merges to main | Merge commit SHA | Artifact build, deployment approval |
Recommended approach
Usekosli evaluate trail on the main-branch build to evaluate the PR trail against a Rego policy, then record the result as an attestation on the main trail.
Identify the PR trail name from the main build
Derive the PR trail name from information available in your main-branch CI context. Common strategies:
- Git ancestry — find the merge commit’s parent that matches a PR trail name.
- Branch naming convention — extract the PR number from the merge commit message (e.g.
Merge pull request #42). - CI environment variables — some CI systems expose the originating PR number on merge builds.
Check the PR trail compliance
There are two ways to check the PR trail’s compliance. Use
kosli evaluate trail with a Rego policy for a formal, policy-driven check that fails the CI step automatically. Alternatively, use kosli get trail with JSON output for a lighter approach that does not require a policy file.- evaluate trail (Rego policy)
- get trail (JSON + jq)
Use Then evaluate the PR trail:The command exits with a non-zero code if the trail does not satisfy the policy, which fails the CI step automatically.
kosli evaluate trail to check the PR trail against a Rego policy. Create a policy file (e.g. pr-compliant.rego):pr-compliant.rego
Attest the result on the main trail
Record a generic attestation on your main-branch trail with the PR trail’s compliance result.Add
- evaluate trail (Rego policy)
- get trail (JSON + jq)
Because
kosli evaluate trail fails the CI step on a non-compliant trail, this attestation only runs when the trail is compliant:pr-build-compliance to your main flow’s template so that missing evidence is flagged:Risks and considerations
This approach works, but carries assumptions you should evaluate for your environment:Code equivalence between PR and main
A PR build runs against the branch head at build time. Between the PR build and the merge to main, the main branch may have received other commits. If the merge is not a fast-forward, the code on main after the merge may differ from what the PR build tested. Mitigations:- Require linear history in your repository settings (GitHub, GitLab, Bitbucket all support this). This forces rebasing before merge, ensuring the PR build tested the exact code that lands on main.
- Require up-to-date branches before merging, so the PR build always includes the latest main-branch changes.
- Re-run critical tests on main if fast-forward merges are not practical. This adds time but removes ambiguity.
Binary reproducibility
If your build process is not reproducible, the artifact built on main may differ from the one built on the PR branch — even from identical source code. In that case, the PR trail’s attestations apply to a different artifact than the one you deploy. If your builds are reproducible, you can strengthen the link by verifying that the artifact fingerprint on main matches one attested in the PR trail.Trust boundaries
The approach above relies on the Kosli API token used in CI having read access to the PR flow. Ensure your CI secrets and permissions are configured so that:- The main-branch build can query
app-prtrails. - Only authorized pipelines can write attestations to
app-main.
Example: GitHub Actions
Below is a simplified GitHub Actions workflow for a main-branch build that links back to the PR trail:- evaluate trail (Rego policy)
- get trail (JSON + jq)
Looking ahead
Kosli is exploring native support for linking trails across flows — removing the need for the scripted approach described above. When available, this will allow you to declare trail dependencies directly in the flow template, with Kosli resolving and evaluating the linked trail’s compliance automatically. Until then, thekosli evaluate trail approach described here is the recommended pattern.