@@ -297,6 +297,7 @@ func (r *OCIRepositoryReconciler) reconcile(ctx context.Context, obj *sourcev1.O
297
297
// reconcileSource fetches the upstream OCI artifact metadata and content.
298
298
// If this fails, it records v1beta2.FetchFailedCondition=True on the object and returns early.
299
299
func (r * OCIRepositoryReconciler ) reconcileSource (ctx context.Context , obj * sourcev1.OCIRepository , metadata * sourcev1.Artifact , dir string ) (sreconcile.Result , error ) {
300
+ var verifyOpts []remote.Option
300
301
ctxTimeout , cancel := context .WithTimeout (ctx , obj .Spec .Timeout .Duration )
301
302
defer cancel ()
302
303
@@ -308,7 +309,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
308
309
conditions .Delete (obj , sourcev1 .SourceVerifiedCondition )
309
310
}
310
311
311
- options := r .craneOptions (ctxTimeout , obj .Spec .Insecure )
312
+ craneOpts := r .craneOptions (ctxTimeout , obj .Spec .Insecure )
312
313
313
314
// Generate the registry credential keychain either from static credentials or using cloud OIDC
314
315
keychain , err := r .keychain (ctx , obj )
@@ -320,7 +321,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
320
321
conditions .MarkTrue (obj , sourcev1 .FetchFailedCondition , e .Reason , e .Err .Error ())
321
322
return sreconcile .ResultEmpty , e
322
323
}
323
- options = append (options , crane .WithAuthFromKeychain (keychain ))
324
+ craneOpts = append (craneOpts , crane .WithAuthFromKeychain (keychain ))
324
325
325
326
if _ , ok := keychain .(soci.Anonymous ); obj .Spec .Provider != sourcev1 .GenericOCIProvider && ok {
326
327
auth , authErr := oidcAuth (ctxTimeout , obj .Spec .URL , obj .Spec .Provider )
@@ -333,8 +334,15 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
333
334
return sreconcile .ResultEmpty , e
334
335
}
335
336
if auth != nil {
336
- options = append (options , crane .WithAuth (auth ))
337
+ craneOpts = append (craneOpts , crane .WithAuth (auth ))
338
+ verifyOpts = append (verifyOpts , remote .WithAuth (auth ))
339
+ } else {
340
+ // If no auth is configured at all, use anonymous access
341
+ verifyOpts = append (verifyOpts , remote .WithAuthFromKeychain (keychain ))
337
342
}
343
+ } else {
344
+ // we need to make sure not to pass a keychain and an auth option at the same time
345
+ verifyOpts = append (verifyOpts , remote .WithAuthFromKeychain (keychain ))
338
346
}
339
347
340
348
// Generate the transport for remote operations
@@ -348,11 +356,12 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
348
356
return sreconcile .ResultEmpty , e
349
357
}
350
358
if transport != nil {
351
- options = append (options , crane .WithTransport (transport ))
359
+ craneOpts = append (craneOpts , crane .WithTransport (transport ))
360
+ verifyOpts = append (verifyOpts , remote .WithTransport (transport ))
352
361
}
353
362
354
363
// Determine which artifact revision to pull
355
- url , err := r .getArtifactURL (obj , options )
364
+ url , err := r .getArtifactURL (obj , craneOpts )
356
365
if err != nil {
357
366
if _ , ok := err .(invalidOCIURLError ); ok {
358
367
e := serror .NewStalling (
@@ -370,7 +379,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
370
379
}
371
380
372
381
// Get the upstream revision from the artifact digest
373
- revision , err := r .getRevision (url , options )
382
+ revision , err := r .getRevision (url , craneOpts )
374
383
if err != nil {
375
384
e := serror .NewGeneric (
376
385
fmt .Errorf ("failed to determine artifact digest: %w" , err ),
@@ -401,7 +410,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
401
410
} else if ! obj .GetArtifact ().HasRevision (revision ) ||
402
411
conditions .GetObservedGeneration (obj , sourcev1 .SourceVerifiedCondition ) != obj .Generation ||
403
412
conditions .IsFalse (obj , sourcev1 .SourceVerifiedCondition ) {
404
- err := r .verifySignature (ctx , obj , url , keychain )
413
+ err := r .verifySignature (ctx , obj , url , verifyOpts ... )
405
414
if err != nil {
406
415
provider := obj .Spec .Verify .Provider
407
416
if obj .Spec .Verify .SecretRef == nil {
@@ -425,7 +434,7 @@ func (r *OCIRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
425
434
}
426
435
427
436
// Pull artifact from the remote container registry
428
- img , err := crane .Pull (url , options ... )
437
+ img , err := crane .Pull (url , craneOpts ... )
429
438
if err != nil {
430
439
e := serror .NewGeneric (
431
440
fmt .Errorf ("failed to pull artifact from '%s': %w" , obj .Spec .URL , err ),
@@ -585,15 +594,15 @@ func (r *OCIRepositoryReconciler) digestFromRevision(revision string) string {
585
594
586
595
// verifySignature verifies the authenticity of the given image reference url. First, it tries using a key
587
596
// if a secret with a valid public key is provided. If not, it falls back to a keyless approach for verification.
588
- func (r * OCIRepositoryReconciler ) verifySignature (ctx context.Context , obj * sourcev1.OCIRepository , url string , keychain authn. Keychain ) error {
597
+ func (r * OCIRepositoryReconciler ) verifySignature (ctx context.Context , obj * sourcev1.OCIRepository , url string , opt ... remote. Option ) error {
589
598
ctxTimeout , cancel := context .WithTimeout (ctx , obj .Spec .Timeout .Duration )
590
599
defer cancel ()
591
600
592
601
provider := obj .Spec .Verify .Provider
593
602
switch provider {
594
603
case "cosign" :
595
604
defaultCosignOciOpts := []soci.Options {
596
- soci .WithAuthnKeychain ( keychain ),
605
+ soci .WithRemoteOptions ( opt ... ),
597
606
}
598
607
599
608
ref , err := name .ParseReference (url )
@@ -807,8 +816,10 @@ func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *sourcev1.O
807
816
808
817
transport := remote .DefaultTransport .Clone ()
809
818
tlsConfig := transport .TLSClientConfig
819
+ clientCert , withClientCert := certSecret .Data [oci .ClientCert ]
820
+ caCert , withCACert := certSecret .Data [oci .CACert ]
810
821
811
- if clientCert , ok := certSecret . Data [ oci . ClientCert ]; ok {
822
+ if withClientCert {
812
823
// parse and set client cert and secret
813
824
if clientKey , ok := certSecret .Data [oci .ClientKey ]; ok {
814
825
cert , err := tls .X509KeyPair (clientCert , clientKey )
@@ -821,14 +832,20 @@ func (r *OCIRepositoryReconciler) transport(ctx context.Context, obj *sourcev1.O
821
832
}
822
833
}
823
834
824
- if caCert , ok := certSecret . Data [ oci . CACert ]; ok {
835
+ if withCACert {
825
836
syscerts , err := x509 .SystemCertPool ()
826
837
if err != nil {
827
838
return nil , err
828
839
}
829
840
syscerts .AppendCertsFromPEM (caCert )
830
841
tlsConfig .RootCAs = syscerts
831
842
}
843
+
844
+ // If no cert is provided, verify that Insecure is set to true.
845
+ if obj .Spec .Insecure && ! withCACert && ! withClientCert {
846
+ tlsConfig .InsecureSkipVerify = true
847
+ }
848
+
832
849
return transport , nil
833
850
}
834
851
0 commit comments