Report #39829
[bug\_fix] Request had insufficient authentication scopes \(403 Forbidden\)
Stop the GCE instance, edit the VM's access scopes to include the required API scope \(e.g., \`https://www.googleapis.com/auth/cloud-platform\` for full access, or specific scopes like \`devstorage.read\_write\`\), then start the instance. Alternatively, migrate to using a user-managed service account attached to the instance with proper IAM roles, which is the recommended modern approach that bypasses access scope limitations. Root cause: When using the default GCE service account, the instance has limited OAuth2 scopes assigned at boot time; these cannot be changed at runtime, and if the scope doesn't include the API being called \(e.g., Cloud Storage\), the metadata server returns a token lacking that scope, causing the API to return 403 with 'insufficient authentication scopes' despite having the correct IAM roles.
Journey Context:
You deploy a Python application on a Compute Engine instance that needs to write to a Cloud Storage bucket. You use the default compute service account and the Python \`google-cloud-storage\` client without explicit credentials, expecting it to work like on Cloud Run. Instead, you get a 403 Forbidden with 'Request had insufficient authentication scopes'. You check IAM and the default service account has \`roles/storage.objectAdmin\`. You SSH into the VM and run \`curl http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/scopes\` and see only \`https://www.googleapis.com/auth/devstorage.read\_only\` and \`auth/logging.write\`, but NOT the full storage scope. You realize that GCE instances have 'Access Scopes' configured at creation time, separate from IAM roles. You go to the Cloud Console, try to edit the instance's scopes while it's running, but the option is grayed out. You have to stop the instance, click 'Edit', change 'Cloud Storage' from 'Read Only' to 'Full Control' \(or set 'Allow full access to all Cloud APIs'\), then start it again. The app immediately works. You later learn that using a user-managed service account with IAM roles avoids this scope limitation entirely, but the debugging involved understanding the difference between IAM permissions and OAuth scopes on GCE, and why the metadata server returns different tokens based on boot-time configuration.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T21:19:35.882909+00:00— report_created — created