Summary
The go-processor (AuthProxy ext_proc) currently uses a static TARGET_SCOPES environment variable for all outbound token exchanges. This means every exchanged token gets the same set of scopes regardless of what scopes the original user token contained.
For scope-based access control to work (e.g., Alice with public access vs Bob with privileged access), the go-processor must forward the original token's scopes through the token exchange, not use a fixed set.
Current Behavior
TARGET_SCOPES is set in the authbridge-config ConfigMap (e.g., "openid github-tool-aud github-full-access")
- When any user's request reaches the agent, AuthBridge exchanges the token using the static
TARGET_SCOPES
- The exchanged token always contains
github-full-access, even if the original user (e.g., Alice) did not have that scope
- The downstream tool always sees
github-full-access and uses the privileged PAT for all users
Expected Behavior
The go-processor should extract the scope claim from the incoming JWT (subject token) and intersect it with TARGET_SCOPES before making the token exchange request:
- If the incoming token has
scope: "openid email profile" and TARGET_SCOPES is "openid github-tool-aud github-full-access", the exchange should request scope=openid github-tool-aud (intersection, plus required scopes like github-tool-aud)
- If the incoming token has
scope: "openid email profile github-full-access", the exchange should request scope=openid github-tool-aud github-full-access
This preserves per-user scope differentiation through the exchange.
Proposed Implementation
Add a new configuration option to go-processor:
SCOPE_FORWARDING (env var, default: "disabled")
"disabled" — current behavior: use static TARGET_SCOPES for all exchanges
"intersect" — extract scopes from subject token, intersect with TARGET_SCOPES
"forward" — extract scopes from subject token, merge with TARGET_SCOPES
Implementation in handleOutbound():
- Parse the incoming JWT's
scope claim (decode without full validation — the token was already validated inbound)
- Split into a set of scopes
- Apply the selected strategy (
intersect or forward) with TARGET_SCOPES
- Pass the resulting scope set to
exchangeToken()
Use Case
The GitHub Issue Agent demo Step 10 shows two users:
- Alice gets a token without
github-full-access — should result in PUBLIC_ACCESS_PAT at the tool
- Bob gets a token with
github-full-access — should result in PRIVILEGED_ACCESS_PAT at the tool
Without scope forwarding, both users get github-full-access in the exchanged token because TARGET_SCOPES is static.
Affected Files
AuthBridge/AuthProxy/go-processor/main.go — handleOutbound() and loadConfig()
AuthBridge/demos/github-issue/k8s/configmaps.yaml — add SCOPE_FORWARDING: "intersect" to authbridge-config
Summary
The go-processor (AuthProxy ext_proc) currently uses a static
TARGET_SCOPESenvironment variable for all outbound token exchanges. This means every exchanged token gets the same set of scopes regardless of what scopes the original user token contained.For scope-based access control to work (e.g., Alice with public access vs Bob with privileged access), the go-processor must forward the original token's scopes through the token exchange, not use a fixed set.
Current Behavior
TARGET_SCOPESis set in theauthbridge-configConfigMap (e.g.,"openid github-tool-aud github-full-access")TARGET_SCOPESgithub-full-access, even if the original user (e.g., Alice) did not have that scopegithub-full-accessand uses the privileged PAT for all usersExpected Behavior
The go-processor should extract the
scopeclaim from the incoming JWT (subject token) and intersect it withTARGET_SCOPESbefore making the token exchange request:scope: "openid email profile"andTARGET_SCOPESis"openid github-tool-aud github-full-access", the exchange should requestscope=openid github-tool-aud(intersection, plus required scopes likegithub-tool-aud)scope: "openid email profile github-full-access", the exchange should requestscope=openid github-tool-aud github-full-accessThis preserves per-user scope differentiation through the exchange.
Proposed Implementation
Add a new configuration option to go-processor:
SCOPE_FORWARDING(env var, default:"disabled")"disabled"— current behavior: use staticTARGET_SCOPESfor all exchanges"intersect"— extract scopes from subject token, intersect withTARGET_SCOPES"forward"— extract scopes from subject token, merge withTARGET_SCOPESImplementation in
handleOutbound():scopeclaim (decode without full validation — the token was already validated inbound)intersectorforward) withTARGET_SCOPESexchangeToken()Use Case
The GitHub Issue Agent demo Step 10 shows two users:
github-full-access— should result inPUBLIC_ACCESS_PATat the toolgithub-full-access— should result inPRIVILEGED_ACCESS_PATat the toolWithout scope forwarding, both users get
github-full-accessin the exchanged token becauseTARGET_SCOPESis static.Affected Files
AuthBridge/AuthProxy/go-processor/main.go—handleOutbound()andloadConfig()AuthBridge/demos/github-issue/k8s/configmaps.yaml— addSCOPE_FORWARDING: "intersect"toauthbridge-config