GitHub Actions Attestation Verification
GitHub Actions Attestation Verification
Overview
Uptrakit can verify GitHub Actions attestations for software releases tracked via the GitHub Releases plugin. Attestations provide Sigstore-based SLSA provenance that proves a given artifact was produced by a specific GitHub Actions workflow run, protecting against supply-chain attacks where artifacts are replaced or tampered with after publication.
Verification is performed via the GitHub Attestations REST API:
GET /repos/{owner}/{repo}/attestations/sha256:{digest}
No gh CLI or Sigstore tooling is required — all verification uses direct REST API calls.
How It Works
Attestation verification is a two-stage process:
Stage 1 — Controller (fetch time)
When fetch_releases runs for a GitHub-sourced software item, the controller:
- Locates a checksums file in the release assets (any file whose name contains
sha256orchecksum, case-insensitive). - Downloads the checksums file and parses
<sha256hex> <filename>and<sha256hex> *<filename>lines. - Stores the
sha256_digestfor each matching release asset inlatest_release_metadata. - Queries the GitHub Attestations API for the first asset with a known digest.
- Stores the resulting
AttestationStatusinlatest_release_metadata.
The attestation status and SHA-256 digests are then propagated into
ExecuteUpdatePayload.release_info when an update is triggered.
Stage 2 — Agent (pre-install)
Before executing a plugin update, the agent independently re-verifies the attestation:
- Checks whether the release URL is a
https://github.com/{owner}/{repo}/…URL. Non-GitHub updates are unaffected. - If the controller already set
attestation_status = Verified, the agent trusts that verdict and proceeds immediately. - Otherwise, the agent independently re-queries the GitHub Attestations API using
the first asset's
sha256_digest. - Based on the result and the
require_attestationpolicy, the agent either proceeds, warns, or aborts the update.
AttestationStatus
| Value | Meaning |
|---|---|
Verified | At least one attestation was found for the release asset digest. |
NotFound | The GitHub Attestations API returned no attestations (404 or empty array). |
Unverified | The check was skipped or inconclusive (no checksums file, network error, etc.). |
Configuration
Both options are set in the GitHub Releases plugin configuration (see Plugin Configurations for the full reference):
{
"verify_attestation": true,
"require_attestation": false
}
verify_attestation (default: true)
When true, the controller downloads the release checksums file, parses SHA-256
digests, and queries the GitHub Attestations API during fetch_releases. Results are
stored in latest_release_metadata and displayed in the UI.
Set to false to disable attestation checking entirely (not recommended for production
use of software from public repositories).
require_attestation (default: false)
When true, the agent will abort the update if the independent re-verification
returns NotFound. The update fails with:
attestation verification failed: no GitHub Actions attestation found for {owner}/{repo};
update blocked by require_attestation policy
When false (default), a warning is emitted in the update output but the update
proceeds. This is the recommended starting point when adopting attestation checks.
Setting
require_attestation = trueprovides the strongest supply-chain guarantee. However, if the upstream project does not useactions/attestin their release workflow, all updates will fail. Verify that attestations are consistently published before enabling this option.
Example: Enabling Strict Attestation
{
"auth_token": "ghp_...",
"verify_attestation": true,
"require_attestation": true
}
With this configuration:
- The controller verifies attestations at fetch time and displays the status in the UI.
- The agent independently re-verifies before install.
- Any release without a valid attestation is blocked.
UI Indicators
The software item detail page shows attestation status in the Latest Version column:
- Attested (green badge) —
Verified - Not attested (red badge) —
NotFound - No badge —
Unverifiedor attestation checking disabled
The update confirmation modal also displays:
- A green confirmation message when
Verified. - A yellow warning when
NotFound(regardless ofrequire_attestation).
Security Considerations
- The independent agent re-verification uses a fresh
reqwest::Clientwithconnect_timeout(10s)andtimeout(30s). - Only
https://github.com/URLs are checked; GitHub Enterprise and other forges are not currently supported in the agent re-verification path. - The agent does not perform Sigstore bundle cryptographic verification — it only checks whether the GitHub Attestations API returns a non-empty result for the expected SHA-256 digest. Full Sigstore verification may be added in a future version.
- Checksums files filtered out by
asset_patternsare still used for attestation checking (the check operates on raw GitHub assets, not the filtered set).