Decision: GitHub Artifact Attestations can provide verifiable build provenance, but they do not prove that code is safe, tests passed, or Apple signing and notarization are valid.
Fastest fix: Verify the exact release file, then check its source identity and workflow against your approved build path.
Use this runbook if you own enterprise iOS or macOS CI and need a release gate for artifact provenance.
CI leads can use it to build a source-verification process.
Security and release teams can use it to keep provenance evidence separate from tests, signatures, and archive approval.
Start with the boundary: what an attestation can establish
GitHub Artifact Attestations are intended to establish provenance for build artifacts and help consumers verify software provenance. That makes them useful for answering a narrow question: does this artifact have verifiable evidence connecting it to a source and build process?
It does not answer the broader question “Is this release safe?” A valid provenance check is not a code review, test report, malware scan, Apple signature check, or approval record. Treat it as one input to release acceptance, not as a release decision by itself. See GitHub’s description of Artifact Attestations and their purpose.
For an iOS release, keep the evidence streams distinct:
| Evidence | What you should verify | What it does not establish |
|---|---|---|
| Build provenance | Artifact digest, source repository and revision, and workflow identity | Code quality or test success |
| CI test record | The required test jobs ran against the intended revision and passed | That the delivered file matches the tested file |
| Apple signing and export | The actual app or archive meets the distribution path’s signing requirements | Which source or workflow produced it |
| Release approval | Your organization’s required reviewers and policy checks completed | That underlying evidence is accurate unless you validate it |
This separation prevents a common acceptance error: seeing a green provenance check and treating it as proof that every release control is green.
First check the artifact: is this the file you will ship?
Start at the delivery boundary, not at the workflow run. Identify the precise object your team plans to release: an archive, an exported app package, or another file consumed by the next deployment step. Then verify provenance for that object.
The digest is the link between a proof and a file. If the attestation is bound to an archive but your team exports, re-signs, compresses, or otherwise transforms the app afterward, do not assume the earlier proof applies unchanged to the resulting file. Byte-changing operations can produce a different artifact. Make the boundary explicit: record which file receives an attestation and which file the consumer verifies.
| Release object | Acceptance question | Action if the file changes |
|---|---|---|
| Xcode archive | Is this the archive built from the revision under review? | Verify the archive that is actually handed to the next stage |
| Exported iOS app | Does the proof correspond to the exported file, not only its archive? | Generate or verify provenance for the exported artifact |
| Uploaded or delivered package | Does the consumer receive the same bytes that were verified? | Re-check the delivered file and retain its digest with the result |
Apple’s archive and export guidance for distributing apps to registered devices is relevant here because the build, archive, and exported app are distinct stages in the delivery flow. Your acceptance record should name the stage and file that the provenance check covers.
Do not treat a filename as proof of identity. Two files can share a name while containing different bytes. Preserve the verification output and the digest alongside the release record, and make the release job fail if the verified file is not the file it is about to publish.
Second check source identity and the approved workflow
Use GitHub’s verification tooling on the artifact, and compare the result with your release policy. The documented CLI form is:
gh attestation verify PATH_TO_ARTIFACT -R OWNER/REPOSITORY
Replace the placeholders with the artifact path and the expected repository. Consult GitHub’s official verification instructions for current command behavior and options. Do not interpret a successful command as an automatic approval. It confirms a verification result; your organization still has to decide whether the identity is trusted.
For an acceptance review, compare at least these four values with the release request:
- Artifact digest: does the proof identify the exact file at the handoff boundary?
- Source repository: is the repository the one your team authorizes for this product?
- Source revision: does the provenance point to the code revision approved for this release?
- Workflow identity: does the named workflow correspond to an approved build path in the expected repository?
The workflow file and its trigger matter. A workflow that can be invoked from an unexpected branch, pull request, or repository context may not meet your policy, even if its provenance is verifiable. Review where the workflow resides, how it is triggered, and whether it uses an approved build definition. GitHub documents verification considerations for reusable workflows; use them to inform your review, but define the trusted workflow list inside your organization.
A practical policy might allow release provenance only from a protected release workflow in the production repository. That is an organizational rule, not a universal trust list supplied by the attestation itself. Write down who owns that list and how a workflow change is reviewed.
Compare verification paths before writing the release gate
A verification tool and a release policy solve different problems. Pick the tool path that fits your runner and evidence-handling requirements; do not weaken identity checks just to make a pipeline pass.
| Option | Useful when | Acceptance detail to verify |
|---|---|---|
| GitHub CLI verification | A CI job or reviewer can access the artifact and run the documented CLI | Confirm the command targets the expected repository and exact file |
| REST API verification | A service or integration consumes verification data programmatically | Handle the API’s documented proof and verification constraints; see GitHub’s REST API reference for attestations |
| Offline verification | The consumer must verify without relying on an online verification path | Follow GitHub’s offline verification guide and test the trust inputs used by your environment |
Keep the check reproducible. Save the command or integration version, its inputs, the verification output, and the release job result. If your consumer uses a different verification path from the one used by your CI job, test both paths with the same controlled artifact before making the second path a production gate.
Third check repository eligibility and prove coverage
Before rolling the process across an organization, confirm that each target repository can generate and consume attestations under its current configuration and eligibility. GitHub’s available security features and requirements can vary by repository context and plan. Check GitHub’s current security feature information instead of assuming that one successful run proves every repository is covered.
Test these as separate operations:
- Generation: does the intended build workflow produce an attestation for the chosen artifact?
- Retrieval: can the consumer or reviewer access the proof in the way your release process requires?
- Verification: does the consumer validate the proof and identify the expected source and workflow?
- Failure handling: does a missing proof, wrong repository, unexpected workflow, or digest mismatch stop release or route to a named reviewer?
A partial rollout can create a false sense of coverage. A successful test in one repository does not demonstrate that another repository has the same eligibility, permissions, workflow configuration, or proof access. Track coverage by repository and release path. Do not report “attestation enforced” unless the real consumer verifies the artifact that it receives.
Scenario: Your iOS build produces an archive, exports an app, and then uploads a delivery package. The archive has valid provenance, but the upload job changes the package. The release team must verify the object it will deliver, not infer that the archive’s proof covers the later file. If the upload job is a new build or transformation boundary, define how the resulting artifact gets its own provenance and what digest the release gate checks.
FAQ: Attestation acceptance
How do you verify the source of a GitHub Actions build artifact?
Run the documented gh attestation verify command against the exact artifact and the expected repository. Then inspect the verification result for the source repository, source revision, and signing workflow identity. A successful verification establishes that the artifact is associated with that provenance; your team must still decide whether the repository, revision, and workflow are approved for release.
What does an attestation prove for an iOS CI artifact?
It can provide verifiable provenance that connects an artifact digest with a source and build workflow. It does not establish that the source code is safe, that tests passed, or that the iOS app has a valid Apple signature. Record those outcomes separately, then define a release policy that requires each relevant check to pass.
How can you tell whether an attestation matches the file you are releasing?
Verify the final file that will be delivered, not an earlier archive or an intermediate upload. Compare the digest in the verification result with the digest of that exact file. If export, repackaging, or another transformation changes the bytes, treat the resulting file as a different artifact and generate or verify provenance for that version.
Can GitHub Artifact Attestations replace Apple code signing or notarization?
No. Attestation verification concerns build provenance, while Apple code signing supports platform-specific trust and distribution requirements. Notarization is a separate Apple process for applicable macOS software distribution; it is not a substitute for iOS app signing or a general iOS release gate. Keep these checks separate in your release evidence.
Fourth separate provenance from Apple signing and release gates
For iOS, Apple signing and export checks belong in their own acceptance lane. Apple’s code-signing documentation describes a different trust function from build provenance. A provenance result cannot establish that an app is signed correctly for its intended distribution channel.
Notarization also needs precise scoping. Apple describes notarization as a process for applicable macOS software distribution in its notarization guidance. Do not turn that into a generic iOS release check. For an iOS workflow, verify the signing and distribution requirements for the actual app delivery route. If your organization also distributes macOS software, treat notarization as a separate platform-specific gate.
Use separate job results or evidence records for:
- provenance verification and artifact digest;
- source revision and workflow approval;
- build and test outcomes;
- Apple signing and export validation;
- release approval and delivery status.
This structure makes a failed control diagnosable. A digest mismatch should not look like a test failure. An invalid signing result should not be hidden by valid provenance. A reviewer should be able to tell which check failed, which artifact it examined, and who owns the next action.
Fifth use a production iOS flow for acceptance
A toy workflow is not enough for a release decision. Choose a real build path that reflects the team’s normal trigger, source revision, archive, export, and delivery process. Keep the scope narrow enough to investigate failures, but representative enough to exercise the actual boundaries.
Follow this sequence:
- Select a release candidate. Record the repository, commit, workflow file, trigger, and intended delivery object. Use the same source revision that the release process approves.
- Build through the approved workflow. Confirm the job runs in the expected repository context and that the workflow identity matches your internal allowlist.
- Generate provenance for the defined artifact. Make clear whether that means the archive, exported app, or a later package. Do not use one name for multiple pipeline outputs.
- Verify at the consumer boundary. Run
gh attestation verifyor your approved verification integration against the exact file that the next release step consumes. - Compare the result with policy. Check the digest, source repository, revision, and workflow identity. Require an explicit decision for any identity your policy does not recognize.
- Run independent gates. Confirm required tests, Apple signing and export validation, and release approval through their own evidence records.
- Exercise failure cases. Try a wrong file, missing proof, unapproved workflow, and unexpected source revision in a controlled test. Confirm each case blocks release or reaches the documented reviewer.
- Retain the acceptance record. Store the artifact reference, digest, verification result, test status, signing evidence, and approval outcome where your release process can retrieve them.
The key pass condition is not “the attestation command returned success.” It is: the real release consumer verified the exact object it received, the identity matched your policy, and independent release gates passed for the same candidate. Decide which artifacts require mandatory verification based on your release policy. If some paths are exempt, document the owner, reason, and compensating control.
Make the Mac build boundary an independent acceptance item
Artifact provenance does not certify the Mac runner, its access controls, or the safety of its signing environment. If a build stage needs macOS, assess the runner separately: who can administer it, how credentials are exposed, which jobs share it, how it is recovered, and what evidence shows that the intended workflow ran there. Do not present an attestation as proof that a Mac environment is isolated or approved.
For capacity planning, first estimate the number and type of Mac CI jobs your release path requires. Then decide whether to buy hardware, expand an existing fleet, or use a temporary remote Mac for a pilot or burst workload. A remote Mac does not remove your responsibility to validate runner permissions, secrets handling, and release evidence. If you are comparing hosted capacity for a Mac-dependent workload, review the MACCOME remote Mac option as an environment choice—not as an attestation or compliance control. If region is part of your deployment review, include the MACCOME Singapore Mac option in that same infrastructure assessment.
Advantages of attestation-based provenance
- It gives reviewers a verifiable link between an artifact and build provenance.
- It lets release consumers check provenance rather than relying only on a workflow log or filename.
- It can complement your existing source, test, signing, and approval gates.
Limits to account for
- It does not decide whether a workflow is trustworthy for your organization.
- It does not certify tests, code quality, Apple signing, or the runner’s access controls.
- It does not remove the need to verify the exact file at the delivery boundary.
If your current process relies on a green CI run and a manually copied package, its weak points are the uncertain file handoff, limited identity checks, and evidence spread across separate systems. A Mac capacity change will not fix those controls; implement the provenance and release gates first. When the iOS pipeline genuinely needs macOS and you need temporary capacity to validate or run it, compare MACCOME’s remote Mac delivery details with buying or expanding local hardware. Choose a short-term hosted option only if it fits your security review and workload; keep a self-managed Mac fleet for sustained workloads or requirements that depend on physical access.