GoogleCloudPlatform / GoogleCloudPlatform/cloud-run-mesh

Feature Request: Preserve `Authorization` header when injecting IAM credentials on Cloud Run mesh

Open
#61 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
35
Forks
8
PR merge metrics
No merged PRs in 30d

Description

## Feature Request: Preserve `Authorization` header when injecting IAM credentials on Cloud Run mesh

### Summary

When Cloud Service Mesh is enabled on Cloud Run, the Envoy sidecar overwrites the outbound `Authorization` header with a Google-signed OIDC token to satisfy the destination service's IAM. This silently drops any user JWT that the calling service is forwarding, breaking service chains that propagate user identity across hops.

Apigee and the open-source `runsd` tool already solve this correctly by splitting the two concerns across two headers: the user JWT stays in `Authorization`, and the IAM credential is injected into `X-Serverless-Authorization` — a header that Cloud Run's edge honours equivalently for IAM verification. The Cloud Run mesh should do the same.

### Current behaviour

1. Service A receives a request carrying a user JWT in `Authorization: Bearer `.
2. Service A calls Service B over the mesh.
3. The Envoy sidecar intercepts the outbound request and replaces `Authorization` with a Google SA OIDC token.
4. Service B receives `Authorization: Bearer ` and never sees the user JWT.

If Service B validates the issuer of the `Authorization` token (e.g. using `AllowedIssuers`), it rejects the call with 401 because the SA token's issuer is not the expected user identity provider. Before issuer validation is added, the problem exists silently — user identity is lost downstream with no error surfaced.

### Expected behaviour

The Envoy sidecar should inject the IAM credential into `X-Serverless-Authorization` and leave `Authorization` untouched, preserving any user JWT for the destination service to validate. This matches the documented behaviour of:

- **Apigee**: injects IAM token into `X-Serverless-Authorization`, forwards user JWT in `Authorization`.
- **runsd** (`zucchinho` fork): same split-header behaviour.
- **Cloud Run documentation**: confirms that `X-Serverless-Authorization` is a supported alternative to `Authorization` for IAM verification at the Cloud Run edge.

### Why this matters

Forwarding a user JWT through a chain of internal service calls is a standard pattern in any API that acts on behalf of an authenticated user. Making the mesh incompatible with this pattern means that any service chain involving user context cannot safely adopt Cloud Run mesh without significant application-layer workarounds (custom headers, re-issued identity claims, etc.).

This is not an edge case — it is a fundamental requirement for production mesh adoption in multi-service architectures.

### Workarounds (all have significant drawbacks)

- Carry the user JWT in a custom header (e.g. `X-User-Authorization`) and update both sides of every service pair — requires coordinated changes across all services and creates a bespoke internal contract.
- Pass user identity as structured claims in custom headers and trust them only from authenticated mesh callers — loses cryptographic verification of the user token downstream.
- Bypass the mesh for calls that carry user JWTs — undermines the purpose of the mesh.

None of these are acceptable as permanent architectural decisions.

### Requested change

Expose a configuration option in the Cloud Run mesh / Traffic Director that causes the Envoy sidecar to inject the IAM OIDC token into `X-Serverless-Authorization` instead of (or in addition to) `Authorization`, leaving any pre-existing `Authorization` header intact.

If a global configuration option is not feasible, a per-HTTP-route or per-service annotation would be acceptable.

### Environment

- Cloud Run (gen2 execution environment)
- Cloud Service Mesh / Traffic Director (`launch_stage = BETA`)
- Direct VPC egress, `private-ranges-only`
- Mesh configured via serverless NEG backends and HTTP routes

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the Cloud Run mesh and Traffic Director configuration described in the issue, then trace how the Envoy sidecar currently handles outbound Authorization headers. The work is complete when a supported global, route-level, or service-level configuration preserves Authorization and places the IAM credential in X-Serverless-Authorization, with behavior verified for both headers.

Written by the indexing model from the issue text.

Assessment

Tech stack
google-cloud
Domain
cloud, networking
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.