Update spire-identity-exchange for 0.4.0 (#900)

* Update spire-identity-exchange for 0.4.0

Signed-off-by: Kevin Fox <[email protected]>

* Understand the plugin config

Signed-off-by: Kevin Fox <[email protected]>

* Fix test

Signed-off-by: Kevin Fox <[email protected]>

* Update ip

Signed-off-by: Kevin Fox <[email protected]>

* Update name

Signed-off-by: Kevin Fox <[email protected]>

* Update name

Signed-off-by: Kevin Fox <[email protected]>

* Update name

Signed-off-by: Kevin Fox <[email protected]>

* Fix broken socket path

Signed-off-by: Kevin Fox <[email protected]>

* Nope, it was right before

Signed-off-by: Kevin Fox <[email protected]>

* Try disabling the spiffe plugin for now

Signed-off-by: Kevin Fox <[email protected]>

* Try logging more

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Map non container behavior

Signed-off-by: Kevin Fox <[email protected]>

* Add missing csi driver settings

Signed-off-by: Kevin Fox <[email protected]>

* Test

Signed-off-by: Kevin Fox <[email protected]>

* Test

Signed-off-by: Kevin Fox <[email protected]>

* Fix

Signed-off-by: Kevin Fox <[email protected]>

* Use local oidc discovery provider path by default

Signed-off-by: Kevin Fox <[email protected]>

* Enable spire-identity-exchange in shared infrastructure

Signed-off-by: Kevin Fox <[email protected]>

* Update timeout

Signed-off-by: Kevin Fox <[email protected]>

* Update timeout

Signed-off-by: Kevin Fox <[email protected]>

* Test config

Signed-off-by: Kevin Fox <[email protected]>

* Test config

Signed-off-by: Kevin Fox <[email protected]>

* Test config

Signed-off-by: Kevin Fox <[email protected]>

* Test config

Signed-off-by: Kevin Fox <[email protected]>

* Fix

Signed-off-by: Kevin Fox <[email protected]>

* Fix

Signed-off-by: Kevin Fox <[email protected]>

* Bump spire-ha-agent version to fix issue

Signed-off-by: Kevin Fox <[email protected]>

* Fix

Signed-off-by: Kevin Fox <[email protected]>

* Fix

Signed-off-by: Kevin Fox <[email protected]>

* Bump version

Signed-off-by: Kevin Fox <[email protected]>

* Update version bits to match what it should be, minus final bump

Signed-off-by: Kevin Fox <[email protected]>

---------

Signed-off-by: Kevin Fox <[email protected]>
Signed-off-by: kfox1111 <[email protected]>
Co-authored-by: Faisal Memon <[email protected]>
This commit is contained in:
kfox1111
2026-08-18 05:17:43 +00:00
committed by GitHub
co-authored by Faisal Memon
parent de48d14312
commit 07ba722da0
45 changed files with 2120 additions and 580 deletions
@@ -92,6 +92,64 @@ Create the name of the service account to use
{{- printf "/spiffe-workload-api/%s" .Values.agentSocketName }}
{{- end }}
{{/*
Volume name for an extra SPIFFE CSI driver. Driver names are DNS subdomains and may
contain dots, which a volume name (a DNS-1123 label) may not, so squash every run of
non-alphanumeric characters down to a single dash.
Args: the driver name as a string
*/}}
{{- define "spire-identity-exchange.csi-volume-name" -}}
{{- printf "spiffe-workload-api-%s" (trimAll "-" (regexReplaceAll "[^a-z0-9]+" (lower .) "-")) | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Path to the SPIRE Agent workload socket one auth plugin should talk to. A plugin that
names no driver of its own, or names the one the exchange itself uses, gets the socket
already mounted for the pod; anything else gets its own mount under /spiffe-workload-apis.
Args: dict "root" <root context> "driver" <csi driver name, may be empty>
*/}}
{{- define "spire-identity-exchange.plugin-workload-api-socket-path" -}}
{{- $root := .root }}
{{- $driver := .driver | default "" }}
{{- if or (eq $driver "") (eq $driver $root.Values.csiDriverName) }}
{{- include "spire-identity-exchange.workload-api-socket-path" $root }}
{{- else }}
{{- printf "/spiffe-workload-apis/%s/%s" $driver $root.Values.agentSocketName }}
{{- end }}
{{- end }}
{{/*
The CSI drivers this release must mount in addition to the pod's own, collected from the
enabled spiffe auth plugins. Deduplicated, so two plugins naming the same driver share one
volume. Returns JSON of driver name -> volume name; callers pipe it through fromJson.
*/}}
{{- define "spire-identity-exchange.extra-csi-drivers" -}}
{{- $root := . }}
{{- $drivers := dict }}
{{- $volumeNames := dict }}
{{- range $name, $config := .Values.auth.plugins }}
{{- $config = $config | default dict }}
{{- if ne (dig "enabled" true $config) false }}
{{- $pluginType := include "spire-identity-exchange.plugin-type" (dict "root" $root "name" $name "config" $config) }}
{{- $driver := dig "csiDriverName" "" $config }}
{{- if and (eq $pluginType "spiffe") (not (empty $driver)) }}
{{- if not (kindIs "string" $driver) }}
{{- fail (printf "auth.plugins.%s.csiDriverName: expected string, got %s" $name (kindOf $driver)) }}
{{- end }}
{{- if ne $driver $root.Values.csiDriverName }}
{{- $volumeName := include "spire-identity-exchange.csi-volume-name" $driver }}
{{- if and (hasKey $volumeNames $volumeName) (ne (index $volumeNames $volumeName) $driver) }}
{{- fail (printf "auth.plugins.%s.csiDriverName: %q and %q both reduce to the volume name %q. Volume names allow only lowercase alphanumerics and dashes, so these two drivers cannot be told apart; rename one so they differ by more than punctuation." $name $driver (index $volumeNames $volumeName) $volumeName) }}
{{- end }}
{{- $_ := set $volumeNames $volumeName $driver }}
{{- $_ := set $drivers $driver $volumeName }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- $drivers | toJson }}
{{- end }}
{{- define "spire-identity-exchange.podSecurityContext" -}}
{{- $podSecurityContext := include "spire-lib.podsecuritycontext" . | fromYaml }}
{{- $openshift := ((.Values).global).openshift | default false }}
@@ -131,3 +189,57 @@ Create the name of the service account to use
{{ .Release.Name }}-server.{{ include "spire-identity-exchange.server.namespace" . }}
{{- end }}
{{- end }}
{{- define "spire-identity-exchange.plugin-type" }}
{{- $type := .name }}
{{- with .config.plugin }}
{{- $type = . }}
{{- end }}
{{- if not (has $type (list "k8s_psat" "spiffe" "github" "gitlab" )) }}
{{- fail (printf "Unknown plugin type specified: %s" $type) }}
{{- end }}
{{- printf "%s" $type }}
{{- end }}
{{/*
Validate one plugin's config block against the option table for its type.
Emits nothing; only fails.
Args: dict "name" <instance name> "type" <plugin type> "config" <config map>
"options" <dict of option name -> "string" | "[]string" | "bool">
*/}}
{{- define "spire-identity-exchange.check-plugin-options" }}
{{- $ctx := . }}
{{- $valid := keys $ctx.options | sortAlpha | join ", " }}
{{- range $key, $val := $ctx.config }}
{{- if not (hasKey $ctx.options $key) }}
{{- fail (printf "auth.plugins.%s.config: %q is not a valid option for plugin type %q (valid options: %s). Use auth.unsupportedBuiltInPlugins to pass through options this chart does not model." $ctx.name $key $ctx.type $valid) }}
{{- end }}
{{- $want := index $ctx.options $key }}
{{- if eq $want "[]string" }}
{{- if not (kindIs "slice" $val) }}
{{- fail (printf "auth.plugins.%s.config.%s: expected a list of strings, got %s" $ctx.name $key (kindOf $val)) }}
{{- end }}
{{- range $val }}
{{- if not (kindIs "string" .) }}
{{- fail (printf "auth.plugins.%s.config.%s: every entry must be a string, got %s" $ctx.name $key (kindOf .)) }}
{{- end }}
{{- end }}
{{- else if not (kindIs $want $val) }}
{{- fail (printf "auth.plugins.%s.config.%s: expected %s, got %s" $ctx.name $key $want (kindOf $val)) }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Fail if any of the named options is absent or empty. Emits nothing.
Args: dict "name" <instance name> "type" <plugin type> "config" <config map>
"required" <list of option names>
*/}}
{{- define "spire-identity-exchange.check-plugin-required" }}
{{- $ctx := . }}
{{- range $ctx.required }}
{{- if empty (index $ctx.config .) }}
{{- fail (printf "auth.plugins.%s.config.%s is required for plugin type %q" $ctx.name . $ctx.type) }}
{{- end }}
{{- end }}
{{- end }}
@@ -4,12 +4,18 @@ dnsNames:
{{- if ne (len .Values.tls.certManager.certificate.dnsNames) 0 }}
{{- toYaml .Values.tls.certManager.certificate.dnsNames | nindent 4 }}
{{- else }}
{{- if .Values.rest.enabled }}
- {{ include "spire-lib.ingress-calculated-name" (dict "ingress" .Values.rest.ingress "Values" .Values) }}
{{- end }}
{{- if .Values.grpc.enabled }}
- {{ include "spire-lib.ingress-calculated-name" (dict "ingress" .Values.grpc.ingress "Values" .Values) }}
{{- $hosts := list }}
{{- range $l := list .Values.tls.rest .Values.tls.grpc }}
{{- if $l.enabled }}
{{- if $l.ingress.enabled }}
{{- $hosts = append $hosts (include "spire-lib.ingress-calculated-name" (dict "ingress" $l.ingress "Values" $.Values) | trim) }}
{{- end }}
{{- if $l.gatewayAPI.enabled }}
{{- $hosts = append $hosts (include "spire-lib.ingress-calculated-name" (dict "ingress" (dict "host" $l.gatewayAPI.host) "Values" $.Values) | trim) }}
{{- end }}
{{- end }}
{{- end }}
{{- toYaml (uniq $hosts) | nindent 4 }}
{{- end }}
issuerRef:
{{- with .Values.tls.certManager.certificate.issuerRef.group }}
@@ -19,7 +25,7 @@ issuerRef:
name: {{ default $fullName .Values.tls.certManager.certificate.issuerRef.name }}
secretName: {{ $fullName }}-cert
{{- end }}
{{- if .Values.tls.certManager.enabled }}
{{- if and .Values.tls.certManager.enabled (or .Values.tls.rest.enabled .Values.tls.grpc.enabled) }}
---
apiVersion: cert-manager.io/v1
kind: Certificate
@@ -1,20 +1,47 @@
{{- $tlsCount := 0 }}
{{- if .Values.tls.externalSecret.enabled }}
{{- $tlsCount = add $tlsCount 1 }}
{{- $fileTLS := or .Values.tls.rest.enabled .Values.tls.grpc.enabled }}
{{- if $fileTLS }}
{{- $tlsCount := 0 }}
{{- if .Values.tls.externalSecret.enabled }}
{{- $tlsCount = add $tlsCount 1 }}
{{- end }}
{{- if .Values.tls.certManager.enabled }}
{{- $tlsCount = add $tlsCount 1 }}
{{- end }}
{{- if ne $tlsCount 1 }}
{{- fail "You must have one and only one TLS configuration enabled (tls.externalSecret or tls.certManager) when a tls listener is enabled" }}
{{- end }}
{{- if and .Values.tls.certManager.enabled (eq (len .Values.tls.certManager.certificate.dnsNames) 0) }}
{{- if and .Values.tls.rest.enabled (not (or .Values.tls.rest.ingress.enabled .Values.tls.rest.gatewayAPI.enabled)) }}
{{- fail "tls.certManager takes the certificate hostname from the exposure: enable tls.rest.ingress or tls.rest.gatewayAPI, or set tls.certManager.certificate.dnsNames" }}
{{- end }}
{{- if and .Values.tls.grpc.enabled (not (or .Values.tls.grpc.ingress.enabled .Values.tls.grpc.gatewayAPI.enabled)) }}
{{- fail "tls.certManager takes the certificate hostname from the exposure: enable tls.grpc.ingress or tls.grpc.gatewayAPI, or set tls.certManager.certificate.dnsNames" }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.tls.certManager.enabled }}
{{- $tlsCount = add $tlsCount 1 }}
{{- if kindIs "slice" .Values.auth.plugins }}
{{- fail "auth.plugins is a mapping keyed by plugin name, not a list: replace each `- plugin: k8s_psat` entry with a `k8s_psat:` key holding its config" }}
{{- end }}
{{- if ne $tlsCount 1 }}
{{- fail "You must have one and only one TLS configuration enabled" }}
{{- if kindIs "slice" .Values.auth.stacks }}
{{- fail "auth.stacks is a mapping keyed by stack name, not a list: replace each `- name: foo` / `plugins: [...]` entry with a `foo:` key holding `plugins: [...]`" }}
{{- end }}
{{- if lt (len .Values.auth.plugins) 1 }}
{{- fail "You must have at least one auth plugin defined" }}
{{- end }}
{{- if not (or .Values.rest.enabled .Values.grpc.enabled) }}
{{- fail "You must have rest and/or grpc enabled" }}
{{- if not (or $fileTLS .Values.spiffe.rest.enabled .Values.spiffe.grpc.enabled) }}
{{- fail "You must enable at least one listener: tls.rest, tls.grpc, spiffe.rest or spiffe.grpc" }}
{{- end }}
{{- $trustDomain := include "spire-lib.trust-domain" . }}
{{- $root := . }}
{{- $enabledPlugins := list }}
{{- range $name, $config := .Values.auth.plugins }}
{{- if ne (dig "enabled" true ($config | default dict)) false }}
{{- $enabledPlugins = append $enabledPlugins $name }}
{{- end }}
{{- end }}
{{- if lt (len $enabledPlugins) 1 }}
{{- fail "Every auth plugin is disabled: at least one entry in auth.plugins must have enabled: true" }}
{{- end }}
{{- include "spire-lib.check-strict-mode" (list . "trustDomain must be set" (eq $trustDomain "example.org"))}}
apiVersion: v1
kind: ConfigMap
@@ -28,23 +55,147 @@ metadata:
data:
six.conf: |
name: spire-identity-exchange
logLevel: info
logLevel: {{ .Values.config.logLevel }}
server:
port: 8443
restPort: 8444
metricsPort: 4950
metricsPort: {{ .Values.telemetry.prometheus.port }}
tls:
{{- if $fileTLS }}
certFile: /secret/tls.crt
keyFile: /secret/tls.key
{{- end }}
grpc:
enable: {{ .Values.tls.grpc.enabled }}
port: {{ .Values.tls.grpc.port }}
rest:
enable: {{ .Values.tls.rest.enabled }}
port: {{ .Values.tls.rest.port }}
spiffe:
grpc:
enable: {{ .Values.spiffe.grpc.enabled }}
port: {{ .Values.spiffe.grpc.port }}
rest:
enable: {{ .Values.spiffe.rest.enabled }}
port: {{ .Values.spiffe.rest.port }}
spire:
agentWorkloadSocketPath: /spiffe-workload-api/spire-agent.sock
agentWorkloadSocketPath: {{ include "spire-identity-exchange.workload-api-socket-path" . }}
agentDelegatedSocketPath: /agent/admin.sock
trustDomain: {{ $trustDomain }}
svidTTL: 1h
auth:
passthroughPlugins: {{ .Values.auth.passthroughPlugins }}
plugins:
{{- toYaml .Values.auth.plugins | nindent 8 }}
{{ with .Values.auth.stacks }}
{{- range $name, $config := .Values.auth.plugins }}
{{- if has $name $enabledPlugins }}
{{- $pluginType := include "spire-identity-exchange.plugin-type" (dict "root" $root "name" $name "config" $config) }}
{{- $cfg := $config.config | default dict }}
{{- if hasKey ($config | default dict) "csiDriverName" }}
{{- if ne $pluginType "spiffe" }}
{{- fail (printf "auth.plugins.%s: csiDriverName is only supported on plugins of type \"spiffe\". Plugin type %q does not talk to a SPIRE Agent workload socket, so there is nothing to mount the driver for." $name $pluginType) }}
{{- end }}
{{- if not (kindIs "string" $config.csiDriverName) }}
{{- fail (printf "auth.plugins.%s.csiDriverName: expected string, got %s" $name (kindOf $config.csiDriverName)) }}
{{- end }}
{{- end }}
{{ if eq $name "k8sPSAT" }}k8s_psat{{ else }}{{ $name | quote }}{{ end }}:
{{- with $config.plugin }}
plugin: {{ . | quote }}
{{- end }}
config:
{{- if eq $pluginType "k8s_psat" }}
{{- if hasKey $cfg "kubeconfig" }}
{{- fail (printf "auth.plugins.%s.config: kubeconfig is not supported by this chart. In a pod, spire-identity-exchange always authenticates to the Kubernetes API with the in-cluster credentials of its own ServiceAccount and ignores a kubeconfig file, so pointing it at another cluster would silently validate tokens against the local one instead." $name) }}
{{- end }}
{{- $_ := include "spire-identity-exchange.check-plugin-options" (dict "name" $name "type" $pluginType "config" $cfg "options" (dict
"clusterName" "string"
"audiences" "[]string"
"allowedNamespaces" "[]string"
"allowedServiceAccounts" "[]string"
"jwksCheck" "bool"
"tokenReview" "bool")) }}
{{- $jwksCheck := ne (dig "jwksCheck" true $cfg) false }}
{{- $tokenReview := ne (dig "tokenReview" true $cfg) false }}
{{- if not (or $jwksCheck $tokenReview) }}
{{- fail (printf "auth.plugins.%s.config: jwksCheck and tokenReview cannot both be false; at least one validation stage must remain active" $name) }}
{{- end }}
{{- if $jwksCheck }}
{{- $_ := include "spire-identity-exchange.check-plugin-required" (dict "name" $name "type" $pluginType "config" $cfg "required" (list "audiences")) }}
{{- end }}
{{- if and (empty $cfg.allowedNamespaces) (empty $cfg.allowedServiceAccounts) }}
{{- fail (printf "auth.plugins.%s.config: at least one of allowedNamespaces or allowedServiceAccounts must be set" $name) }}
{{- end }}
{{- toYaml $config.config | nindent 12 }}
{{- else if eq $pluginType "spiffe" }}
{{- if hasKey $cfg "agentWorkloadSocketPath" }}
{{- fail (printf "auth.plugins.%s.config: agentWorkloadSocketPath is set by this chart, not in values. The SPIRE Agent workload socket is mounted from the SPIFFE CSI driver and the path is filled in automatically when connectWithTrustBundle is true." $name) }}
{{- end }}
{{- $_ := include "spire-identity-exchange.check-plugin-options" (dict "name" $name "type" $pluginType "config" $cfg "options" (dict
"issuerURL" "string"
"discoveryURL" "string"
"trustDomain" "string"
"audiences" "[]string"
"pathPatterns" "[]string"
"connectWithTrustBundle" "bool")) }}
{{- $_ := include "spire-identity-exchange.check-plugin-required" (dict "name" $name "type" $pluginType "config" $cfg "required" (list "issuerURL" "audiences" "trustDomain" "pathPatterns")) }}
{{- $driver := dig "csiDriverName" "" ($config | default dict) }}
{{- if and (not (empty $driver)) (not $cfg.connectWithTrustBundle) }}
{{- fail (printf "auth.plugins.%s: csiDriverName is only meaningful when config.connectWithTrustBundle is true; the SPIRE Agent workload socket is not used otherwise." $name) }}
{{- end }}
{{- $keySource := dig "keySource" "oidc" ($config | default dict) }}
{{- if not (has $keySource (list "oidc" "oidcLocal")) }}
{{- fail (printf "auth.plugins.%s.keySource: %q is not valid; must be oidc or oidcLocal" $name $keySource) }}
{{- end }}
{{- $effective := $cfg }}
{{- if $cfg.connectWithTrustBundle }}
{{- $effective = merge (dict "agentWorkloadSocketPath" (include "spire-identity-exchange.plugin-workload-api-socket-path" (dict "root" $root "driver" $driver))) $cfg }}
{{- end }}
{{- if and (eq $keySource "oidcLocal") (empty $cfg.discoveryURL) }}
{{- $effective = merge (dict "discoveryURL" (printf "https://%s-spiffe-oidc-discovery-provider" $root.Release.Name)) $effective }}
{{- end }}
{{- toYaml $effective | nindent 12 }}
{{- else if eq $pluginType "github" }}
{{- $_ := include "spire-identity-exchange.check-plugin-options" (dict "name" $name "type" $pluginType "config" $cfg "options" (dict
"issuerURL" "string"
"audiences" "[]string"
"allowedRepositoryOwners" "[]string"
"allowedRepositories" "[]string")) }}
{{- $_ := include "spire-identity-exchange.check-plugin-required" (dict "name" $name "type" $pluginType "config" $cfg "required" (list "audiences")) }}
{{- if and (empty $cfg.allowedRepositoryOwners) (empty $cfg.allowedRepositories) }}
{{- fail (printf "auth.plugins.%s.config: at least one of allowedRepositoryOwners or allowedRepositories must be set" $name) }}
{{- end }}
{{- toYaml $config.config | nindent 12 }}
{{- else if eq $pluginType "gitlab" }}
{{- $_ := include "spire-identity-exchange.check-plugin-options" (dict "name" $name "type" $pluginType "config" $cfg "options" (dict
"issuerURL" "string"
"audiences" "[]string"
"allowedNamespacePaths" "[]string"
"allowedProjectPaths" "[]string")) }}
{{- $_ := include "spire-identity-exchange.check-plugin-required" (dict "name" $name "type" $pluginType "config" $cfg "required" (list "audiences")) }}
{{- if and (empty $cfg.allowedNamespacePaths) (empty $cfg.allowedProjectPaths) }}
{{- fail (printf "auth.plugins.%s.config: at least one of allowedNamespacePaths or allowedProjectPaths must be set" $name) }}
{{- end }}
{{- toYaml $config.config | nindent 12 }}
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.auth.unsupportedBuiltInPlugins }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- $stacks := dict }}
{{- range $stackName, $stack := .Values.auth.stacks }}
{{- if ne (dig "enabled" true ($stack | default dict)) false }}
{{- range $plugin := $stack.plugins }}
{{- if not (has $plugin $enabledPlugins) }}
{{- if hasKey $root.Values.auth.plugins $plugin }}
{{- fail (printf "auth.stacks.%s lists plugin %q, which is disabled. Set auth.plugins.%s.enabled: true or drop it from the stack; the exchange refuses to start when a stack names a plugin it did not load." $stackName $plugin $plugin) }}
{{- else }}
{{- fail (printf "auth.stacks.%s lists plugin %q, which is not defined in auth.plugins" $stackName $plugin) }}
{{- end }}
{{- end }}
{{- end }}
{{- $_ := set $stacks $stackName (omit $stack "enabled") }}
{{- end }}
{{- end }}
{{- with $stacks }}
stacks:
{{- toYaml . | nindent 8 }}
{{- end }}
@@ -80,7 +231,7 @@ data:
NodeAttestor "x509pop" {
plugin_data {
spiffe_endpoint_socket = "unix:///spiffe-workload-api/spire-agent.sock"
spiffe_endpoint_socket = "unix://{{ include "spire-identity-exchange.workload-api-socket-path" . }}"
}
}
@@ -1,5 +1,7 @@
{{- $configSum := (include (print $.Template.BasePath "/configmap.yaml") . | sha256sum) }}
{{- $trustDomain := include "spire-lib.trust-domain" . }}
{{- $fileTLS := or .Values.tls.rest.enabled .Values.tls.grpc.enabled }}
{{- $extraCSIDrivers := include "spire-identity-exchange.extra-csi-drivers" . | fromJson }}
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -55,7 +57,7 @@ spec:
- /trustbundle/socket
env:
- name: SPIFFE_ENDPOINT_SOCKET
value: "unix:///spiffe-workload-api/spire-agent.sock"
value: "unix://{{ include "spire-identity-exchange.workload-api-socket-path" . }}"
- name: SPIFFE_TRUST_DOMAIN
value: {{ $trustDomain }}
readinessProbe:
@@ -124,26 +126,49 @@ spec:
- -config
- /etc/spire/identity-exchange/six.conf
- -expand-env
{{- with .Values.extraEnv }}
env:
- name: SPIFFE_TRUST_DOMAIN
value: {{ $trustDomain | quote }}
- name: K8S_CLUSTER_NAME
value: {{ include "spire-lib.cluster-name" . | trim | quote }}
- name: SPIFFE_JWT_ISSUER
value: {{ include "spire-lib.jwt-issuer" . | trim | quote }}
{{- with .Values.extraEnv }}
{{- . | toYaml | nindent 12 }}
{{- end }}
ports:
{{- if .Values.rest.enabled }}
- containerPort: 8444
{{- if .Values.tls.rest.enabled }}
- containerPort: {{ .Values.tls.rest.port }}
name: rest
{{- end }}
{{- if .Values.grpc.enabled }}
- containerPort: 8443
{{- if .Values.tls.grpc.enabled }}
- containerPort: {{ .Values.tls.grpc.port }}
name: grpc
{{- end }}
{{- if .Values.spiffe.rest.enabled }}
- containerPort: {{ .Values.spiffe.rest.port }}
name: rest-spiffe
{{- end }}
{{- if .Values.spiffe.grpc.enabled }}
- containerPort: {{ .Values.spiffe.grpc.port }}
name: grpc-spiffe
{{- end }}
- containerPort: {{ .Values.telemetry.prometheus.port }}
name: prom
volumeMounts:
- name: spiffe-workload-api
mountPath: {{ include "spire-identity-exchange.workload-api-socket-path" . | dir }}
readOnly: true
{{- range $driver, $volumeName := $extraCSIDrivers }}
- name: {{ $volumeName }}
mountPath: /spiffe-workload-apis/{{ $driver }}
readOnly: true
{{- end }}
{{- if $fileTLS }}
- name: certdir
mountPath: /secret
readOnly: true
{{- end }}
- name: spire-identity-exchange-config
mountPath: /etc/spire/identity-exchange/six.conf
subPath: six.conf
@@ -168,6 +193,13 @@ spec:
csi:
driver: "{{ .Values.csiDriverName }}"
readOnly: true
{{- range $driver, $volumeName := $extraCSIDrivers }}
- name: {{ $volumeName }}
csi:
driver: "{{ $driver }}"
readOnly: true
{{- end }}
{{- if $fileTLS }}
- name: certdir
{{- if .Values.tls.externalSecret.enabled }}
secret:
@@ -176,6 +208,7 @@ spec:
secret:
secretName: {{ include "spire-identity-exchange.fullname" . }}-cert
{{- end }}
{{- end }}
- name: spire-agent-socket
emptyDir: {}
- name: spire-agent-data
@@ -1,13 +0,0 @@
{{- if .Values.grpc.gatewayAPI.enabled -}}
{{- $routeKind := include "spire-lib.gateway-route-kind" (dict "gatewayAPI" .Values.grpc.gatewayAPI) -}}
{{- include "spire-lib.gateway-routes" (dict
"root" .
"gatewayAPI" .Values.grpc.gatewayAPI
"name" (printf "%s-grpc" (include "spire-identity-exchange.fullname" .))
"namespace" (include "spire-identity-exchange.namespace" .)
"svcName" (printf "%s-grpc" (include "spire-identity-exchange.fullname" .))
"port" .Values.grpc.service.port
"labels" (include "spire-identity-exchange.labels" .)
"routeKind" $routeKind
"backendTLS" (eq $routeKind "HTTPRoute")) }}
{{- end }}
@@ -10,7 +10,7 @@ solvers:
- http01:
ingress: {}
{{- end }}
{{- if and .Values.tls.certManager.enabled .Values.tls.certManager.issuer.create }}
{{- if and .Values.tls.certManager.enabled .Values.tls.certManager.issuer.create (or .Values.tls.rest.enabled .Values.tls.grpc.enabled) }}
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
@@ -0,0 +1,28 @@
{{- if (dig "telemetry" "prometheus" "podMonitor" "enabled" .Values.telemetry.prometheus.podMonitor.enabled .Values.global) }}
{{- $namespace := include "spire-identity-exchange.podMonitor.namespace" . }}
{{- $podNamespace := include "spire-identity-exchange.namespace" . }}
apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
name: {{ include "spire-identity-exchange.fullname" . }}
namespace: {{ $namespace | quote }}
labels:
{{- include "spire-identity-exchange.labels" . | nindent 4 }}
{{- if ne (len (dig "telemetry" "prometheus" "podMonitor" "labels" (dict) .Values.global)) 0 }}
{{- .Values.global.telemetry.prometheus.podMonitor.labels | toYaml | nindent 4 }}
{{- end }}
{{- with .Values.telemetry.prometheus.podMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:
{{- include "spire-identity-exchange.selectorLabels" . | nindent 6 }}
podMetricsEndpoints:
- port: prom
{{- if ne $namespace $podNamespace }}
namespaceSelector:
matchNames:
- {{ $podNamespace | quote }}
{{- end }}
{{- end }}
@@ -1,13 +0,0 @@
{{- if .Values.rest.gatewayAPI.enabled -}}
{{- $routeKind := include "spire-lib.gateway-route-kind" (dict "gatewayAPI" .Values.rest.gatewayAPI) -}}
{{- include "spire-lib.gateway-routes" (dict
"root" .
"gatewayAPI" .Values.rest.gatewayAPI
"name" (printf "%s-rest" (include "spire-identity-exchange.fullname" .))
"namespace" (include "spire-identity-exchange.namespace" .)
"svcName" (printf "%s-rest" (include "spire-identity-exchange.fullname" .))
"port" .Values.rest.service.port
"labels" (include "spire-identity-exchange.labels" .)
"routeKind" $routeKind
"backendTLS" (eq $routeKind "HTTPRoute")) }}
{{- end }}
@@ -0,0 +1,15 @@
{{- if and .Values.spiffe.grpc.enabled .Values.spiffe.grpc.gatewayAPI.enabled -}}
{{- $fullName := printf "%s-grpc-spiffe" (include "spire-identity-exchange.fullname" .) -}}
{{/* Passthrough only. This backend serves an X509-SVID, whose only SAN is a
spiffe:// URI, so a BackendTLSPolicy hostname check could never match. */}}
{{- include "spire-lib.gateway-routes" (dict
"root" .
"gatewayAPI" .Values.spiffe.grpc.gatewayAPI
"name" $fullName
"namespace" (include "spire-identity-exchange.namespace" .)
"svcName" $fullName
"port" .Values.spiffe.grpc.service.port
"labels" (include "spire-identity-exchange.labels" .)
"routeKind" "TLSRoute"
"backendTLS" false) }}
{{- end }}
@@ -0,0 +1,39 @@
{{- if and .Values.spiffe.grpc.enabled .Values.spiffe.grpc.ingress.enabled -}}
{{- $port := .Values.spiffe.grpc.service.port }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.spiffe.grpc.ingress) }}
{{- $fullName := printf "%s-grpc-spiffe" (include "spire-identity-exchange.fullname" .) }}
{{- $path := "/" }}
{{- $pathType := "Prefix" }}
{{- $tlsSection := true }}
{{- $annotations := deepCopy .Values.spiffe.grpc.ingress.annotations }}
{{- if eq $ingressControllerType "ingress-nginx" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/force-ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/backend-protocol" "HTTPS" }}
{{- if not .Values.spiffe.grpc.ingress.tlsSecret }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-passthrough" "true" }}
{{- end }}
{{- else if eq $ingressControllerType "openshift" }}
{{- if .Values.spiffe.grpc.ingress.tlsSecret }}
{{- $_ := set $annotations "route.openshift.io/termination" "reencrypt" }}
{{- else }}
{{- $_ := set $annotations "route.openshift.io/termination" "passthrough" }}
{{- end }}
{{- $path = "" }}
{{- $pathType = "ImplementationSpecific" }}
{{- $tlsSection = false }}
{{- end }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ include "spire-identity-exchange.namespace" . }}
labels:
{{ include "spire-identity-exchange.labels" . | nindent 4 }}
{{- with $annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{ include "spire-lib.ingress-spec" (dict "ingress" .Values.spiffe.grpc.ingress "svcName" $fullName "port" $port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{- end }}
@@ -0,0 +1,23 @@
{{- if .Values.spiffe.grpc.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "spire-identity-exchange.fullname" . }}-grpc-spiffe
namespace: {{ include "spire-identity-exchange.namespace" . }}
{{- with .Values.spiffe.grpc.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.spiffe.grpc.service.type }}
{{- if and (eq .Values.spiffe.grpc.service.type "LoadBalancer") .Values.spiffe.grpc.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.spiffe.grpc.service.loadBalancerIP }}
{{- end }}
ports:
- name: https
port: {{ .Values.spiffe.grpc.service.port }}
targetPort: grpc-spiffe
protocol: TCP
selector:
{{- include "spire-identity-exchange.selectorLabels" . | nindent 4 }}
{{- end }}
@@ -0,0 +1,15 @@
{{- if and .Values.spiffe.rest.enabled .Values.spiffe.rest.gatewayAPI.enabled -}}
{{- $fullName := printf "%s-rest-spiffe" (include "spire-identity-exchange.fullname" .) -}}
{{/* Passthrough only. This backend serves an X509-SVID, whose only SAN is a
spiffe:// URI, so a BackendTLSPolicy hostname check could never match. */}}
{{- include "spire-lib.gateway-routes" (dict
"root" .
"gatewayAPI" .Values.spiffe.rest.gatewayAPI
"name" $fullName
"namespace" (include "spire-identity-exchange.namespace" .)
"svcName" $fullName
"port" .Values.spiffe.rest.service.port
"labels" (include "spire-identity-exchange.labels" .)
"routeKind" "TLSRoute"
"backendTLS" false) }}
{{- end }}
@@ -0,0 +1,39 @@
{{- if and .Values.spiffe.rest.enabled .Values.spiffe.rest.ingress.enabled -}}
{{- $port := .Values.spiffe.rest.service.port }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.spiffe.rest.ingress) }}
{{- $fullName := printf "%s-rest-spiffe" (include "spire-identity-exchange.fullname" .) }}
{{- $path := "/" }}
{{- $pathType := "Prefix" }}
{{- $tlsSection := true }}
{{- $annotations := deepCopy .Values.spiffe.rest.ingress.annotations }}
{{- if eq $ingressControllerType "ingress-nginx" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/force-ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/backend-protocol" "HTTPS" }}
{{- if not .Values.spiffe.rest.ingress.tlsSecret }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-passthrough" "true" }}
{{- end }}
{{- else if eq $ingressControllerType "openshift" }}
{{- if .Values.spiffe.rest.ingress.tlsSecret }}
{{- $_ := set $annotations "route.openshift.io/termination" "reencrypt" }}
{{- else }}
{{- $_ := set $annotations "route.openshift.io/termination" "passthrough" }}
{{- end }}
{{- $path = "" }}
{{- $pathType = "ImplementationSpecific" }}
{{- $tlsSection = false }}
{{- end }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ include "spire-identity-exchange.namespace" . }}
labels:
{{ include "spire-identity-exchange.labels" . | nindent 4 }}
{{- with $annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{ include "spire-lib.ingress-spec" (dict "ingress" .Values.spiffe.rest.ingress "svcName" $fullName "port" $port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{- end }}
@@ -0,0 +1,23 @@
{{- if .Values.spiffe.rest.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "spire-identity-exchange.fullname" . }}-rest-spiffe
namespace: {{ include "spire-identity-exchange.namespace" . }}
{{- with .Values.spiffe.rest.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.spiffe.rest.service.type }}
{{- if and (eq .Values.spiffe.rest.service.type "LoadBalancer") .Values.spiffe.rest.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.spiffe.rest.service.loadBalancerIP }}
{{- end }}
ports:
- name: https
port: {{ .Values.spiffe.rest.service.port }}
targetPort: rest-spiffe
protocol: TCP
selector:
{{- include "spire-identity-exchange.selectorLabels" . | nindent 4 }}
{{- end }}
@@ -0,0 +1,14 @@
{{- if and .Values.tls.grpc.enabled .Values.tls.grpc.gatewayAPI.enabled -}}
{{- $fullName := printf "%s-grpc" (include "spire-identity-exchange.fullname" .) -}}
{{- $routeKind := include "spire-lib.gateway-route-kind" (dict "gatewayAPI" .Values.tls.grpc.gatewayAPI) -}}
{{- include "spire-lib.gateway-routes" (dict
"root" .
"gatewayAPI" .Values.tls.grpc.gatewayAPI
"name" $fullName
"namespace" (include "spire-identity-exchange.namespace" .)
"svcName" $fullName
"port" .Values.tls.grpc.service.port
"labels" (include "spire-identity-exchange.labels" .)
"routeKind" $routeKind
"backendTLS" (eq $routeKind "HTTPRoute")) }}
{{- end }}
@@ -1,20 +1,20 @@
{{- if .Values.grpc.ingress.enabled -}}
{{- $port := .Values.grpc.service.port }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.grpc.ingress) }}
{{- if and .Values.tls.grpc.enabled .Values.tls.grpc.ingress.enabled -}}
{{- $port := .Values.tls.grpc.service.port }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.tls.grpc.ingress) }}
{{- $fullName := printf "%s-grpc" (include "spire-identity-exchange.fullname" .) }}
{{- $path := "/" }}
{{- $pathType := "Prefix" }}
{{- $tlsSection := true }}
{{- $annotations := deepCopy .Values.grpc.ingress.annotations }}
{{- $annotations := deepCopy .Values.tls.grpc.ingress.annotations }}
{{- if eq $ingressControllerType "ingress-nginx" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/force-ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/backend-protocol" "HTTPS" }}
{{- if not (and .Values.grpc.ingress.enabled .Values.grpc.ingress.tlsSecret) }}
{{- if not .Values.tls.grpc.ingress.tlsSecret }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-passthrough" "true" }}
{{- end }}
{{- else if eq $ingressControllerType "openshift" }}
{{- if and .Values.grpc.ingress.enabled .Values.grpc.ingress.tlsSecret }}
{{- if .Values.tls.grpc.ingress.tlsSecret }}
{{- $_ := set $annotations "route.openshift.io/termination" "reencrypt" }}
{{- else }}
{{- $_ := set $annotations "route.openshift.io/termination" "passthrough" }}
@@ -35,5 +35,5 @@ metadata:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{ include "spire-lib.ingress-spec" (dict "ingress" .Values.grpc.ingress "svcName" $fullName "port" $port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{ include "spire-lib.ingress-spec" (dict "ingress" .Values.tls.grpc.ingress "svcName" $fullName "port" $port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{- end }}
@@ -1,21 +1,21 @@
{{- if .Values.grpc.enabled }}
{{- if .Values.tls.grpc.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "spire-identity-exchange.fullname" . }}-grpc
namespace: {{ include "spire-identity-exchange.namespace" . }}
{{- with .Values.service.annotations }}
{{- with .Values.tls.grpc.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.grpc.service.type }}
{{- if and (eq .Values.grpc.service.type "LoadBalancer") .Values.grpc.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.grpc.service.loadBalancerIP }}
type: {{ .Values.tls.grpc.service.type }}
{{- if and (eq .Values.tls.grpc.service.type "LoadBalancer") .Values.tls.grpc.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.tls.grpc.service.loadBalancerIP }}
{{- end }}
ports:
- name: https
port: {{ .Values.grpc.service.port }}
port: {{ .Values.tls.grpc.service.port }}
targetPort: grpc
protocol: TCP
selector:
@@ -0,0 +1,14 @@
{{- if and .Values.tls.rest.enabled .Values.tls.rest.gatewayAPI.enabled -}}
{{- $fullName := printf "%s-rest" (include "spire-identity-exchange.fullname" .) -}}
{{- $routeKind := include "spire-lib.gateway-route-kind" (dict "gatewayAPI" .Values.tls.rest.gatewayAPI) -}}
{{- include "spire-lib.gateway-routes" (dict
"root" .
"gatewayAPI" .Values.tls.rest.gatewayAPI
"name" $fullName
"namespace" (include "spire-identity-exchange.namespace" .)
"svcName" $fullName
"port" .Values.tls.rest.service.port
"labels" (include "spire-identity-exchange.labels" .)
"routeKind" $routeKind
"backendTLS" (eq $routeKind "HTTPRoute")) }}
{{- end }}
@@ -1,20 +1,20 @@
{{- if .Values.rest.ingress.enabled -}}
{{- $port := .Values.rest.service.port }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.rest.ingress) }}
{{- if and .Values.tls.rest.enabled .Values.tls.rest.ingress.enabled -}}
{{- $port := .Values.tls.rest.service.port }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.tls.rest.ingress) }}
{{- $fullName := printf "%s-rest" (include "spire-identity-exchange.fullname" .) }}
{{- $path := "/" }}
{{- $pathType := "Prefix" }}
{{- $tlsSection := true }}
{{- $annotations := deepCopy .Values.rest.ingress.annotations }}
{{- $annotations := deepCopy .Values.tls.rest.ingress.annotations }}
{{- if eq $ingressControllerType "ingress-nginx" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/force-ssl-redirect" "true" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/backend-protocol" "HTTPS" }}
{{- if not (and .Values.rest.ingress.enabled .Values.rest.ingress.tlsSecret) }}
{{- if not .Values.tls.rest.ingress.tlsSecret }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-passthrough" "true" }}
{{- end }}
{{- else if eq $ingressControllerType "openshift" }}
{{- if and .Values.rest.ingress.enabled .Values.rest.ingress.tlsSecret }}
{{- if .Values.tls.rest.ingress.tlsSecret }}
{{- $_ := set $annotations "route.openshift.io/termination" "reencrypt" }}
{{- else }}
{{- $_ := set $annotations "route.openshift.io/termination" "passthrough" }}
@@ -35,5 +35,5 @@ metadata:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{ include "spire-lib.ingress-spec" (dict "ingress" .Values.rest.ingress "svcName" $fullName "port" $port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{ include "spire-lib.ingress-spec" (dict "ingress" .Values.tls.rest.ingress "svcName" $fullName "port" $port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{- end }}
@@ -1,21 +1,21 @@
{{- if .Values.rest.enabled }}
{{- if .Values.tls.rest.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "spire-identity-exchange.fullname" . }}-rest
namespace: {{ include "spire-identity-exchange.namespace" . }}
{{- with .Values.rest.service.annotations }}
{{- with .Values.tls.rest.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.rest.service.type }}
{{- if and (eq .Values.rest.service.type "LoadBalancer") .Values.rest.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.rest.service.loadBalancerIP }}
type: {{ .Values.tls.rest.service.type }}
{{- if and (eq .Values.tls.rest.service.type "LoadBalancer") .Values.tls.rest.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.tls.rest.service.loadBalancerIP }}
{{- end }}
ports:
- name: https
port: {{ .Values.rest.service.port }}
port: {{ .Values.tls.rest.service.port }}
targetPort: rest
protocol: TCP
selector: