| 116 | } |
| 117 | |
| 118 | func verifyRun(config *VerifyConfig) error { |
| 119 | ctx := context.Background() |
| 120 | opts := config.Opts |
| 121 | baseRepo := opts.BaseRepo |
| 122 | tagName := opts.TagName |
| 123 | |
| 124 | if tagName == "" { |
| 125 | release, err := shared.FetchLatestRelease(ctx, config.HttpClient, baseRepo) |
| 126 | if err != nil { |
| 127 | return err |
| 128 | } |
| 129 | tagName = release.TagName |
| 130 | } |
| 131 | |
| 132 | // Retrieve the ref for the release tag |
| 133 | ref, err := shared.FetchRefSHA(ctx, config.HttpClient, baseRepo, tagName) |
| 134 | if err != nil { |
| 135 | return err |
| 136 | } |
| 137 | |
| 138 | releaseRefDigest := artifact.NewDigestedArtifactForRelease(ref, shared.DigestAlgForRef(ref)) |
| 139 | |
| 140 | // Find all the attestations for the release tag SHA |
| 141 | attestations, err := config.AttClient.GetByDigest(api.FetchParams{ |
| 142 | Digest: releaseRefDigest.DigestWithAlg(), |
| 143 | PredicateType: "release", |
| 144 | Owner: baseRepo.RepoOwner(), |
| 145 | Repo: baseRepo.RepoOwner() + "/" + baseRepo.RepoName(), |
| 146 | Initiator: "github", |
| 147 | // TODO: Allow this value to be set via a flag. |
| 148 | // The limit is set to 100 to ensure we fetch all attestations for a given SHA. |
| 149 | // While multiple attestations can exist for a single SHA, |
| 150 | // only one attestation is associated with each release tag. |
| 151 | Limit: 100, |
| 152 | }) |
| 153 | if err != nil { |
| 154 | return fmt.Errorf("no attestations for tag %s (%s)", tagName, releaseRefDigest.DigestWithAlg()) |
| 155 | } |
| 156 | |
| 157 | // Filter attestations by tag name |
| 158 | filteredAttestations, err := shared.FilterAttestationsByTag(attestations, tagName) |
| 159 | if err != nil { |
| 160 | return fmt.Errorf("error parsing attestations for tag %s: %w", tagName, err) |
| 161 | } |
| 162 | |
| 163 | if len(filteredAttestations) == 0 { |
| 164 | return fmt.Errorf("no attestations found for release %s in %s", tagName, baseRepo.RepoName()) |
| 165 | } |
| 166 | |
| 167 | if len(filteredAttestations) > 1 { |
| 168 | return fmt.Errorf("duplicate attestations found for release %s in %s", tagName, baseRepo.RepoName()) |
| 169 | } |
| 170 | |
| 171 | // Verify attestation |
| 172 | verified, err := config.AttVerifier.VerifyAttestation(releaseRefDigest, filteredAttestations[0]) |
| 173 | if err != nil { |
| 174 | return fmt.Errorf("failed to verify attestations for tag %s: %w", tagName, err) |
| 175 | } |