From de37ae3aa80c868a852524877e51c83d34453f06 Mon Sep 17 00:00:00 2001 From: Antonio Nunez Date: Tue, 5 May 2026 11:48:33 +0800 Subject: [PATCH 1/2] feat: replace GCS TestPermissions health check with probe object round-trip --- .../anytrust/google_cloud_storage_service.go | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/daprovider/anytrust/google_cloud_storage_service.go b/daprovider/anytrust/google_cloud_storage_service.go index 0d9b89638e0..4c65a70201b 100644 --- a/daprovider/anytrust/google_cloud_storage_service.go +++ b/daprovider/anytrust/google_cloud_storage_service.go @@ -7,11 +7,9 @@ import ( "fmt" "io" "math" - "sort" "time" googlestorage "cloud.google.com/go/storage" - "github.com/google/go-cmp/cmp" "github.com/spf13/pflag" "google.golang.org/api/option" @@ -159,22 +157,37 @@ func (gcs *GoogleCloudStorageService) String() string { } func (gcs *GoogleCloudStorageService) HealthCheck(ctx context.Context) error { + // GCP's testIamPermissions API does not evaluate conditional IAM bindings, + // so it always returns empty results when permissions are granted via a + // condition (e.g. resource.name.startsWith(...)). Instead, we verify + // storage access by performing an actual write/read/delete round-trip on a + // small probe object within our configured prefix. + probeKey := gcs.objectPrefix + ".health-check-probe" bucket := gcs.operator.Bucket(gcs.bucket) - // check if we have bucket permissions - permissions := []string{ - "storage.objects.create", - "storage.objects.delete", - "storage.objects.list", - "storage.objects.get", + + // write + w := bucket.Object(probeKey).NewWriter(ctx) + if _, err := w.Write([]byte("health-check")); err != nil { + return fmt.Errorf("health check: failed to write probe object: %w", err) + } + if err := w.Close(); err != nil { + return fmt.Errorf("health check: failed to close probe object writer: %w", err) } - perms, err := bucket.IAM().TestPermissions(ctx, permissions) + + // read + r, err := bucket.Object(probeKey).NewReader(ctx) if err != nil { - return fmt.Errorf("could not check permissions: %w", err) + return fmt.Errorf("health check: failed to read probe object: %w", err) } - sort.Strings(permissions) - sort.Strings(perms) - if !cmp.Equal(perms, permissions) { - return fmt.Errorf("permissions mismatch (-want +got):\n%s", cmp.Diff(permissions, perms)) + if _, err := io.ReadAll(r); err != nil { + r.Close() + return fmt.Errorf("health check: failed to read probe object data: %w", err) + } + r.Close() + + // delete + if err := bucket.Object(probeKey).Delete(ctx); err != nil { + return fmt.Errorf("health check: failed to delete probe object: %w", err) } return nil From e7e03316e72d13cacf8d1c6178f04199ea04c572 Mon Sep 17 00:00:00 2001 From: Antonio Nunez Date: Wed, 20 May 2026 16:39:52 +0800 Subject: [PATCH 2/2] fix(anytrust): suppress context.Canceled log in GoogleCloudStorageService.GetByHash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit context.Canceled is expected when the ReaderTimeoutWrapper or RedundantStorageService returns early because a faster inner service already succeeded. Logging it at ERROR level is misleading — the overall call succeeded. --- daprovider/anytrust/google_cloud_storage_service.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/daprovider/anytrust/google_cloud_storage_service.go b/daprovider/anytrust/google_cloud_storage_service.go index 4c65a70201b..8864a083bc6 100644 --- a/daprovider/anytrust/google_cloud_storage_service.go +++ b/daprovider/anytrust/google_cloud_storage_service.go @@ -4,6 +4,7 @@ package anytrust import ( "context" + "errors" "fmt" "io" "math" @@ -131,7 +132,12 @@ func (gcs *GoogleCloudStorageService) GetByHash(ctx context.Context, key common. log.Trace("anytrust.GoogleCloudStorageService.GetByHash", "key", pretty.PrettyHash(key), "this", gcs) buf, err := gcs.operator.Download(ctx, gcs.bucket, gcs.objectPrefix, key) if err != nil { - log.Error("anytrust.GoogleCloudStorageService.GetByHash", "err", err) + // context.Canceled is expected when RedundantStorageService cancels + // the shared sub-context after a faster inner service already returned + // successfully. Logging it at ERROR level would be misleading. + if !errors.Is(err, context.Canceled) { + log.Error("anytrust.GoogleCloudStorageService.GetByHash", "err", err) + } return nil, err } return buf, nil