A browser cannot speak native gRPC in the same way as a Go or Java client. The gRPC-Web protocol adapts calls for browser constraints and commonly carries request metadata in HTTP headers and response metadata in a trailer frame inside the body. That adaptation creates a useful bridge for web applications, but it does not move the authorization decision into the browser or into the protocol adapter.
The first design mistake is treating CORS as authentication. CORS controls which browser origins may read a cross-origin response. It does not prove who sent a request, and it does not stop a server-side client or a script outside the browser. A public CORS policy on a gRPC-Web endpoint can be reasonable if the endpoint still requires a validated bearer token, a session cookie with CSRF protection, or mutual TLS at a trusted proxy. The identity check has to happen before the request reaches service code.
The second mistake is trusting a header because it is familiar. A gateway may add x-user-id, x-tenant-id or an authorization context after validating a token. If the same gateway forwards a client-supplied copy of that header, downstream services may see two values or the attacker's value. Gateways should remove untrusted identity headers, authenticate the request, and inject a new context. Services should reject requests that arrive without the expected gateway identity marker and should use the marker only on a network path that ordinary clients cannot reach.
Method-level authorization still matters after a valid token is established. A token can be valid for the application while the caller lacks permission for a specific service method or resource. Mapping an HTTP path to a gRPC method is convenient, but the policy should use the canonical service and method names and the resource identifiers in the request. Wildcard access such as * is a change to the authorization model, not a harmless convenience for generated clients.
Session cookies need a separate review. gRPC-Web clients often use ordinary POST requests, so browsers may attach cookies automatically. The proxy must apply CSRF defenses to state-changing calls, set SameSite deliberately, and avoid accepting cookies on endpoints that also accept a bearer token unless the precedence rule is clear. If both credentials are accepted, the stronger identity must not be silently replaced by a weaker one from a query parameter or custom header.
The wire format also changes what intermediaries see. Metadata becomes headers, and some trailers appear in the response body. A reverse proxy can terminate TLS, enforce request size limits, attach tracing metadata, and forward the adapted response. It can also break streaming, compress messages incorrectly, or remove CORS response headers. Test these behaviors through the same ingress path used in production. A successful call from a local gRPC client says nothing about a browser call through an identity-aware proxy.
Logging should connect the user identity, the client application, the gRPC method, the resource, and the authorization result without recording access tokens. When a call is denied, distinguish an expired credential, a valid credential with insufficient scope, a policy mismatch, and a malformed request. That difference matters during incident response because each condition points to a different control.
The practical rule is simple: authenticate at the edge, authorize at the service, and verify both through the browser-facing path. gRPC-Web is a compatibility layer. A secure deployment still depends on ordinary HTTP protections, explicit method policy, and an intermediary that knows which identity headers it owns.