feat: As a user, I want to select a Consumer (and its Consumer Group) from a JWT claim in openid-connect on a single route.
- Dominant language
- Lua
- Stars
- 17.1k
- Forks
- 2.9k
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 63
Description
### Description
## Feature Description
Add a `consumer_selector` capability to the `openid-connect` plugin so a single route can select a Consumer (and Consumer Group) from a JWT claim (for example, `iss`) before OIDC validation.
This enables deterministic multi-realm authentication on one route by mapping token claim values to Consumer identities, then applying the selected Consumer Group’s `openid-connect` configuration (realm-specific discovery/JWKS/introspection settings).
## Motivation
Today, Consumer Group plugin configs are applied only after a Consumer is resolved.
Without a pre-auth resolver like `key-auth`, route-level `openid-connect` cannot dynamically switch realms by Consumer Group.
This forces users to:
- duplicate routes per realm, or
- use unsupported workaround patterns with extra auth plugins.
## Proposed Behavior
Add new optional attributes in `openid-connect`:
- `consumer_selector.enabled` (boolean)
- `consumer_selector.claim` (string, default `iss`)
- `consumer_selector.map` (object: `claim_value -> consumer_name`)
- `consumer_selector.strict` (boolean, default `true`)
Request flow with selector enabled:
1. Extract bearer token.
2. Decode JWT payload to read selector claim.
3. Resolve mapped Consumer by `consumer_name`.
4. Attach Consumer to request context.
5. Load selected Consumer Group’s `openid-connect` config.
6. Continue normal OIDC validation and header injection (`X-Userinfo`, etc.) using selected config.
## Compatibility / Risk Notes
- Feature is opt-in (`consumer_selector.enabled=false` by default).
- Existing `openid-connect` behavior is unchanged when selector is not enabled.
- This introduces a new control path and should be reviewed for:
- claim spoofing risks before signature verification,
- config mismatch/fallback behavior,
- interaction with existing plugin execution order.
## Example Config
```json
"openid-connect": {
"client_id": "dummy",
"client_secret": "dummy",
"discovery": "https://idp.example/.well-known/openid-configuration",
"bearer_only": true,
"consumer_selector": {
"enabled": true,
"claim": "iss",
"strict": true,
"map": {
"https://idp.example/realms/realm-a": "realm-a-consumer",
"https://idp.example/realms/realm-b": "realm-b-consumer"
}
}
}
```
If this design direction is acceptable, I can split this into smaller PRs (schema/docs first, runtime behavior second) if preferred.
Contributor guide
Research direction
Start by reading the existing openid-connect plugin schema and runtime authentication flow, including how Consumer Groups are resolved and configured. Define the schema, documentation, and runtime changes needed so an enabled selector maps a JWT claim to a Consumer before validation, while preserving the disabled path and covering spoofing, fallback, and execution-order behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- lua
- Domain
- authentication
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100