@@ -36,7 +36,7 @@ import (
3636 "sigs.k8s.io/controller-runtime/pkg/client"
3737
3838 sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1"
39- internalgit "github.com/fluxcd/source-controller/internal/git"
39+ intgit "github.com/fluxcd/source-controller/internal/git"
4040)
4141
4242// GitRepositoryReconciler reconciles a GitRepository object
@@ -76,10 +76,11 @@ func (r *GitRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro
7676 log .Error (err , "artifacts GC failed" )
7777 }
7878
79- // try git clone
79+ // try git sync
8080 syncedRepo , err := r .sync (ctx , * repo .DeepCopy ())
8181 if err != nil {
8282 log .Error (err , "Git repository sync failed" )
83+ return ctrl.Result {Requeue : true }, err
8384 }
8485
8586 // update status
@@ -128,6 +129,7 @@ func (r *GitRepositoryReconciler) sync(ctx context.Context, repository sourcev1.
128129 }
129130 }
130131
132+ // determine auth method
131133 var auth transport.AuthMethod
132134 if repository .Spec .SecretRef != nil {
133135 name := types.NamespacedName {
@@ -142,7 +144,7 @@ func (r *GitRepositoryReconciler) sync(ctx context.Context, repository sourcev1.
142144 return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
143145 }
144146
145- method , cleanup , err := internalgit .AuthMethodFromSecret (repository .Spec .URL , secret )
147+ method , cleanup , err := intgit .AuthMethodFromSecret (repository .Spec .URL , secret )
146148 if err != nil {
147149 err = fmt .Errorf ("auth error: %w" , err )
148150 return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .AuthenticationFailedReason , err .Error ()), err
@@ -259,6 +261,45 @@ func (r *GitRepositoryReconciler) sync(ctx context.Context, repository sourcev1.
259261 return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
260262 }
261263
264+ // verify PGP signature
265+ if repository .Spec .Verification != nil {
266+ commit , err := repo .CommitObject (ref .Hash ())
267+ if err != nil {
268+ err = fmt .Errorf ("git resolve HEAD error: %w" , err )
269+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .GitOperationFailedReason , err .Error ()), err
270+ }
271+
272+ if commit .PGPSignature == "" {
273+ err = fmt .Errorf ("PGP signature not found for commit '%s'" , ref .Hash ())
274+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .VerificationFailedReason , err .Error ()), err
275+ }
276+
277+ name := types.NamespacedName {
278+ Namespace : repository .GetNamespace (),
279+ Name : repository .Spec .Verification .SecretRef .Name ,
280+ }
281+
282+ var secret corev1.Secret
283+ err = r .Client .Get (ctx , name , & secret )
284+ if err != nil {
285+ err = fmt .Errorf ("PGP public keys secret error: %w" , err )
286+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .VerificationFailedReason , err .Error ()), err
287+ }
288+
289+ var verified bool
290+ for _ , bytes := range secret .Data {
291+ if _ , err := commit .Verify (string (bytes )); err == nil {
292+ verified = true
293+ break
294+ }
295+ }
296+
297+ if ! verified {
298+ err = fmt .Errorf ("PGP signature of '%s' can't be verified" , commit .Author )
299+ return sourcev1 .GitRepositoryNotReady (repository , sourcev1 .VerificationFailedReason , err .Error ()), err
300+ }
301+ }
302+
262303 if revision == "" {
263304 revision = fmt .Sprintf ("%s/%s" , branch , ref .Hash ().String ())
264305 }
@@ -307,7 +348,6 @@ func (r *GitRepositoryReconciler) shouldResetStatus(repository sourcev1.GitRepos
307348 }
308349 }
309350
310- // set initial status
311351 if len (repository .Status .Conditions ) == 0 || resetStatus {
312352 resetStatus = true
313353 }
0 commit comments