Make the external server's downstream RBAC subject configurable (#899)
Replace the hardcoded `User: spire-root` subject with an `externalServerSubject` block (`kind`/`name`/`namespace`) so the downstream RBAC can bind to a User, Group, or ServiceAccount. Defaults preserve the previous behavior. Signed-off-by: sabsari <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c727e4e6b5
commit
ecf6324d67
@@ -88,6 +88,9 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
|
|||||||
| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
|
| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
|
||||||
| `kind` | Define SPIRE server deployment type. Can be statefulset/deployment. Defaults to statefulset if not set. This feature is experimental. | `statefulset` |
|
| `kind` | Define SPIRE server deployment type. Can be statefulset/deployment. Defaults to statefulset if not set. This feature is experimental. | `statefulset` |
|
||||||
| `externalServer` | Deploy only the bundle ConfigMap, RBAC rules, and identity documents but not the server. Use in a nested setup where the server is external. | `false` |
|
| `externalServer` | Deploy only the bundle ConfigMap, RBAC rules, and identity documents but not the server. Use in a nested setup where the server is external. | `false` |
|
||||||
|
| `externalServerSubject.kind` | RBAC subject kind the external (nested) server's downstream bindings are granted to. One of "User" (client-certificate identity, the historical default), "Group", or "ServiceAccount" (e.g. for a static-token kubeconfig). Only used when externalServer is true. | `User` |
|
||||||
|
| `externalServerSubject.name` | Name of the subject. For kind "User" it must match the CN of the client certificate the external server presents; for kind "Group" it is the group name (e.g. a certificate O value); for kind "ServiceAccount" it is the name of the (operator-managed, out-of-band) ServiceAccount. | `spire-root` |
|
||||||
|
| `externalServerSubject.namespace` | Namespace of the ServiceAccount. Only used when kind is "ServiceAccount"; empty uses the server namespace. | `""` |
|
||||||
| `imagePullSecrets` | Pull secrets for images | `[]` |
|
| `imagePullSecrets` | Pull secrets for images | `[]` |
|
||||||
| `nameOverride` | Name override | `""` |
|
| `nameOverride` | Name override | `""` |
|
||||||
| `crNameOverride` | Name override for any custom resources | `""` |
|
| `crNameOverride` | Name override for any custom resources | `""` |
|
||||||
|
|||||||
@@ -412,12 +412,27 @@ The code below determines what connection type should be used.
|
|||||||
{{- default .Values.caSubject.commonName $g }}
|
{{- default .Values.caSubject.commonName $g }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
{{- define "spire-server.external-server-subject-kind" -}}
|
||||||
|
{{- $kind := .Values.externalServerSubject.kind | default "User" }}
|
||||||
|
{{- if not (has $kind (list "User" "Group" "ServiceAccount")) }}
|
||||||
|
{{- fail (printf "Unknown externalServerSubject.kind: %s (must be \"User\", \"Group\", or \"ServiceAccount\")" $kind) }}
|
||||||
|
{{- end }}
|
||||||
|
{{- $kind }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
{{- define "spire-server.subject" }}
|
{{- define "spire-server.subject" }}
|
||||||
subjects:
|
subjects:
|
||||||
{{- if .Values.externalServer }}
|
{{- if .Values.externalServer }}
|
||||||
|
{{- $kind := include "spire-server.external-server-subject-kind" . }}
|
||||||
|
{{- if eq $kind "ServiceAccount" }}
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: {{ .Values.externalServerSubject.name | quote }}
|
||||||
|
namespace: {{ .Values.externalServerSubject.namespace | default (include "spire-server.namespace" .) | quote }}
|
||||||
|
{{- else }}
|
||||||
- apiGroup: rbac.authorization.k8s.io
|
- apiGroup: rbac.authorization.k8s.io
|
||||||
kind: User
|
kind: {{ $kind }}
|
||||||
name: spire-root
|
name: {{ .Values.externalServerSubject.name | quote }}
|
||||||
|
{{- end }}
|
||||||
{{- else }}
|
{{- else }}
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: {{ include "spire-server.serviceAccountName" . }}
|
name: {{ include "spire-server.serviceAccountName" . }}
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ kind: statefulset
|
|||||||
## @param externalServer Deploy only the bundle ConfigMap, RBAC rules, and identity documents but not the server. Use in a nested setup where the server is external.
|
## @param externalServer Deploy only the bundle ConfigMap, RBAC rules, and identity documents but not the server. Use in a nested setup where the server is external.
|
||||||
externalServer: false
|
externalServer: false
|
||||||
|
|
||||||
|
## @param externalServerSubject.kind RBAC subject kind the external (nested) server's downstream bindings are granted to. One of "User" (client-certificate identity, the historical default), "Group", or "ServiceAccount" (e.g. for a static-token kubeconfig). Only used when externalServer is true.
|
||||||
|
## @param externalServerSubject.name Name of the subject. For kind "User" it must match the CN of the client certificate the external server presents; for kind "Group" it is the group name (e.g. a certificate O value); for kind "ServiceAccount" it is the name of the (operator-managed, out-of-band) ServiceAccount.
|
||||||
|
## @param externalServerSubject.namespace Namespace of the ServiceAccount. Only used when kind is "ServiceAccount"; empty uses the server namespace.
|
||||||
|
externalServerSubject:
|
||||||
|
kind: User
|
||||||
|
name: spire-root
|
||||||
|
namespace: ""
|
||||||
|
|
||||||
## @param imagePullSecrets [array] Pull secrets for images
|
## @param imagePullSecrets [array] Pull secrets for images
|
||||||
imagePullSecrets: []
|
imagePullSecrets: []
|
||||||
|
|
||||||
|
|||||||
@@ -288,4 +288,35 @@ spire-server:
|
|||||||
Expect(objs[serverTmpl]).Should(ContainSubstring("path: clusterb"))
|
Expect(objs[serverTmpl]).Should(ContainSubstring("path: clusterb"))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
Describe("spire-server.externalServerSubject", func() {
|
||||||
|
It("binds the external server's downstream RBAC to a ServiceAccount subject", func() {
|
||||||
|
objs, err := ValueStringRender(chart, `
|
||||||
|
spire-server:
|
||||||
|
externalServer: true
|
||||||
|
externalServerSubject:
|
||||||
|
kind: ServiceAccount
|
||||||
|
name: spire-external
|
||||||
|
namespace: spire-ext
|
||||||
|
`)
|
||||||
|
Expect(err).Should(Succeed())
|
||||||
|
roles := objs["spire/charts/spire-server/templates/roles.yaml"]
|
||||||
|
Expect(roles).Should(ContainSubstring("kind: ServiceAccount"))
|
||||||
|
Expect(roles).Should(ContainSubstring(`name: "spire-external"`))
|
||||||
|
Expect(roles).Should(ContainSubstring(`namespace: "spire-ext"`))
|
||||||
|
})
|
||||||
|
It("binds the external server's downstream RBAC to a Group subject", func() {
|
||||||
|
objs, err := ValueStringRender(chart, `
|
||||||
|
spire-server:
|
||||||
|
externalServer: true
|
||||||
|
externalServerSubject:
|
||||||
|
kind: Group
|
||||||
|
name: spire-admins
|
||||||
|
`)
|
||||||
|
Expect(err).Should(Succeed())
|
||||||
|
roles := objs["spire/charts/spire-server/templates/roles.yaml"]
|
||||||
|
Expect(roles).Should(ContainSubstring("apiGroup: rbac.authorization.k8s.io"))
|
||||||
|
Expect(roles).Should(ContainSubstring("kind: Group"))
|
||||||
|
Expect(roles).Should(ContainSubstring(`name: "spire-admins"`))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user