## TL;DR
`secretmanager.versions.access` denied means the service account lacks the Secret Manager Secret Accessor role on that secret. Add the IAM binding (secret level is tightest), wait a minute for propagation, and the read succeeds. This is IAM, not a code problem.

## Error
```text
gcp secret manager: permission secretmanager.versions.access denied
```

## Steps
1. Identify the caller: check which service account the workload uses (GCE metadata, workload identity, or the key file in use). Expected: a concrete service account email, not a guess.
2. Inspect current bindings: run `gcloud secrets get-iam-policy` on the secret. Expected: you see whether the service account is present and at what level.
3. Grant the role at secret level: run `gcloud secrets add-iam-policy-binding` with `--member` set to the service account and `--role roles/secretmanager.secretAccessor`. Expected: the binding appears in the policy.
4. Wait 60 to 120 seconds for IAM propagation, then retry `gcloud secrets versions access latest`. Expected: the secret payload returns instead of a 403.
5. If it still fails, check for a deny policy or organization constraint blocking the grant. Expected: no deny rule overrides your allow.

## When to use
- Secret Manager reads fail with `secretmanager.versions.access` denied
- A workload works locally with your user credentials but fails with its service account
- After moving a secret to a new project

## When not to use
- Secret not found errors (wrong name or project)
- The Secret Manager API is not enabled (different error)

## Tool compatibility
- Google Cloud Secret Manager, `gcloud secrets` IAM commands; IAM propagation behavior

## Variant phrasings
### 403 accessing gcp secret from cloud run
The Cloud Run service account needs the Secret Accessor role on each secret it reads; grant it at secret level and redeploy.

### secretmanager permission denied for service account
Confirm the exact service account email first; grants to the wrong identity are the most common miss.

## Why it happens
GCP evaluates Secret Manager access per secret version read, and the default posture grants nothing. Workloads authenticate as their service account, which rarely matches the developer's personal IAM, so the binding that works for you locally does not exist for the workload.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_xh2fsd55G9LJ4zL8F67hDQ
