From 7dc12ddfd1d79d16875f0f4abfbd5d2b2db2c6ff Mon Sep 17 00:00:00 2001 From: Miguel Crespo <162333021+miguel-crespo-fdc@users.noreply.github.com> Date: Fri, 17 May 2024 10:32:48 +0100 Subject: [PATCH] feat: default role for dex support (#1559) Kuberpult changes to support Dex. We created a configurable default user that is selected if it is enabled and dex does not return any roles associated with a user after authentication. This is done as we haven't retrieved the groups from google thorugh dex yet. --------- Co-authored-by: Oliver Breitwieser Co-authored-by: Sven Urbanski --- charts/kuberpult/templates/cd-service.yaml | 4 +++- charts/kuberpult/templates/frontend-service.yaml | 3 ++- charts/kuberpult/values.yaml | 3 +++ pkg/auth/auth.go | 11 ++++++++++- pkg/auth/dex.go | 2 +- services/cd-service/pkg/cmd/server.go | 3 ++- 6 files changed, 21 insertions(+), 5 deletions(-) diff --git a/charts/kuberpult/templates/cd-service.yaml b/charts/kuberpult/templates/cd-service.yaml index c47e719b9..63b3bf717 100644 --- a/charts/kuberpult/templates/cd-service.yaml +++ b/charts/kuberpult/templates/cd-service.yaml @@ -217,6 +217,8 @@ spec: {{- if .Values.auth.dexAuth.enabled }} - name: KUBERPULT_DEX_RBAC_POLICY_PATH value: /kuberpult-rbac/policy.csv + - name: KUBERPULT_DEX_DEFAULT_ROLE_ENABLED + value: "{{ .Values.auth.dexAuth.defaultRoleEnabled }}" {{- end }} - name: KUBERPULT_AZURE_ENABLE_AUTH value: "{{ .Values.auth.azureAuth.enabled }}" @@ -282,7 +284,7 @@ spec: {{- if .Values.auth.dexAuth.enabled }} - name: kuberpult-rbac mountPath: /kuberpult-rbac -{{- end }} +{{- end }} {{- if .Values.dogstatsdMetrics.enabled }} - name: dsdsocket mountPath: {{ .Values.dogstatsdMetrics.hostSocketPath }} diff --git a/charts/kuberpult/templates/frontend-service.yaml b/charts/kuberpult/templates/frontend-service.yaml index e0db3073d..109737856 100644 --- a/charts/kuberpult/templates/frontend-service.yaml +++ b/charts/kuberpult/templates/frontend-service.yaml @@ -148,7 +148,8 @@ spec: - name: KUBERPULT_DEX_CLIENT_ID value: "{{ .Values.auth.dexAuth.clientId }}" - name: KUBERPULT_DEX_CLIENT_SECRET - value: "{{ .Values.auth.dexAuth.clientSecret }}" + value: + {{- toYaml .Values.auth.dexAuth.clientSecret | nindent 12 }} - name: KUBERPULT_DEX_BASE_URL value: "{{ .Values.auth.dexAuth.baseURL }}" - name: KUBERPULT_DEX_SCOPES diff --git a/charts/kuberpult/values.yaml b/charts/kuberpult/values.yaml index cb66ceaa8..f4155c7d4 100644 --- a/charts/kuberpult/values.yaml +++ b/charts/kuberpult/values.yaml @@ -290,6 +290,9 @@ auth: enabled: false # Indicates if dex is to be installed. If you want to use your own Dex instance do not enable this flag. installDex: false + # If kuberpult cannot find a role in the dex response, it will use the role "default". + # This is only recommended for when you want the simplest possible setup, or for testing purposes. + defaultRoleEnabled: false # If using e.g. GCP IAP cluster internal communication to Dex is necessary as otherwise its endpoints cannot be accessed by the frontend service # If enabled, kuberpult communicates with dex over http, not https useClusterInternalCommunicationToDex: false diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index b62d80883..21504e0da 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -86,7 +86,8 @@ type GrpcContextReader interface { } type DexGrpcContextReader struct { - DexEnabled bool + DexEnabled bool + DexDefaultRoleEnabled bool } type DummyGrpcContextReader struct { @@ -143,7 +144,15 @@ func (x *DexGrpcContextReader) ReadUserFromGrpcContext(ctx context.Context) (*Us // RBAC Role of the user. only mandatory if DEX is enabled. if x.DexEnabled { rolesInHeader := md.Get(HeaderUserRole) + if len(rolesInHeader) == 0 { + if x.DexDefaultRoleEnabled { + u.DexAuthContext = &DexAuthContext{ + Role: "default", + } + logger.FromContext(ctx).Warn("role undefined but dex is enabled. Default user role enabled. Proceeding with default role.") + return u, nil + } return nil, grpc.AuthError(ctx, fmt.Errorf("extract: role undefined but dex is enabled")) } userRole, err := Decode64(rolesInHeader[0]) diff --git a/pkg/auth/dex.go b/pkg/auth/dex.go index 6c19fea9f..4e46731a9 100644 --- a/pkg/auth/dex.go +++ b/pkg/auth/dex.go @@ -213,7 +213,7 @@ func (a *DexAppClient) handleCallback(w http.ResponseWriter, r *http.Request) { idToken, err := ValidateOIDCToken(ctx, a.IssuerURL, idTokenRAW, a.ClientID, a.UseClusterInternalCommunication) if err != nil { - http.Error(w, "failed to verify the token", http.StatusInternalServerError) + http.Error(w, fmt.Sprintf("failed to verify the token: %v", err), http.StatusInternalServerError) return } diff --git a/services/cd-service/pkg/cmd/server.go b/services/cd-service/pkg/cmd/server.go index 0e305fc1f..c1aae9b69 100755 --- a/services/cd-service/pkg/cmd/server.go +++ b/services/cd-service/pkg/cmd/server.go @@ -88,6 +88,7 @@ type Config struct { DbUserPassword string `default:"" split_words:"true"` DbAuthProxyPort string `default:"5432" split_words:"true"` DbMigrationsLocation string `default:"" split_words:"true"` + DexDefaultRoleEnabled bool `default:"false" split_words:"true"` DbWriteEslTableOnly bool `default:"false" split_words:"true"` } @@ -136,7 +137,7 @@ func RunServer() { } reader = &auth.DummyGrpcContextReader{Role: c.DexMockRole} } else { - reader = &auth.DexGrpcContextReader{DexEnabled: c.DexEnabled} + reader = &auth.DexGrpcContextReader{DexEnabled: c.DexEnabled, DexDefaultRoleEnabled: c.DexDefaultRoleEnabled} } dexRbacPolicy, err := auth.ReadRbacPolicy(c.DexEnabled, c.DexRbacPolicyPath) if err != nil {