Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
GCP with AI By James Joyner IV · · 8 min read Last reviewed Jul 2026

GCP Error: 'Permission secretmanager.versions.access denied' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix Secret Manager 403 'Permission secretmanager.versions.access denied': grant secretAccessor to the right identity, at the right scope, on the secret.

  • #gcp
  • #troubleshooting
  • #errors
  • #iam
Free toolkit

Stuck on this GCP with AI error? Get the free incident triage checklist

A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.

Overview

Reading a secret value fails when the calling identity lacks secretmanager.versions.access on that secret:

google.api_core.exceptions.PermissionDenied: 403 Permission
'secretmanager.versions.access' denied for resource
'projects/acme-prod-platform/secrets/db-password/versions/latest'
(or it may not exist).

Secret Manager access is granted per secret (or per project) via roles/secretmanager.secretAccessor. A workload can list secret names yet be denied the value, because accessing a version is a distinct, tightly-scoped permission.

Symptoms

  • Apps on Cloud Run / GKE / Cloud Functions fail at startup fetching a secret with secretmanager.versions.access denied.
  • The identity can see the secret exists but cannot read its payload.
  • Works in dev (broad roles) but fails in prod where IAM is least-privilege.
  • The (or it may not exist) tail appears even though the secret is clearly there.

Common Root Causes

1. Missing secretAccessor role

The runtime service account was never granted roles/secretmanager.secretAccessor on the secret or project.

2. Wrong runtime identity

The service runs as the default compute/App Engine service account, not the one you granted access to.

3. Grant at the wrong scope

The role was bound on a different project, or on a different secret than the one being read.

4. Secret Manager API disabled, or secret in another project

The API is off, or the secret path points to a project the identity has no access to (hence “or it may not exist”).

How to Diagnose

All read-only.

# Which identity is the workload actually running as?
gcloud run services describe api \
  --region=us-central1 --project=acme-prod-platform \
  --format="value(spec.template.spec.serviceAccountName)"

# Does that identity have accessor on the secret?
gcloud secrets get-iam-policy db-password \
  --project=acme-prod-platform \
  --flatten="bindings[].members" \
  --filter="bindings.role:roles/secretmanager.secretAccessor" \
  --format="table(bindings.members)"

# Test the exact permission for the active identity
gcloud secrets get-iam-policy db-password --project=acme-prod-platform >/dev/null && \
gcloud projects test-iam-permissions acme-prod-platform \
  --permissions=secretmanager.versions.access

# Is the API enabled and the secret present?
gcloud services list --enabled --project=acme-prod-platform \
  --filter="config.name:secretmanager.googleapis.com"
gcloud secrets describe db-password --project=acme-prod-platform --format="value(name)"

If the runtime service account isn’t in the accessor list, that’s the gap.

Fixes

Grant secretAccessor on the specific secret (least privilege — prefer per-secret over project-wide):

gcloud secrets add-iam-policy-binding db-password \
  --project=acme-prod-platform \
  --member="serviceAccount:app-runtime@acme-prod-platform.iam.gserviceaccount.com" \
  --role="roles/secretmanager.secretAccessor"

Point the workload at the intended service account instead of the default one:

gcloud run services update api \
  --region=us-central1 --project=acme-prod-platform \
  --service-account=app-runtime@acme-prod-platform.iam.gserviceaccount.com

Enable the API if it’s off:

gcloud services enable secretmanager.googleapis.com --project=acme-prod-platform

Allow ~1 minute for IAM propagation, then retry.

What to Watch Out For

  • roles/viewer lets you list secret metadata but not read values — you need secretmanager.secretAccessor for the payload.
  • Grant on the individual secret, not the whole project, so one workload can’t read every secret.
  • The (or it may not exist) wording is deliberately ambiguous — it can mean a real permission gap or a wrong project/secret path; verify both.
  • On GKE, the accessor role must be on the identity Workload Identity maps the pod to, not the node service account.
Free download · 368-page PDF

Fixed it? Get 500 GCP with AI & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.