Skip to content

attestation verify --bundle fails due to a default newline at the end of the bundle file #9521

@ramonpetgrave64

Description

@ramonpetgrave64

Describe the bug

gh --version
gh version 2.55.0 (2024-08-20)
https://github.com/cli/cli/releases/tag/v2.55.0

When you try to to run gh attestation verify --bundle ... against an unmodified .jsonl file provided by the Action /actions/attest-build-provenance@1.4.1, it fails with a misleading error message about hashes not matching. But if you delete the empty newline character from the file, verifying succeeds.

Steps to reproduce the behavior

  1. Clone my repo https://github.com/ramonpetgrave/github-build-attestations-rw

  2. Download my artifacts and attestations bundle files from a recent workflow run (which I've stored as artifacts with actions/upload-artifact@v4)

    gh run download 10537450203
    
  3. Verifying the unmodified attestation file will fail

     gh attestation verify slsa3_build_artifact/gundam --bundle slsa3_build_attestation/attestation.jsonl --repo ramonpetgrave/github-build-attestations-rw                                                                                                       
    Loaded digest sha256:5b4167c6bdf2cf66e30ac3af8d63036bda530293e5dd694085f7df9d8d4fa91d for file://slsa3_build_artifact/gundam
    Loaded 2 attestations from slsa3_build_attestation/attestation.jsonl
    ✗ Verification failed
    
    Error: verifying with issuer "sigstore.dev": failed to verify signature: provided artifact digest does not match any digest in statement
    
  4. Remove the last byte from the attestations file, which is a newline character.

    truncate -s -1 slsa3_build_attestation/attestation.jsonl 
    
  5. Verification now succeeds

    gh attestation verify slsa3_build_artifact/gundam --bundle slsa3_build_attestation/attestation.jsonl --repo ramonpetgrave/github-build-attestations-rw
    Loaded digest sha256:5b4167c6bdf2cf66e30ac3af8d63036bda530293e5dd694085f7df9d8d4fa91d for file://slsa3_build_artifact/gundam
    Loaded 1 attestation from slsa3_build_attestation/attestation.jsonl
    ✓ Verification succeeded!
    
    sha256:5b4167c6bdf2cf66e30ac3af8d63036bda530293e5dd694085f7df9d8d4fa91d was attested by:
    REPO                                        PREDICATE_TYPE                  WORKFLOW                                                             
    ramonpetgrave/github-build-attestations-rw  https://slsa.dev/provenance/v1  .github/workflows/attest-build-provenance-slsa3-rw.yml@refs/heads/dev
    

Expected vs actual behavior

Using the Action actions/attest-build-provenance correctly and and downloading it as an "artifact", I expect to be able to do an "offline" verification using that same bundle of attestations without any additional handling of the file.

The jsonlines spec seems to be okay with newlines at the end of a .jsonl file, so perhaps the Action actions/attest-build-provenance is correctly adding the newline.

But I think the gh CLI should avoid trying to parse empty lines.

  • var line []byte
    line, err = reader.ReadBytes('\n')
    for err == nil {
    var bundle bundle.ProtobufBundle
    bundle.Bundle = new(protobundle.Bundle)
    err = bundle.UnmarshalJSON(line)
    if err != nil {
    return nil, fmt.Errorf("failed to unmarshal bundle from JSON: %v", err)
    }
    a := api.Attestation{Bundle: &bundle}
    attestations = append(attestations, &a)
    line, err = reader.ReadBytes('\n')
    }

Otherwise, gh attestation verify --bundle ... only succeeds when I manually remove the empty line at the end of the attestations bundle file.

Logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinggh-attestationrelated to the gh attestation commandneeds-triageneeds to be reviewed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions