Skip to content

Commit 007d600

Browse files
committed
feat: add SignOCI method to return both artifact and signature manifest digest
Signed-off-by: Junjie Gao <[email protected]>
1 parent bb2ee7a commit 007d600

File tree

1 file changed

+24
-15
lines changed

1 file changed

+24
-15
lines changed

notation.go

+24-15
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,21 @@ type SignOptions struct {
141141
// Sign signs the OCI artifact and push the signature to the Repository.
142142
// The descriptor of the sign content is returned upon successful signing.
143143
func Sign(ctx context.Context, signer Signer, repo registry.Repository, signOpts SignOptions) (ocispec.Descriptor, error) {
144+
artifactMenifestDesc, _, err := SignOCI(ctx, signer, repo, signOpts)
145+
return artifactMenifestDesc, err
146+
}
147+
148+
// SignOCI signs the OCI artifact and push the signature to the Repository.
149+
//
150+
// Both artifact and signature manifest descriptors are returned upon successful
151+
// signing.
152+
func SignOCI(ctx context.Context, signer Signer, repo registry.Repository, signOpts SignOptions) (artifactManifestDesc ocispec.Descriptor, sigManifestDesc ocispec.Descriptor, err error) {
144153
// sanity check
145154
if err := validateSignArguments(signer, signOpts.SignerSignOptions); err != nil {
146-
return ocispec.Descriptor{}, err
155+
return ocispec.Descriptor{}, ocispec.Descriptor{}, err
147156
}
148157
if repo == nil {
149-
return ocispec.Descriptor{}, errors.New("repo cannot be nil")
158+
return ocispec.Descriptor{}, ocispec.Descriptor{}, errors.New("repo cannot be nil")
150159
}
151160

152161
logger := log.GetLogger(ctx)
@@ -155,30 +164,30 @@ func Sign(ctx context.Context, signer Signer, repo registry.Repository, signOpts
155164
// artifactRef is a valid full reference
156165
artifactRef = ref.Reference
157166
}
158-
targetDesc, err := repo.Resolve(ctx, artifactRef)
167+
artifactManifestDesc, err = repo.Resolve(ctx, artifactRef)
159168
if err != nil {
160-
return ocispec.Descriptor{}, fmt.Errorf("failed to resolve reference: %w", err)
169+
return ocispec.Descriptor{}, ocispec.Descriptor{}, fmt.Errorf("failed to resolve reference: %w", err)
161170
}
162171

163172
// artifactRef is a tag or a digest, if it's a digest it has to match
164173
// the resolved digest
165-
if artifactRef != targetDesc.Digest.String() {
174+
if artifactRef != artifactManifestDesc.Digest.String() {
166175
if _, err := digest.Parse(artifactRef); err == nil {
167176
// artifactRef is a digest, but does not match the resolved digest
168-
return ocispec.Descriptor{}, fmt.Errorf("user input digest %s does not match the resolved digest %s", artifactRef, targetDesc.Digest.String())
177+
return ocispec.Descriptor{}, ocispec.Descriptor{}, fmt.Errorf("user input digest %s does not match the resolved digest %s", artifactRef, artifactManifestDesc.Digest.String())
169178
}
170179

171180
// artifactRef is a tag
172181
logger.Warnf("Always sign the artifact using digest(`@sha256:...`) rather than a tag(`:%s`) because tags are mutable and a tag reference can point to a different artifact than the one signed", artifactRef)
173-
logger.Infof("Resolved artifact tag `%s` to digest `%v` before signing", artifactRef, targetDesc.Digest)
182+
logger.Infof("Resolved artifact tag `%s` to digest `%v` before signing", artifactRef, artifactManifestDesc.Digest)
174183
}
175-
descToSign, err := addUserMetadataToDescriptor(ctx, targetDesc, signOpts.UserMetadata)
184+
descToSign, err := addUserMetadataToDescriptor(ctx, artifactManifestDesc, signOpts.UserMetadata)
176185
if err != nil {
177-
return ocispec.Descriptor{}, err
186+
return ocispec.Descriptor{}, ocispec.Descriptor{}, err
178187
}
179188
sig, signerInfo, err := signer.Sign(ctx, descToSign, signOpts.SignerSignOptions)
180189
if err != nil {
181-
return ocispec.Descriptor{}, err
190+
return ocispec.Descriptor{}, ocispec.Descriptor{}, err
182191
}
183192

184193
var pluginAnnotations map[string]string
@@ -188,21 +197,21 @@ func Sign(ctx context.Context, signer Signer, repo registry.Repository, signOpts
188197
logger.Debug("Generating annotation")
189198
annotations, err := generateAnnotations(signerInfo, pluginAnnotations)
190199
if err != nil {
191-
return ocispec.Descriptor{}, err
200+
return ocispec.Descriptor{}, ocispec.Descriptor{}, err
192201
}
193202
logger.Debugf("Generated annotations: %+v", annotations)
194-
logger.Debugf("Pushing signature of artifact descriptor: %+v, signature media type: %v", targetDesc, signOpts.SignatureMediaType)
195-
_, _, err = repo.PushSignature(ctx, signOpts.SignatureMediaType, sig, targetDesc, annotations)
203+
logger.Debugf("Pushing signature of artifact descriptor: %+v, signature media type: %v", artifactManifestDesc, signOpts.SignatureMediaType)
204+
_, sigManifestDesc, err = repo.PushSignature(ctx, signOpts.SignatureMediaType, sig, artifactManifestDesc, annotations)
196205
if err != nil {
197206
var referrerError *remote.ReferrersError
198207

199208
// do not log an error for failing to delete referral index
200209
if !errors.As(err, &referrerError) || !referrerError.IsReferrersIndexDelete() {
201210
logger.Error("Failed to push the signature")
202211
}
203-
return ocispec.Descriptor{}, ErrorPushSignatureFailed{Msg: err.Error()}
212+
return ocispec.Descriptor{}, ocispec.Descriptor{}, ErrorPushSignatureFailed{Msg: err.Error()}
204213
}
205-
return targetDesc, nil
214+
return artifactManifestDesc, sigManifestDesc, nil
206215
}
207216

208217
// SignBlob signs the arbitrary data from blobReader and returns

0 commit comments

Comments
 (0)