catalog
catalog copied to clipboard
FluxCD addon should set service account name when possible
Background
FluxCD has supported impersonating into a service account when installing or upgrading a helm release, since 0.16
- https://github.com/fluxcd/helm-controller/blob/main/CHANGELOG.md#0160
- https://github.com/fluxcd/helm-controller/pull/406
Kubevela has supported impersonating into a user since 1.4
- https://github.com/kubevela/kubevela/pull/3713
- https://github.com/kubevela/kubevela/pull/3434
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 3e7001cb55ff1897a7a7d6439dc3569a01db7222. 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