kubevela / catalog

Catalog of community maintained components and traits.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

FluxCD addon should set service account name when possible

jeffguorg opened this issue · comments

Background

FluxCD has supported impersonating into a service account when installing or upgrading a helm release, since 0.16

Kubevela has supported impersonating into a user since 1.4

Problem

By default, helm-controller uses it's own service account to install charts into cluster, which is bound to not only the essential flux-system:sa-helm-controller cluster role, but also a super user cluster-admin.

This lead to a problem that an application may escalate it's own privilege by installing a helm chart.

Proposal

Allow user to set the service account or let helm controller use the annotations set by kubevela mutating webhook

  • If user set the serviceAccountName in parameter, use the parameter
  • If kubevela set the username in annotation and it's a service account in the helm release's namespace, strip the prefix and use the service account name
  • or else it fallbacks to default

So that user can specify a service account, or the platform can restrict the action of helm chart.

Demo Implementation

Talk is cheap, let's see the code. This is a simple modification on fluxcd addon v2.1.1 3e7001c. tested on kubevela 1.5.10

diff --git a/addons/fluxcd/definitions/helm-release-def.cue b/addons/fluxcd/definitions/helm-release-def.cue
index e474fbe..72c8784 100644
--- a/addons/fluxcd/definitions/helm-release-def.cue
+++ b/addons/fluxcd/definitions/helm-release-def.cue
@@ -1,3 +1,4 @@
+import ("strings")
 helm: {
        attributes: {
                workload: type: "autodetects.core.oam.dev"
@@ -140,6 +141,12 @@ template: {
                        if parameter.values != _|_ {
                                values: parameter.values
                        }
+                       if parameter.serviceAccountName != _|_ {
+                               serviceAccountName: parameter.serviceAccountName
+                       }
+                       if parameter.serviceAccountName == _|_ && strings.HasPrefix(_serviceAccountIntermediate.username, _serviceAccountIntermediate.prefix) {
+                               serviceAccountName: strings.TrimPrefix(_serviceAccountIntermediate.username, _serviceAccountIntermediate.prefix)
+                       }
                        install: {
                                remediation: {
                                        retries: parameter.retries
@@ -170,6 +177,11 @@ template: {
                }
        }

+       _serviceAccountIntermediate: {
+               username: context.appAnnotations["app.oam.dev/username"]
+               prefix: "system:serviceaccount:\(context.namespace):"
+       }
+
        parameter: {
                repoType: *"helm" | "git" | "oss" | "oci"
                // +usage=The interval at which to check for repository/bucket and release updates, default to 5m
@@ -208,6 +220,8 @@ template: {
                version: *"*" | string
                // +usage=The namespace for helm chart, optional
                targetNamespace?: string
+               // +usage=The service account used to install or upgrade helm release
+               serviceAccountName?: string
                // +usage=The release name
                releaseName?: string
                // +usage=Retry times when install/upgrade fail.

It can be ported to master and kustomize with almost no effort, but I known little about kustomize

Good catch! ping @Somefive @wangyikewxgm