KEY TAKEAWAYS
- Decide the allowed repository, actual signing workflow, source revision and predicate before evaluating the candidate. A broad verification success is not the same as satisfying that policy.
- When a reusable workflow signs the attestation, check that reusable workflow—not just the application workflow that called it.[1][3]
- Accepting provenance permits the next security and integration review. It does not certify that the artifact is safe to run.
A green result answers the question you asked
Before adding a downloaded tool to an agent workflow, ask two different questions: did it come from the build process you agreed to trust, and is it acceptable to run in this integration? Artifact attestations address the first question. They do not replace the second.
The GitHub CLI manual says verification checks the actor's identity and the expected predicate type—the kind of claim being signed. At minimum, gh attestation verify requires an owner or repository. More precise signer constraints are the verifier's choice. A successful check scoped only to an organization is therefore not evidence that your separately required workflow was enforced.[1]
The procedure below makes that choice explicit before verification. It covers build provenance, not whether a file belongs to a particular release or equals a release asset. Those are different acceptance questions; neither substitutes for the build identity you require.
1. Define the identity from trusted records
Choose an acceptance owner and obtain the expected values from independently approved source and builder records: the team's reviewed build configuration, release approval and allowed builder revisions. Do not copy the candidate's claims into the policy simply because those values make it pass. The table separates constraints that the manual documents; requiring them together is the proposed policy for this guide.[1]
| Policy choice | Documented control | What the team must decide |
|---|---|---|
| Artifact-linked repository | --repo; --owner is broader scope | Which owner/repository the artifact must be linked with. This does not by itself select an exact reusable signer. |
| Actual signer workflow | --signer-workflow; --signer-repo narrows only the repository | Which workflow file may sign. If a reusable builder does the signing, allow that builder's path, not merely its caller. |
| Source ref | --source-ref | Which Git ref must be associated with the source repository. Keep it distinct from the approved source digest. |
| Source digest | --source-digest | Which source-repository digest the approval requires. This is not the downloaded binary's checksum. |
| Signer digest | --signer-digest | Which digest associated with the signing workflow is allowed. This is separate from the application's source digest. |
| Predicate type | --predicate-type | Which claim type is required. This guide requires https://slsa.dev/provenance/v1 build provenance, not an interchangeable signed claim. |
These controls and their meanings come from the captured manual.[1] It does not establish a versioned input-serialization contract for the digest flags. Resolve actual digest values from your approved records and confirm their required representation against your installed CLI and applicable documentation; do not guess a hash, prefix or revision. If a required value cannot be established, keep acceptance on hold.
Repository and signer can be different. GitHub's reusable-workflow guide explicitly shows a calling repository and a separate reusable workflow repository; it offers --signer-repo for the latter or --signer-workflow for an exact file. A signer-repository match is not an exact-workflow match.[3]
2. Check the CLI and identify the exact artifact
Before running the example, inspect your installation with gh --version and gh attestation verify --help. Confirm that it exposes the policy flags you intend to use. The live manual inspected for this guide is unversioned; the minimum CLI release supporting this complete command was not established. These diagnostic commands were not run for this article.
For a binary, use the local file you intend to accept. For a container, the manual accepts an oci:// image URI and requires prior authentication with that registry. GitHub's documentation gives separate binary and container examples for an online environment.[1][2] Record the exact candidate file or image identity in the acceptance record; do not verify one candidate and then substitute another for installation. Use your existing approved authentication route, without placing credentials in the record.
3. Verify against the predeclared policy
Unexecuted binary command example. It assumes all shell variables have already been populated with the actual candidate and independently approved policy values; it supplies no commit IDs, hashes or verification output. The command uses documented flags and keeps build provenance explicit even though that predicate is the manual's default.[1]
gh attestation verify "$ARTIFACT_PATH" --repo "$EXPECTED_ORIGIN_REPO" --signer-workflow "$EXPECTED_SIGNER_WORKFLOW" --source-ref "$EXPECTED_SOURCE_REF" --source-digest "$EXPECTED_SOURCE_DIGEST" --signer-digest "$EXPECTED_SIGNER_DIGEST" --predicate-type https://slsa.dev/provenance/v1 --format json
- ARTIFACT_PATH is the local binary path. EXPECTED_ORIGIN_REPO uses owner/repository syntax.
- EXPECTED_SIGNER_WORKFLOW is the allowed signing workflow path in the documented form [host/]<owner>/<repo>/<path>/<to>/<workflow>. For a reusable builder, supply its path.[1]
- EXPECTED_SOURCE_REF is the approved Git ref. EXPECTED_SOURCE_DIGEST and EXPECTED_SIGNER_DIGEST are separately approved digest values, not values learned from the candidate or invented for this example.
- For the container variant, replace the file argument with your exact oci:// image URI after the required registry authentication. Keep the same policy constraints; the different input does not relax the signer policy.[1]
Keep the actual invocation, CLI version, exit status and full JSON result with the policy version and candidate identity. If verification fails, or required evidence cannot be obtained, record HOLD and investigate the mismatch. Do not remove --signer-workflow, change the predicate or widen --repo to --owner just to obtain a success. A deliberate policy revision needs its own approval and a new evaluation; it is not repair of the original result.
4. Read the result without over-trusting the predicate
On successful verification, --format json returns an array with one entry per verified attestation. Each entry has attestation and verificationResult. Evaluate the relevant verified record or records against your policy; the existence of a nonempty array is not a complete acceptance rule.[1]
Within verificationResult, the manual distinguishes signature.certificate and verifiedTimestamps from statement.predicate. It warns that only the certificate and verified timestamps contain values the originating workflow cannot manipulate. If an attacker controls that workflow's execution context, predicate contents can be falsified. Use the certificate-backed identity and enforced constraints as documented; do not elevate a predicate's self-description into independently authenticated builder identity.[1]
This boundary does not guarantee that the authenticated builder itself is uncompromised. The manual suggests a trusted-builder design in which building and signing happen inside a reusable workflow whose execution cannot be influenced by caller input. Merely calling a reusable workflow does not establish that condition. This guide makes no SLSA certification claim.[1][3]
Predicate type is also a boundary. The manual defaults to https://slsa.dev/provenance/v1; GitHub separately documents verifying an SPDX SBOM with --predicate-type https://spdx.dev/Document/v2.3.[1][2] A valid SBOM attestation is a different claim. If your policy requires build provenance, an SBOM-only result does not satisfy it—and a signed dependency inventory does not certify freedom from vulnerabilities.
Worked decision: a valid signer can still be the wrong signer
Hypothetical, not an observed verification. Cedar Integration is a fictional team evaluating an agent connector. Its policy allows source from cedar-example/connector, requires signing by cedar-example/build-tools/.github/workflows/trusted-build.yml, requires its approved source ref and separately approved source and signer digests, and requires https://slsa.dev/provenance/v1. These names describe a fictional policy; no real repository, artifact or approved revision was retrieved.
Assume, solely for this reasoning exercise, that a broader repository-only verification succeeds and the result identifies cedar-example/connector/.github/workflows/release.yml as the actual signer. Also assume the source ref/digest match the team's approved source and the predicate is build provenance. This is a premise for deciding, not fabricated terminal or JSON output.
| Policy dimension | Hypothetical finding | Decision |
|---|---|---|
| Origin and source | Application repository and approved source ref/digest match. | Source expectations are satisfied under the premise; they do not settle signer identity. |
| Signer path | The actual signer is the application's release.yml, not the required reusable trusted-build.yml. | HOLD. A valid signature from another workflow does not satisfy the exact-workflow policy. |
| Signer revision | The required builder path is absent. | Do not substitute the caller's revision for the approved builder digest. The path mismatch already prevents acceptance. |
| Predicate | The assumed predicate is https://slsa.dev/provenance/v1. | The claim type matches, but cannot cure the signer mismatch. |
| Security and fitness | Provenance acceptance has not been reached. | No deployment approval follows. Keep the integration unapproved pending the required evidence and separate reviews. |
Cedar's finished decision is HOLD, owned by its acceptance lead. The next action is to request a candidate built and attested by the approved reusable builder, then evaluate that candidate under the unchanged policy. The fully constrained command above is the appropriate verification shape; the broad success assumed in the example was never enough.
In the matching branch, assume instead that the required repository, reusable signer path, source ref, source digest, signer digest and provenance predicate all satisfy the policy. Cedar can record provenance accepted and proceed to its separate security and integration review. It still cannot record artifact safe or deployment approved on that evidence alone.
5. Make the security and integration decision separately
After provenance acceptance, apply the checks appropriate to the agent integration: dependency and vulnerability policy, permissions and runtime behavior, license requirements, and compatibility with the intended environment. These are proposed team checks, not tests performed by gh attestation verify or by this article.
- Record provenance accepted only when the candidate satisfies the predeclared provenance policy and the supporting result is retained.
- Record HOLD when required identity, predicate or evidence is missing or mismatched. State the responsible owner and the specific evidence needed to continue.
- Authorize use only after the separate security and fitness decision is complete. Keep that decision linked to the same candidate, without treating a signature as a safety certificate.
The useful outcome is not a green terminal line. It is a reviewable decision about which builder and source you accepted, which claim you verified, and which checks remain before an agent may use the artifact.
Documentation and limits
This guide uses official GitHub CLI and GitHub Docs pages captured on 12 October 2026 in Asia/Seoul. That is a documentation observation date, not a feature release date. Vendor publication/update dates and a minimum compatible CLI version were not established. Check current documentation and installed help before using these controls.
No binary, container or attestation was downloaded or verified for this article. No example command, vulnerability check, runtime test or deployment was executed. The policy sequence is a recommendation; Cedar's completed HOLD decision is a clearly labeled hypothetical application of it.
Sources & scope
A proposed team acceptance procedure grounded in GitHub's official documentation, checked on 12 October 2026 in Asia/Seoul. Commands are unexecuted examples; the worked decision is hypothetical. No artifact, attestation or runtime was tested. Minimum compatible GitHub CLI version and vendor publication/update dates were not established.
- GitHub CLI: gh attestation verify ↗
Official live manual checked 12 October 2026 (Asia/Seoul). Identity and predicate enforcement, exact flag syntax, JSON output and workflow-controlled predicate warning. Minimum compatible CLI version and vendor dates not established.
- GitHub Docs: Using artifact attestations to establish provenance for builds ↗
Official documentation checked 12 October 2026 (Asia/Seoul), reached via the prior security-for-github-actions URL. Binary, online OCI and distinct SPDX SBOM verification examples; not executions performed for this guide. Vendor dates not established.
- GitHub Docs: Using artifact attestations and reusable workflows to achieve SLSA v1 Build Level 3 ↗
Official documentation checked 12 October 2026 (Asia/Seoul), reached via the prior security-guides URL. Separate caller and reusable signer repository/path examples. Cited for identity distinctions, not certification of any artifact or team. Vendor dates not established.
Publication history
- — Initial prepared edition: expected build identity, constrained verification procedure and hypothetical HOLD decision. The edition date is not evidence of deployment.
Have a correction or a different perspective? Contact Palanthos.