envoyproxy / envoyproxy/gateway

OIDC: make the forwarded access token header configurable

Open
#9,622 1 comment 0 reactions 0 assignees View on GitHub
area/api area/envoy kind/feature stale
Dominant language
Go
Stars
3k
Forks
864
Avg merge
2d 2h
Merged PRs (30d)
140

Description

The below was generated using AI and I'll come back to clean up the description.

*Description*:

## What

Allow the OIDC access token to be forwarded to a configurable upstream header, the same way `forwardIDToken.header` works today.

## Why

Follow-up to #7343. That issue delivered configurable forwarding for the **ID token** (#9367), but the **access token** is still hardwired to `Authorization: Bearer `:

```go
// api/v1alpha1/oidc_types.go
// ForwardAccessToken indicates whether the Envoy should forward the access token
// via the Authorization header Bearer scheme to the upstream.
ForwardAccessToken *bool `json:"forwardAccessToken,omitempty"`
```
Forwarding both tokens at once already works (access token on Authorization, ID token on a custom header), so this is a symmetry/flexibility gap rather than a blocked use case. It matters when the upstream already uses Authorization for its own scheme, or when a backend expects the access token on a specific vendor header.

Originally raised by @tvandinther in https://github.com/envoyproxy/gateway/issues/7343#issuecomment-3511105788:

> It would be particularly useful to be able to forward both the ID token and access token at the same time to 2 different and configurable headers. Even if we could opt to forward the ID token, in the proposed changes we would then lose the access token. They both have unique use cases which warrant having them both forwarded.

Blocked on upstream Envoy

Envoy's oauth2 filter exposes the two tokens asymmetrically:
```
// api/envoy/extensions/filters/http/oauth2/v3/oauth.proto
bool forward_bearer_token = 7; // access token — no header field
OAuth2TokenForwarding forward_id_token = 31; // ID token — { string header = 1; }
```
OAuth2TokenForwarding already exists and is exactly the right shape. The upstream change is to add a parallel field at the next free number:
```
// Forward the OAuth2 access token to the upstream on a configurable header.
// Mutually exclusive with forward_bearer_token.
OAuth2TokenForwarding forward_access_token = 32;
```
plus the corresponding handling in source/extensions/filters/http/oauth2/filter.cc, matching how forward_id_token is applied. envoyproxy/envoy#45268 is the precedent to follow.

Until that lands and EG picks it up via a go-control-plane / Envoy image bump, there is no xDS field to translate into. This cannot be implemented in EG alone.

Proposed Envoy Gateway API

forwardAccessToken is already released as *bool, so it can't be retyped without breaking users. Two options, to be agreed before implementation:

Option A — sibling field (preferred):
oidc:
forwardAccessTokenTo:
header: X-Access-Token
Keeps forwardAccessToken: true working as shorthand for header: Authorization; the two are mutually exclusive via CEL. Symmetric with forwardIDToken, though the naming is a bit awkward.

Option B — reuse the existing field name with a union type. Cleaner surface, but needs care to stay backward compatible with the bool.

Either way the existing CEL rule on OIDCConfig (which keys on forwardAccessToken being a bool) needs reworking to cover the new combinations, including rejecting the same header for both tokens.

Implementation sketch (once unblocked)

Mirrors the ID token path almost exactly:

- api/v1alpha1/oidc_types.go — new field + CEL validation
- internal/ir/xds.go — IR field alongside ForwardIDTokenHeader
- internal/gatewayapi/securitypolicy.go — translation
- internal/xds/translator/oidc.go — set ForwardAccessToken on the oauth2 config, following the ForwardIdToken block
- Tests: CEL, gatewayapi testdata, xds testdata, e2e
- Docs + release note fragment

Small, low-risk PR — the entire cost is upstream.

/kind feature

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with Envoy's oauth.proto and source/extensions/filters/http/oauth2/filter.cc, following envoyproxy/envoy#45268; this issue is blocked until the upstream configurable access-token field lands. Once available, trace the analogous ForwardIDToken path through api/v1alpha1/oidc_types.go, internal/ir/xds.go, internal/gatewayapi/securitypolicy.go, and internal/xds/translator/oidc.go, then run the listed CEL, gatewayapi, xDS, and e2e tests.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, authentication, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.