Summary
Enabling token exchange on a NebariApp configures Keycloak so that every other NebariApp client in the same realm can exchange its access token for the target client's audience. There is no per-peer allowlist, namespace boundary, mutual consent, or administrator approval.
Affected code
api/v1/nebariapp_types.go (L291-297, L304-306) - the field documents that enabling it "creates policies allowing all other NebariApp clients in the same realm to exchange tokens for this client's audience."
internal/controller/reconcilers/auth/reconciler.go - reconcileTokenExchange (L536-597) lists NebariApps cluster-wide (L541), reads each peer's OIDC Secret for its client ID (L568-585), and passes all peer client IDs to ConfigureTokenExchange (L596). The only per-peer filters are: skip self (L551), skip auth-disabled peers (L556), skip non-keycloak peers (L563).
internal/controller/reconcilers/auth/providers/keycloak.go - ConfigureTokenExchange (L308-458) creates one client policy per peer (L384-417) and links them all to the token-exchange permission (L425-455).
Impact
Any newly created NebariApp client automatically becomes an authorized token-exchange peer of every target that enabled the feature, regardless of namespace or trust level. A target cannot restrict which applications may exchange for its audience.
Remediation
- Require an explicit allowlist of peer client IDs or
NebariApp references.
- Require target and peer consent, or administrator approval.
- Support namespace and group policy, and minimize exchanged claims, lifetime, and scopes.
- Reject unknown or deleted peers automatically, and audit every exchange and configuration change.
Acceptance criteria
- Token exchange permits only approved peers.
- Enabling the feature does not grant exchange rights to unrelated applications.
References
- CWE-863 (Incorrect Authorization)
Line numbers reference commit 4ad2c10.
Summary
Enabling token exchange on a
NebariAppconfigures Keycloak so that every otherNebariAppclient in the same realm can exchange its access token for the target client's audience. There is no per-peer allowlist, namespace boundary, mutual consent, or administrator approval.Affected code
api/v1/nebariapp_types.go(L291-297, L304-306) - the field documents that enabling it "creates policies allowing all other NebariApp clients in the same realm to exchange tokens for this client's audience."internal/controller/reconcilers/auth/reconciler.go-reconcileTokenExchange(L536-597) listsNebariApps cluster-wide (L541), reads each peer's OIDC Secret for its client ID (L568-585), and passes all peer client IDs toConfigureTokenExchange(L596). The only per-peer filters are: skip self (L551), skip auth-disabled peers (L556), skip non-keycloak peers (L563).internal/controller/reconcilers/auth/providers/keycloak.go-ConfigureTokenExchange(L308-458) creates one client policy per peer (L384-417) and links them all to the token-exchange permission (L425-455).Impact
Any newly created
NebariAppclient automatically becomes an authorized token-exchange peer of every target that enabled the feature, regardless of namespace or trust level. A target cannot restrict which applications may exchange for its audience.Remediation
NebariAppreferences.Acceptance criteria
References
Line numbers reference commit
4ad2c10.