Skip to content

Commit a794e28

Browse files
committed
Fix verification condition
Delete a failed verification condition at the beginning of the source reconciliation and set `SourceVerifiedCondition` to false approprietly. Set the `BuildOptions.Verify` to true as long as Verify is enabled in the API fields. Signed-off-by: Soule BA <soule@weave.works>
1 parent 25673ac commit a794e28

File tree

9 files changed

+31
-27
lines changed

9 files changed

+31
-27
lines changed

api/v1beta2/helmchart_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ type HelmChartSpec struct {
9090
// Verify contains the secret name containing the trusted public keys
9191
// used to verify the signature and specifies which provider to use to check
9292
// whether OCI image is authentic.
93-
// This field is only supported for OCI sources.
93+
// This field is only supported when using HelmRepository source with spec.type 'oci'.
9494
// Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.
9595
// +optional
9696
Verify *OCIRepositoryVerification `json:"verify,omitempty"`

config/crd/bases/source.toolkit.fluxcd.io_helmcharts.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,9 @@ spec:
407407
description: Verify contains the secret name containing the trusted
408408
public keys used to verify the signature and specifies which provider
409409
to use to check whether OCI image is authentic. This field is only
410-
supported for OCI sources. Chart dependencies, which are not bundled
411-
in the umbrella chart artifact, are not verified.
410+
supported when using HelmRepository source with spec.type 'oci'.
411+
Chart dependencies, which are not bundled in the umbrella chart
412+
artifact, are not verified.
412413
properties:
413414
provider:
414415
default: cosign

controllers/helmchart_controller.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,12 @@ func (r *HelmChartReconciler) reconcileStorage(ctx context.Context, obj *sourcev
372372
}
373373

374374
func (r *HelmChartReconciler) reconcileSource(ctx context.Context, obj *sourcev1.HelmChart, build *chart.Build) (_ sreconcile.Result, retErr error) {
375+
// Remove any failed verification condition.
376+
// The reason is that a failing verification should be recalculated.
377+
if conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) {
378+
conditions.Delete(obj, sourcev1.SourceVerifiedCondition)
379+
}
380+
375381
// Retrieve the source
376382
s, err := r.getSource(ctx, obj)
377383
if err != nil {
@@ -650,15 +656,8 @@ func (r *HelmChartReconciler) buildFromHelmRepository(ctx context.Context, obj *
650656
Force: obj.Generation != obj.Status.ObservedGeneration,
651657
// The remote builder will not attempt to download the chart if
652658
// an artifact exists with the same name and version and `Force` is false.
653-
// It will try to verify the chart if:
654-
// - we are on the first reconciliation
655-
// - the HelmChart spec has changed (generation drift)
656-
// - the previous reconciliation resulted in a failed artifact verification
657-
// - there is no artifact in storage
658-
Verify: obj.Spec.Verify != nil && (obj.Generation <= 0 ||
659-
conditions.GetObservedGeneration(obj, sourcev1.SourceVerifiedCondition) != obj.Generation ||
660-
conditions.IsFalse(obj, sourcev1.SourceVerifiedCondition) ||
661-
obj.GetArtifact() == nil),
659+
// It will however try to verify the chart if `obj.Spec.Verify` is set, at every reconciliation.
660+
Verify: obj.Spec.Verify != nil && obj.Spec.Verify.Provider != "",
662661
}
663662
if artifact := obj.GetArtifact(); artifact != nil {
664663
opts.CachedChart = r.Storage.LocalPath(*artifact)
@@ -1293,9 +1292,13 @@ func observeChartBuild(obj *sourcev1.HelmChart, build *chart.Build, err error) {
12931292
}
12941293

12951294
switch buildErr.Reason {
1296-
case chart.ErrChartMetadataPatch, chart.ErrValuesFilesMerge, chart.ErrDependencyBuild, chart.ErrChartPackage, chart.ErrChartVerification:
1295+
case chart.ErrChartMetadataPatch, chart.ErrValuesFilesMerge, chart.ErrDependencyBuild, chart.ErrChartPackage:
1296+
conditions.Delete(obj, sourcev1.FetchFailedCondition)
1297+
conditions.MarkTrue(obj, sourcev1.BuildFailedCondition, buildErr.Reason.Reason, buildErr.Error())
1298+
case chart.ErrChartVerification:
12971299
conditions.Delete(obj, sourcev1.FetchFailedCondition)
12981300
conditions.MarkTrue(obj, sourcev1.BuildFailedCondition, buildErr.Reason.Reason, buildErr.Error())
1301+
conditions.MarkFalse(obj, sourcev1.SourceVerifiedCondition, sourcev1.VerificationError, buildErr.Error())
12991302
default:
13001303
conditions.Delete(obj, sourcev1.BuildFailedCondition)
13011304
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, buildErr.Reason.Reason, buildErr.Error())

controllers/helmchart_controller_test.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2262,11 +2262,11 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignature(t *testing.T
22622262

22632263
tests := []struct {
22642264
name string
2265+
shouldSign bool
2266+
beforeFunc func(obj *sourcev1.HelmChart)
22652267
want sreconcile.Result
22662268
wantErr bool
22672269
wantErrMsg string
2268-
shouldSign bool
2269-
beforeFunc func(obj *sourcev1.HelmChart)
22702270
assertConditions []metav1.Condition
22712271
cleanFunc func(g *WithT, build *chart.Build)
22722272
}{
@@ -2280,11 +2280,12 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignature(t *testing.T
22802280
SecretRef: &meta.LocalObjectReference{Name: "cosign-key"},
22812281
}
22822282
},
2283+
want: sreconcile.ResultEmpty,
22832284
wantErr: true,
22842285
wantErrMsg: "chart verification error: failed to verify <url>: no matching signatures:",
2285-
want: sreconcile.ResultEmpty,
22862286
assertConditions: []metav1.Condition{
22872287
*conditions.TrueCondition(sourcev1.BuildFailedCondition, "ChartVerificationError", "chart verification error: failed to verify <url>: no matching signatures:"),
2288+
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, sourcev1.VerificationError, "chart verification error: failed to verify <url>: no matching signatures:"),
22882289
},
22892290
},
22902291
{
@@ -2296,14 +2297,16 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignature(t *testing.T
22962297
Provider: "cosign",
22972298
}
22982299
},
2299-
wantErr: true,
23002300
want: sreconcile.ResultEmpty,
2301+
wantErr: true,
23012302
assertConditions: []metav1.Condition{
23022303
*conditions.TrueCondition(sourcev1.BuildFailedCondition, "ChartVerificationError", "chart verification error: failed to verify <url>: no matching signatures:"),
2304+
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, sourcev1.VerificationError, "chart verification error: failed to verify <url>: no matching signatures:"),
23032305
},
23042306
},
23052307
{
2306-
name: "signed charts should pass verification",
2308+
name: "signed charts should pass verification",
2309+
shouldSign: true,
23072310
beforeFunc: func(obj *sourcev1.HelmChart) {
23082311
obj.Spec.Chart = metadata.Name
23092312
obj.Spec.Version = metadata.Version
@@ -2312,8 +2315,7 @@ func TestHelmChartReconciler_reconcileSourceFromOCI_verifySignature(t *testing.T
23122315
SecretRef: &meta.LocalObjectReference{Name: "cosign-key"},
23132316
}
23142317
},
2315-
shouldSign: true,
2316-
want: sreconcile.ResultSuccess,
2318+
want: sreconcile.ResultSuccess,
23172319
assertConditions: []metav1.Condition{
23182320
*conditions.TrueCondition(sourcev1.ArtifactOutdatedCondition, "NewChart", "pulled '<name>' chart with version '<version>'"),
23192321
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of version <version>"),

docs/api/source.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,7 @@ OCIRepositoryVerification
684684
<p>Verify contains the secret name containing the trusted public keys
685685
used to verify the signature and specifies which provider to use to check
686686
whether OCI image is authentic.
687-
This field is only supported for OCI sources.
687+
This field is only supported when using HelmRepository source with spec.type &lsquo;oci&rsquo;.
688688
Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.</p>
689689
</td>
690690
</tr>
@@ -2269,7 +2269,7 @@ OCIRepositoryVerification
22692269
<p>Verify contains the secret name containing the trusted public keys
22702270
used to verify the signature and specifies which provider to use to check
22712271
whether OCI image is authentic.
2272-
This field is only supported for OCI sources.
2272+
This field is only supported when using HelmRepository source with spec.type &lsquo;oci&rsquo;.
22732273
Chart dependencies, which are not bundled in the umbrella chart artifact, are not verified.</p>
22742274
</td>
22752275
</tr>

docs/spec/v1beta2/helmcharts.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ data:
290290

291291
Note that the keys must have the `.pub` extension for Flux to make use of them.
292292

293-
Flux will loop over the public keys and use them verify a HelmChart's signature.
293+
Flux will loop over the public keys and use them to verify a HelmChart's signature.
294294
This allows for older HelmCharts to be valid as long as the right key is in the secret.
295295

296296
#### Keyless verification

docs/spec/v1beta2/ocirepositories.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ data:
462462

463463
Note that the keys must have the `.pub` extension for Flux to make use of them.
464464

465-
Flux will loop over the public keys and use them verify an artifact's signature.
465+
Flux will loop over the public keys and use them to verify an artifact's signature.
466466
This allows for older artifacts to be valid as long as the right key is in the secret.
467467

468468
#### Keyless verification

internal/helm/registry/auth.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func KeychainAdaptHelper(keyChain authn.Keychain) func(string) (registry.LoginOp
105105
}
106106

107107
// AuthAdaptHelper returns an ORAS credentials callback configured with the authorization data
108-
// from the given authn authenticator This allows for example to make use of credential helpers from
108+
// from the given authn authenticator. This allows for example to make use of credential helpers from
109109
// cloud providers.
110110
// Ref: https://github.com/google/go-containerregistry/tree/main/pkg/authn
111111
func AuthAdaptHelper(auth authn.Authenticator) (registry.LoginOption, error) {

internal/helm/repository/chart_repository.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -523,10 +523,8 @@ func (r *ChartRepository) RemoveCache() error {
523523
}
524524

525525
// VerifyChart verifies the chart against a signature.
526-
// If no signature is provided, a keyless verification is performed.
527526
// It returns an error on failure.
528527
func (r *ChartRepository) VerifyChart(_ context.Context, _ *repo.ChartVersion) error {
529-
// no-op
530528
// this is a no-op because this is not implemented yet.
531529
return fmt.Errorf("not implemented")
532530
}

0 commit comments

Comments
 (0)