From 1e12d49d743445ab2d4c7f865b261460836129e7 Mon Sep 17 00:00:00 2001 From: gillcaleb Date: Thu, 17 Aug 2023 09:05:50 -0400 Subject: [PATCH] Add optional long lived SA token (#923) --------- Co-authored-by: Caleb Gill --- templates/_helpers.tpl | 11 +++ templates/server-serviceaccount-secret.yaml | 21 ++++++ test/unit/server-serviceaccount-secret.bats | 77 +++++++++++++++++++++ values.schema.json | 3 + values.yaml | 6 ++ 5 files changed, 118 insertions(+) create mode 100644 templates/server-serviceaccount-secret.yaml create mode 100644 test/unit/server-serviceaccount-secret.bats diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl index fc068388a..d76971c2f 100644 --- a/templates/_helpers.tpl +++ b/templates/_helpers.tpl @@ -82,6 +82,17 @@ Compute if the server serviceaccount is enabled. (eq (.Values.global.enabled | toString) "true"))) -}} {{- end -}} +{{/* +Compute if the server serviceaccount should have a token created and mounted to the serviceaccount. +*/}} +{{- define "vault.serverServiceAccountSecretCreationEnabled" -}} +{{- $_ := set . "serverServiceAccountSecretCreationEnabled" + (and + (eq (.Values.server.serviceAccount.create | toString) "true") + (eq (.Values.server.serviceAccount.createSecret | toString) "true")) -}} +{{- end -}} + + {{/* Compute if the server auth delegator serviceaccount is enabled. */}} diff --git a/templates/server-serviceaccount-secret.yaml b/templates/server-serviceaccount-secret.yaml new file mode 100644 index 000000000..74d70f900 --- /dev/null +++ b/templates/server-serviceaccount-secret.yaml @@ -0,0 +1,21 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.serverServiceAccountSecretCreationEnabled" . }} +{{- if .serverServiceAccountSecretCreationEnabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "vault.serviceAccount.name" . }}-token + namespace: {{ include "vault.namespace" . }} + annotations: + kubernetes.io/service-account.name: {{ template "vault.serviceAccount.name" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +type: kubernetes.io/service-account-token +{{ end }} \ No newline at end of file diff --git a/test/unit/server-serviceaccount-secret.bats b/test/unit/server-serviceaccount-secret.bats new file mode 100644 index 000000000..2cfe33395 --- /dev/null +++ b/test/unit/server-serviceaccount-secret.bats @@ -0,0 +1,77 @@ +#!/usr/bin/env bats + +load _helpers + +@test "server/ServiceAccountSecret: verify service account name match" { + cd `chart_dir` + + local actual=$( (helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.dev.enabled=true' \ + --set 'server.serviceAccount.create=false' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + + local actual=$(helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.dev.enabled=true' \ + --set 'server.serviceAccount.name=user-defined-ksa' \ + --set 'server.serviceAccount.createSecret=true' \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "user-defined-ksa-token" ] + + local actual=$(helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.dev.enabled=true' \ + --set 'server.serviceAccount.createSecret=true' \ + . | tee /dev/stderr | + yq -r '.metadata.name' | tee /dev/stderr) + [ "${actual}" = "release-name-vault-token" ] + +} + +@test "server/ServiceAccountSecret: annotation mapping to service account" { + cd `chart_dir` + + local actual=$(helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.dev.enabled=true' \ + --set 'server.serviceAccount.name=user-defined-ksa' \ + --set 'server.serviceAccount.createSecret=true' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations["kubernetes.io/service-account.name"]' | tee /dev/stderr) + [ "${actual}" = "user-defined-ksa" ] + + local actual=$(helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.dev.enabled=true' \ + --set 'server.serviceAccount.createSecret=true' \ + . | tee /dev/stderr | + yq -r '.metadata.annotations["kubernetes.io/service-account.name"]' | tee /dev/stderr) + [ "${actual}" = "release-name-vault" ] + +} + +@test "server/ServiceAccountSecret: namespace" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.serviceAccount.create=true' \ + --set 'server.serviceAccount.createSecret=true' \ + --namespace foo \ + . | tee /dev/stderr | + yq -r '.metadata.namespace' | tee /dev/stderr) + [ "${actual}" = "foo" ] + local actual=$(helm template \ + --show-only templates/server-serviceaccount-secret.yaml \ + --set 'server.serviceAccount.create=true' \ + --set 'server.serviceAccount.createSecret=true' \ + --set 'global.namespace=bar' \ + --namespace foo \ + . | tee /dev/stderr | + yq -r '.metadata.namespace' | tee /dev/stderr) + [ "${actual}" = "bar" ] +} + diff --git a/values.schema.json b/values.schema.json index 2aefb06d0..f08a98e16 100644 --- a/values.schema.json +++ b/values.schema.json @@ -985,6 +985,9 @@ "extraLabels": { "type": "object" }, + "createSecret": { + "type": "boolean" + }, "name": { "type": "string" }, diff --git a/values.yaml b/values.yaml index 8538cd61c..f70869a81 100644 --- a/values.yaml +++ b/values.yaml @@ -917,6 +917,12 @@ server: # The name of the service account to use. # If not set and create is true, a name is generated using the fullname template name: "" + # Create a Secret API object to store a non-expiring token for the service account. + # Prior to v1.24.0, Kubernetes used to generate this secret for each service account by default. + # Kubernetes now recommends using short-lived tokens from the TokenRequest API or projected volumes instead if possible. + # For more details, see https://kubernetes.io/docs/concepts/configuration/secret/#service-account-token-secrets + # serviceAccount.create must be equal to 'true' in order to use this feature. + createSecret: false # Extra annotations for the serviceAccount definition. This can either be # YAML or a YAML-formatted multi-line templated string map of the # annotations to apply to the serviceAccount.