aaif-goose/goose · critical

{e}

Error message

{e}

What it means

Passthrough of the failure from sigstore_verify::verify: the bundle parsed fine but cryptographic verification failed — artifact digest mismatch, certificate chain not rooted in the pinned trusted root, expired certificates, or policy rejection. In verify_provenance this per-bundle error is captured and ultimately surfaces inside the final 'Sigstore verification failed' message.

Source

Thrown at crates/goose-cli/src/commands/update.rs:171

    }

    req.send().await.context("Failed to fetch attestations")
}

// Verify a single attestation bundle against the artifact digest and workflow.
fn verify_bundle(
    bundle_json: &serde_json::Value,
    artifact_digest: Sha256Hash,
    policy: &VerificationPolicy,
    trusted_root: &TrustedRoot,
    workflow: &str,
) -> Result<()> {
    let bundle_str = serde_json::to_string(bundle_json)?;
    let bundle = Bundle::from_json(&bundle_str)
        .map_err(|e| anyhow::anyhow!("Failed to parse bundle: {e}"))?;

    let result = sigstore_verify::verify(artifact_digest, &bundle, policy, trusted_root)
        .map_err(|e| anyhow::anyhow!("{e}"))?;

    let identity = result
        .identity
        .as_deref()
        .ok_or_else(|| anyhow::anyhow!("No identity in certificate"))?;

    let expected = format!("/.github/workflows/{workflow}");
    if !identity.contains(&expected) {
        bail!("Workflow mismatch: expected {workflow}, got {identity}");
    }

    Ok(())
}

/// Returns `Ok(())` when the downloaded archive has verified provenance.
async fn verify_provenance(archive_data: &[u8], tag: &str) -> Result<()> {
    let digest = sha256_hex(archive_data);
    println!("Archive SHA-256: {digest}");

View on GitHub (pinned to 3810898a74)

Solutions

  1. Treat as a hard stop — never bypass or downgrade the verification
  2. Delete any cached download and re-run `goose update` from a trusted network
  3. Verify the artifact manually with slsa-verifier against the official GitHub release to confirm
  4. If manual verification also fails, report possible tampering to the goose maintainers
Defensive patterns

Strategy: try-catch

Try / catch

match sigstore_verify::verify(digest, &bundle, &policy, &trusted_root) {
    Ok(result) => { /* continue with identity check */ }
    Err(e) => {
        // fail closed: log and abort; never proceed with an unverified artifact
        anyhow::bail!("provenance verification failed: {e}");
    }
}

Prevention

When it happens

Trigger: Archive bytes do not match the digest signed in the attestation (corrupted or tampered download); attestation signed by a key/cert outside goose's trusted root; replayed bundle from a different release; expired Fulcio cert at verification time.

Common situations: MITM'd or mirrored downloads; cached/partial downloads resumed incorrectly; release published with unsigned or mis-signed provenance; system clock badly wrong.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/516625c4159c34c5. Report an issue: GitHub.