# rpc error: code = PermissionDenied desc = caller does not have permission to access resource

- **ID:** `go/grpc-permission-denied`
- **Domain:** go
- **Category:** auth_error
- **Verification:** ai_generated
- **Fix Rate:** 80%

## Root Cause

The authenticated caller passed authentication but failed authorization — the principal lacks the required role/scope for the method or resource. Often the token is valid but issued for a different audience or scope.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| 1.x | active | — | — |

## Workarounds

1. **** (85% success)
   ```
   Log the principal and required scope to confirm the mismatch, and verify the token audience:

p, _ := peer.FromContext(ctx)
log.Printf("denied for peer=%v method=%s", p.Addr, method)
// decode JWT claims: check aud and scope
   ```
2. **** (82% success)
   ```
   Request the correct OAuth scope when minting the token and propagate it through the interceptor:

// ensure scope includes the API's required scope, e.g. "orders.write"
ts := config.TokenSource(ctx, &oauth2.Token{AccessToken: tok})
ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "Bearer "+tok)
   ```

## Dead Ends

- **** — Refreshing a valid token yields another valid token with the same scopes; authorization still fails. (85% fail)
- **** — Authorization decisions are deterministic per principal; retrying never grants a missing permission. (95% fail)
