{"record":{"id":"2065fa2ed1460801","repo":"grpc/grpc-go","slug":"unable-to-transfer-oauthaccess-perrpccredentials","errorCode":null,"errorMessage":"unable to transfer oauthAccess PerRPCCredentials: %v","messagePattern":"unable to transfer oauthAccess PerRPCCredentials: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"credentials/oauth/oauth.go","lineNumber":133,"sourceCode":"\treturn true\n}\n\n// oauthAccess supplies PerRPCCredentials from a given token.\ntype oauthAccess struct {\n\ttoken oauth2.Token\n}\n\n// NewOauthAccess constructs the PerRPCCredentials using a given token.\n//\n// Deprecated: use oauth.TokenSource instead.\nfunc NewOauthAccess(token *oauth2.Token) credentials.PerRPCCredentials {\n\treturn oauthAccess{token: *token}\n}\n\nfunc (oa oauthAccess) GetRequestMetadata(ctx context.Context, _ ...string) (map[string]string, error) {\n\tri, _ := credentials.RequestInfoFromContext(ctx)\n\tif err := credentials.CheckSecurityLevel(ri.AuthInfo, credentials.PrivacyAndIntegrity); err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to transfer oauthAccess PerRPCCredentials: %v\", err)\n\t}\n\treturn map[string]string{\n\t\t\"authorization\": oa.token.Type() + \" \" + oa.token.AccessToken,\n\t}, nil\n}\n\nfunc (oa oauthAccess) RequireTransportSecurity() bool {\n\treturn true\n}\n\n// NewComputeEngine constructs the PerRPCCredentials that fetches access tokens from\n// Google Compute Engine (GCE)'s metadata server. It is only valid to use this\n// if your program is running on a GCE instance.\n// TODO(dsymonds): Deprecate and remove this.\nfunc NewComputeEngine() credentials.PerRPCCredentials {\n\treturn TokenSource{google.ComputeTokenSource(\"\")}\n}\n","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/credentials/oauth/oauth.go#L115-L151","documentation":"Returned by oauthAccess.GetRequestMetadata when CheckSecurityLevel finds the transport below PrivacyAndIntegrity. oauthAccess (the deprecated NewOauthAccess constructor) attaches a raw OAuth2 token, which gRPC will not send over an insecure channel. The %v is the security-level error.","triggerScenarios":"Using the deprecated oauth.NewOauthAccess(token) and dialing with insecure.NewCredentials(); a bundle downgrade that drops the transport below PrivacyAndIntegrity.","commonSituations":"Legacy code still on NewOauthAccess (deprecated in favor of oauth.TokenSource) combined with a plaintext dev channel.","solutions":["Dial with credentials.NewTLS(&tls.Config{}).","Migrate from the deprecated oauth.NewOauthAccess to oauth.TokenSource{ts} (the deprecation note in the source recommends this).","Use a self-signed cert for local testing rather than insecure.NewCredentials()."],"exampleFix":"// before\ncreds := oauth.NewOauthAccess(token)\nconn, _ := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithPerRPCCredentials(creds))\n// after\nts := oauth2.StaticTokenSource(token)\nconn, _ := grpc.Dial(addr, grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: ts}))","handlingStrategy":"validation","validationCode":"// Migrate off the deprecated NewOauthAccess and use TLS:\nts := oauth2.StaticTokenSource(token)\nconn, err := grpc.Dial(addr,\n    grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),\n    grpc.WithPerRPCCredentials(oauth.TokenSource{TokenSource: ts}),\n)","typeGuard":null,"tryCatchPattern":"if status.Code(err) == codes.Unauthenticated && strings.Contains(err.Error(), \"oauthAccess PerRPCCredentials\") {\n    log.Fatal(\"oauthAccess requires TLS; also consider migrating to oauth.TokenSource\")\n}","preventionTips":["Migrate from deprecated oauth.NewOauthAccess to oauth.TokenSource.","Always use TLS transport with OAuth token credentials.","Add a CI rule flagging NewOauthAccess usage."],"tags":["grpc","oauth","tls","security","deprecated","credentials"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}