Description
ee_utils_sak_validate() can report all checks as OK while sf_as_ee() with via = "gcs_to_asset" still fails with a 403. The two functions
require different GCS IAM permissions and the validator does not test all of them.
Steps to reproduce
- Create a service account and grant it
roles/storage.objectAdmin on the bucket.
- Run the validator:
rgee::ee_utils_sak_validate("path/to/key.json", bucket = "my-bucket")
Upload GCS objects : OK!
Download GCS objects : OK!
GEE & GCS sync : OK!
- Attempt the upload:
sf_as_ee(FC, via = "gcs_to_asset", bucket = "my-bucket", assetId = "...")
Error: http_403 <SA_EMAIL> does not have storage.buckets.get access to the Google Cloud Storage bucket.
Root cause
sf_as_ee() with via = "gcs_to_asset" calls googleCloudStorageR::gcs_get_bucket() as a pre-flight check, which requires storage.buckets.get.
This permission is not included in roles/storage.objectAdmin and is not tested by ee_utils_sak_validate().
Workaround
Grant an additional role to the service account:
gsutil iam ch serviceAccount:<SA_EMAIL>:legacyBucketReader gs://my-bucket
Suggested fix
- Add a
gcs_get_bucket() call inside ee_utils_sak_validate() so it catches this permission gap, or
- Document the minimum required roles:
roles/storage.objectAdmin + roles/storage.legacyBucketReader (or simply roles/storage.admin to avoid
the confusion entirely).
Description
ee_utils_sak_validate()can report all checks as OK whilesf_as_ee()withvia = "gcs_to_asset"still fails with a 403. The two functionsrequire different GCS IAM permissions and the validator does not test all of them.
Steps to reproduce
roles/storage.objectAdminon the bucket.Root cause
sf_as_ee()withvia = "gcs_to_asset"callsgoogleCloudStorageR::gcs_get_bucket()as a pre-flight check, which requiresstorage.buckets.get.This permission is not included in
roles/storage.objectAdminand is not tested byee_utils_sak_validate().Workaround
Grant an additional role to the service account:
Suggested fix
gcs_get_bucket()call insideee_utils_sak_validate()so it catches this permission gap, orroles/storage.objectAdmin+roles/storage.legacyBucketReader(or simplyroles/storage.adminto avoidthe confusion entirely).