From 43807ae12a82f86be755a8af5415f58b5e0df443 Mon Sep 17 00:00:00 2001 From: Jan Eitzinger Date: Wed, 1 Apr 2026 13:46:21 +0200 Subject: [PATCH] feat: Also submit projects array via oidc token Entire-Checkpoint: 2064482d97e1 --- internal/auth/oidc.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/auth/oidc.go b/internal/auth/oidc.go index 2786c09a..934c8542 100644 --- a/internal/auth/oidc.go +++ b/internal/auth/oidc.go @@ -162,7 +162,8 @@ func (oa *OIDC) OAuth2Callback(rw http.ResponseWriter, r *http.Request) { return } - projects := make([]string, 0) + // projects is populated below from ID token claims + var projects []string // Extract profile claims from userinfo (username, name) var userInfoClaims struct { @@ -189,6 +190,8 @@ func (oa *OIDC) OAuth2Callback(rw http.ResponseWriter, r *http.Request) { ResourceAccess map[string]struct { Roles []string `json:"roles"` } `json:"resource_access"` + // Custom multi-valued user attribute mapped via a Keycloak User Attribute mapper + Projects []string `json:"projects"` } if err := idToken.Claims(&idTokenClaims); err != nil { cclog.Errorf("failed to extract ID token claims: %s", err.Error()) @@ -199,6 +202,12 @@ func (oa *OIDC) OAuth2Callback(rw http.ResponseWriter, r *http.Request) { cclog.Debugf("OIDC userinfo claims: username=%q name=%q", userInfoClaims.Username, userInfoClaims.Name) cclog.Debugf("OIDC ID token realm_access roles: %v", idTokenClaims.RealmAccess.Roles) cclog.Debugf("OIDC ID token resource_access: %v", idTokenClaims.ResourceAccess) + cclog.Debugf("OIDC ID token projects: %v", idTokenClaims.Projects) + + projects = idTokenClaims.Projects + if projects == nil { + projects = []string{} + } // Prefer username from userInfo; fall back to ID token claim username := userInfoClaims.Username