diff --git a/coderd/database/types.go b/coderd/database/types.go index 188825cea6eb7..2528a30aa3fe8 100644 --- a/coderd/database/types.go +++ b/coderd/database/types.go @@ -214,6 +214,9 @@ func (p AgentIDNamePair) Value() (driver.Value, error) { type UserLinkClaims struct { IDTokenClaims map[string]interface{} `json:"id_token_claims"` UserInfoClaims map[string]interface{} `json:"user_info_claims"` + // MergeClaims are computed in Golang. It is the result of merging + // the IDTokenClaims and UserInfoClaims. UserInfoClaims take precedence. + MergedClaims map[string]interface{} `json:"merged_claims"` } func (a *UserLinkClaims) Scan(src interface{}) error { diff --git a/coderd/userauth.go b/coderd/userauth.go index 7d8e6c2bbc44f..44b8c15a5dba5 100644 --- a/coderd/userauth.go +++ b/coderd/userauth.go @@ -1326,6 +1326,7 @@ func (api *API) userOIDC(rw http.ResponseWriter, r *http.Request) { UserClaims: database.UserLinkClaims{ IDTokenClaims: idtokenClaims, UserInfoClaims: userInfoClaims, + MergedClaims: mergedClaims, }, }).SetInitAuditRequest(func(params *audit.RequestParams) (*audit.Request[database.User], func()) { return audit.InitRequest[database.User](rw, params) diff --git a/enterprise/dbcrypt/dbcrypt_internal_test.go b/enterprise/dbcrypt/dbcrypt_internal_test.go index 10d56b50a074c..3e252496d6a69 100644 --- a/enterprise/dbcrypt/dbcrypt_internal_test.go +++ b/enterprise/dbcrypt/dbcrypt_internal_test.go @@ -64,6 +64,16 @@ func TestUserLinks(t *testing.T) { "number": float64(2), }, }, + MergedClaims: map[string]interface{}{ + "sub": "123", + "groups": []interface{}{ + "foo", "bar", + }, + "number": float64(2), + "struct": map[string]interface{}{ + "number": float64(2), + }, + }, } updated, err := crypt.UpdateUserLink(ctx, database.UpdateUserLinkParams{