diff --git a/.github/tests/images.json b/.github/tests/images.json index 53f3fe4..db8cfe9 100644 --- a/.github/tests/images.json +++ b/.github/tests/images.json @@ -9,6 +9,11 @@ "query": "chown.image", "filter": "LATESTSHA", "sort-flags": [] + }, + { + "query": "tools.bash.image", + "filter": "LATESTSHA", + "sort-flags": [] } ], "spire-agent/values.yaml": [ diff --git a/charts/spire/charts/spire-server/README.md b/charts/spire/charts/spire-server/README.md index cb59246..298cab5 100644 --- a/charts/spire/charts/spire-server/README.md +++ b/charts/spire/charts/spire-server/README.md @@ -189,6 +189,14 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `caSubject.country` | Country for Spire server CA | `ARPA` | | `caSubject.organization` | Organization for Spire server CA | `Example` | | `caSubject.commonName` | Common Name for Spire server CA | `example.org` | +| `credentialComposer.cel.enabled` | Enable the cel based credential composer | `false` | +| `credentialComposer.cel.image.registry` | The OCI registry to pull the image from | `ghcr.io` | +| `credentialComposer.cel.image.repository` | The repository within the registry | `spiffe/spire-credentialcomposer-cel` | +| `credentialComposer.cel.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `credentialComposer.cel.image.tag` | Overrides the image tag | `0.0.2` | +| `credentialComposer.cel.checksum` | The sha256 checksum of the plugin binary | `23fa1d10f15ad5d5c555930cf82289c664801d7d5609bfd8847f95a0a667e4e4` | +| `credentialComposer.cel.pluginPath` | The filename in the container of the plugin | `/ko-app/cmd` | +| `credentialComposer.cel.jwt.expression` | The expression to use for jwt token composing | `""` | | `credentialComposer.uniqueID.enabled` | Add the x509UniqueIdentifier attribute to workload X509-SVIDs | `false` | | `keyManager.disk.enabled` | Flag to enable keyManager on disk | `true` | | `keyManager.memory.enabled` | Flag to enable keyManager in memory | `false` | @@ -328,6 +336,10 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr | `tools.kubectl.image.repository` | The repository within the registry | `rancher/kubectl` | | `tools.kubectl.image.pullPolicy` | The image pull policy | `IfNotPresent` | | `tools.kubectl.image.tag` | Overrides the image tag whose default is the chart appVersion | `""` | +| `tools.busybox.image.registry` | The OCI registry to pull the image from | `""` | +| `tools.busybox.image.repository` | The repository within the registry | `busybox` | +| `tools.busybox.image.pullPolicy` | The image pull policy | `IfNotPresent` | +| `tools.busybox.image.tag` | Overrides the image tag whose default is the chart appVersion | `1.37.0-uclibc` | | `telemetry.prometheus.enabled` | Flag to enable prometheus monitoring | `false` | | `telemetry.prometheus.podMonitor.enabled` | Enable podMonitor for prometheus | `false` | | `telemetry.prometheus.podMonitor.namespace` | Override where to install the podMonitor, if not set will use the same namespace as the spire-agent | `""` | diff --git a/charts/spire/charts/spire-server/templates/configmap.yaml b/charts/spire/charts/spire-server/templates/configmap.yaml index 1baaa55..ed30e50 100644 --- a/charts/spire/charts/spire-server/templates/configmap.yaml +++ b/charts/spire/charts/spire-server/templates/configmap.yaml @@ -102,9 +102,21 @@ server: {{- end }} plugins: - {{- if .Values.credentialComposer.uniqueID.enabled }} + {{- if or .Values.credentialComposer.uniqueID.enabled .Values.credentialComposer.cel.enabled }} CredentialComposer: + {{- if or .Values.credentialComposer.uniqueID.enabled }} uniqueid: {} + {{- end }} + {{- with .Values.credentialComposer.cel }} + {{- if .enabled }} + cel: + plugin_cmd: "/cel/credentialcomposer-cel" + plugin_checksum: {{ .checksum }} + plugin_data: + jwt: + expression_string: {{ .jwt.expression | quote }} + {{- end }} + {{- end }} {{- end }} DataStore: diff --git a/charts/spire/charts/spire-server/templates/server-resource.yaml b/charts/spire/charts/spire-server/templates/server-resource.yaml index 9b6f7dc..ab5c718 100644 --- a/charts/spire/charts/spire-server/templates/server-resource.yaml +++ b/charts/spire/charts/spire-server/templates/server-resource.yaml @@ -121,8 +121,41 @@ spec: securityContext: {{- $podSecurityContext | toYaml | nindent 8 }} {{- include "spire-lib.default_cluster_priority_class_name" . | nindent 6 }} - {{- if or (gt (len .Values.initContainers) 0) (and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create) .Values.nodeAttestor.tpmDirect.enabled $needsChown }} + {{- if or (gt (len .Values.initContainers) 0) (and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create) .Values.nodeAttestor.tpmDirect.enabled .Values.credentialComposer.cel.enabled $needsChown }} initContainers: + {{- if .Values.credentialComposer.cel.enabled }} + - name: init-cel + securityContext: + {{- include "spire-lib.securitycontext" . | nindent 12 }} + image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.tools.busybox.image "global" .Values.global) }} + # SPIRE must be able to fork the plugin directly within its container. First copy a busybox so that the plugin can be copied into the right place. + command: + - busybox + - sh + - -ec + - | + cp -a /bin/busybox /cel/busybox + volumeMounts: + - name: cel + mountPath: /cel + imagePullPolicy: {{ .Values.credentialComposer.cel.image.pullPolicy }} + - name: init-cel2 + securityContext: + {{- include "spire-lib.securitycontext" . | nindent 12 }} + image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.credentialComposer.cel.image "global" .Values.global) }} + # Second, use the previously copied busybox to copy the plugin into a volume that can be mounted where SPIRE can execute it. + command: + - /cel/busybox + - sh + - -ec + - | + /cel/busybox cp -a {{ .Values.credentialComposer.cel.pluginPath }} /cel/credentialcomposer-cel + /cel/busybox rm -f /cel/busybox + volumeMounts: + - name: cel + mountPath: /cel + imagePullPolicy: {{ .Values.credentialComposer.cel.image.pullPolicy }} + {{- end }} {{- if .Values.nodeAttestor.tpmDirect.enabled }} - name: init-tpm-direct securityContext: @@ -302,6 +335,11 @@ spec: mountPath: /kubeconfigs readOnly: true {{- end }} + {{- if .Values.credentialComposer.cel.enabled }} + - name: cel + mountPath: /cel + readOnly: true + {{- end }} {{- if .Values.nodeAttestor.tpmDirect.enabled }} - name: tpm-direct mountPath: /tpm @@ -440,6 +478,10 @@ spec: secret: secretName: {{ include "spire-server.fullname" . }}-kubeconfigs {{- end }} + {{- if .Values.credentialComposer.cel.enabled }} + - name: cel + emptyDir: {} + {{- end }} {{- if .Values.nodeAttestor.tpmDirect.enabled }} - name: tpm-direct emptyDir: {} diff --git a/charts/spire/charts/spire-server/values.yaml b/charts/spire/charts/spire-server/values.yaml index 69bb392..73b914d 100644 --- a/charts/spire/charts/spire-server/values.yaml +++ b/charts/spire/charts/spire-server/values.yaml @@ -340,6 +340,34 @@ caSubject: commonName: example.org credentialComposer: + cel: + ## @param credentialComposer.cel.enabled Enable the cel based credential composer + enabled: false + ## @param credentialComposer.cel.image.registry The OCI registry to pull the image from + ## @param credentialComposer.cel.image.repository The repository within the registry + ## @param credentialComposer.cel.image.pullPolicy The image pull policy + ## @param credentialComposer.cel.image.tag Overrides the image tag + ## + image: + registry: ghcr.io + repository: spiffe/spire-credentialcomposer-cel + pullPolicy: IfNotPresent + tag: "0.0.2" + ## @param credentialComposer.cel.checksum The sha256 checksum of the plugin binary + checksum: 23fa1d10f15ad5d5c555930cf82289c664801d7d5609bfd8847f95a0a667e4e4 + ## @param credentialComposer.cel.pluginPath The filename in the container of the plugin + pluginPath: /ko-app/cmd + jwt: + ## @param credentialComposer.cel.jwt.expression The expression to use for jwt token composing + expression: "" + #expression: | + # spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDResponse{ + # attributes: spire.plugin.server.credentialcomposer.v1.JWTSVIDAttributes{ + # claims: request.attributes.claims.mapOverrideEntries( + # {'newclaim': "value"} + # ) + # } + # } uniqueID: ## @param credentialComposer.uniqueID.enabled Add the x509UniqueIdentifier attribute to workload X509-SVIDs enabled: false @@ -779,6 +807,17 @@ tools: repository: rancher/kubectl pullPolicy: IfNotPresent tag: "" + busybox: + ## @param tools.busybox.image.registry The OCI registry to pull the image from + ## @param tools.busybox.image.repository The repository within the registry + ## @param tools.busybox.image.pullPolicy The image pull policy + ## @param tools.busybox.image.tag Overrides the image tag whose default is the chart appVersion + ## + image: + registry: "" + repository: busybox + pullPolicy: IfNotPresent + tag: 1.37.0-uclibc telemetry: prometheus: diff --git a/examples/credentialcomposer-cel/values.yaml b/examples/credentialcomposer-cel/values.yaml new file mode 100644 index 0000000..749430a --- /dev/null +++ b/examples/credentialcomposer-cel/values.yaml @@ -0,0 +1,14 @@ +# Details at https://github.com/spiffe/spire-credentialcomposer-cel/blob/main/README.md +spire-server: + credentialComposer: + cel: + enabled: true + jwt: + expression: | + spire.plugin.server.credentialcomposer.v1.ComposeWorkloadJWTSVIDResponse{ + attributes: spire.plugin.server.credentialcomposer.v1.JWTSVIDAttributes{ + claims: request.attributes.claims.mapOverrideEntries( + {'newclaim': "value"} + ) + } + }