DevOpsil
GCP
85%
Needs Review

Fix GCP Cloud Storage '403 Forbidden' Errors

Amara OkaforAmara Okafor3 min read

The Error: "403 Forbidden" on Cloud Storage

You try to access a GCS object and get:

AccessDeniedException: 403 [email protected] does not have
storage.objects.get access to the Google Cloud Storage object.

Or from gsutil:

ServiceException: 403 Forbidden

You know the bucket exists and the object is there, but GCP won't let you in.

Root Cause

GCP Cloud Storage access is controlled by IAM policies and, on older buckets, ACLs. Common causes of 403 errors:

  • Missing IAM role on the service account or user
  • Wrong project context -- authenticated to a different project
  • Uniform bucket-level access enabled, making ACLs irrelevant
  • VPC Service Controls blocking access from outside the perimeter
  • Requester Pays enabled but the requester didn't provide a billing project

Step-by-Step Fix

1. Identify Who You Are

gcloud auth list
# Shows the active account

gcloud config get-value project
# Shows the active project

For service accounts in GKE or Compute Engine:

curl -H "Metadata-Flavor: Google" \
  http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email

2. Check Your Current Permissions

# Test if you can list objects
gsutil ls gs://my-bucket/

# Test a specific object
gsutil stat gs://my-bucket/my-object.txt

3. Check Bucket IAM Policy

gsutil iam get gs://my-bucket/

Or with gcloud:

gcloud storage buckets get-iam-policy gs://my-bucket/ --format=json

Look for your service account or user in the bindings. You need at minimum:

  • roles/storage.objectViewer -- to read objects
  • roles/storage.objectAdmin -- to read, write, and delete objects

4. Grant the Required Role

# Grant object viewer to a service account
gsutil iam ch \
  serviceAccount:[email protected]:objectViewer \
  gs://my-bucket/

# Or using gcloud for project-level access
gcloud projects add-iam-policy-binding my-project \
  --member="serviceAccount:[email protected]" \
  --role="roles/storage.objectViewer"

5. Check for Uniform Bucket-Level Access

gsutil uniformbucketlevelaccess get gs://my-bucket/

If enabled, ACLs are ignored and only IAM policies matter. This is the recommended setting, but it means you can't use gsutil acl commands.

6. Handle Cross-Project Access

If the bucket is in a different project, you need to grant permissions explicitly:

# In the project that OWNS the bucket
gsutil iam ch \
  serviceAccount:[email protected]:objectViewer \
  gs://my-bucket/

7. Check VPC Service Controls

If your organization uses VPC Service Controls:

gcloud access-context-manager perimeters list \
  --policy=POLICY_ID --format="table(name,status.resources)"

If the bucket's project is inside a perimeter, requests from outside are blocked with 403. You need to either:

  • Make the request from inside the perimeter (e.g., from a VM in the project)
  • Add an ingress rule to the perimeter

8. Handle Requester Pays Buckets

If the bucket has Requester Pays enabled:

# This fails
gsutil cat gs://requester-pays-bucket/file.txt

# This works -- specify a billing project
gsutil -u my-billing-project cat gs://requester-pays-bucket/file.txt

9. Verify the Fix

gsutil cat gs://my-bucket/my-object.txt
# Should return the file contents

# Or test with a simple list
gsutil ls gs://my-bucket/

Prevention Tips

  • Use Workload Identity in GKE instead of JSON key files. It eliminates key management headaches and automatically scopes permissions.
  • Apply least privilege using predefined roles like roles/storage.objectViewer instead of roles/storage.admin.
  • Enable uniform bucket-level access on all buckets so permissions are managed in one place (IAM), not two (IAM + ACLs).
  • Use gcloud policy-troubleshoot to debug access issues: gcloud policy-troubleshoot iam gs://bucket --permission=storage.objects.get [email protected].
  • Audit IAM bindings with Cloud Asset Inventory to catch overly permissive or missing roles.
Share:

Was this article helpful?

Amara Okafor
Amara Okafor

DevSecOps Lead

Security-first mindset in everything I ship. From zero-trust architectures to supply chain security, I make sure your pipeline doesn't become your weakest link.

Related Articles

Discussion