Merge branch 'main' into release

This commit is contained in:
Faisal Memon
2024-03-04 09:54:53 -08:00
39 changed files with 971 additions and 115 deletions
+5 -5
View File
@@ -2,26 +2,26 @@
{
"name": "kube-prometheus-stack",
"repo": "https://prometheus-community.github.io/helm-charts",
"version": "56.6.2"
"version": "56.20.0"
},
{
"name": "cert-manager",
"repo": "https://charts.jetstack.io",
"version": "v1.14.1"
"version": "v1.14.3"
},
{
"name": "ingress-nginx",
"repo": "https://kubernetes.github.io/ingress-nginx",
"version": "4.9.1"
"version": "4.10.0"
},
{
"name": "mysql",
"repo": "https://charts.bitnami.com/bitnami",
"version": "9.19.1"
"version": "9.22.0"
},
{
"name": "postgresql",
"repo": "https://charts.bitnami.com/bitnami",
"version": "14.0.1"
"version": "14.2.3"
}
]
+1 -1
View File
@@ -61,7 +61,7 @@ jobs:
- name: Create Pull Request
id: cpr
uses: peter-evans/[email protected].0
uses: peter-evans/[email protected].1
with:
token: ${{ secrets.GITHUB_TOKEN }}
title: Bump test chart dependencies
+29 -2
View File
@@ -45,7 +45,7 @@ jobs:
- name: Checkout
uses: actions/[email protected]
- id: set-matrix
- id: set-matrix-example
name: Collect all examples
run: |
examples="$(find examples -maxdepth 2 -type f -name run-tests.sh | xargs -I % dirname %)"
@@ -53,8 +53,17 @@ jobs:
echo "${examples_json}"
echo "examples=$examples_json" >>"$GITHUB_OUTPUT"
- id: set-matrix-integration
name: Collect all integration tests
run: |
integrationtests="$(find tests/integration -maxdepth 2 -type f -name run-tests.sh | xargs -I % dirname %)"
integrationtests_json="$(echo "$integrationtests" | jq -c --slurp --raw-input 'split("\n") | map(select(. != ""))')"
echo "${integrationtests_json}"
echo "integrationtests=$integrationtests_json" >>"$GITHUB_OUTPUT"
outputs:
examples: ${{ steps.set-matrix.outputs.examples }}
examples: ${{ steps.set-matrix-example.outputs.examples }}
integrationtests: ${{ steps.set-matrix-integration.outputs.integrationtests }}
example-test:
runs-on: ubuntu-22.04
@@ -74,6 +83,24 @@ jobs:
steps:
- run: 'echo "Skipping example-test"'
integration-test:
runs-on: ubuntu-22.04
needs:
- build-matrix
strategy:
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
example:
- ${{ fromJson(needs.build-matrix.outputs.integrationtests) }}
steps:
- run: 'echo "Skipping integration-test"'
upgrade-test:
runs-on: ubuntu-22.04
+60 -5
View File
@@ -156,7 +156,7 @@ jobs:
version: ${{ env.CHART_TESTING_VERSION }}
- name: Create kind ${{ matrix.k8s }} cluster
uses: helm/kind-action@v1.8.0
uses: helm/kind-action@v1.9.0
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
@@ -187,7 +187,7 @@ jobs:
- name: Checkout
uses: actions/[email protected]
- id: set-matrix
- id: set-matrix-example
name: Collect all examples
run: |
examples="$(find examples -maxdepth 2 -type f -name run-tests.sh | xargs -I % dirname %)"
@@ -195,8 +195,17 @@ jobs:
echo "${examples_json}"
echo "examples=$examples_json" >>"$GITHUB_OUTPUT"
- id: set-matrix-integration
name: Collect all integration tests
run: |
integrationtests="$(find tests/integration -maxdepth 2 -type f -name run-tests.sh | xargs -I % dirname %)"
integrationtests_json="$(echo "$integrationtests" | jq -c --slurp --raw-input 'split("\n") | map(select(. != ""))')"
echo "${integrationtests_json}"
echo "integrationtests=$integrationtests_json" >>"$GITHUB_OUTPUT"
outputs:
examples: ${{ steps.set-matrix.outputs.examples }}
examples: ${{ steps.set-matrix-example.outputs.examples }}
integrationtests: ${{ steps.set-matrix-integration.outputs.integrationtests }}
example-test:
runs-on: ubuntu-22.04
@@ -230,7 +239,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: Create kind cluster
uses: helm/kind-action@v1.8.0
uses: helm/kind-action@v1.9.0
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
@@ -249,6 +258,52 @@ jobs:
fi
${{ matrix.example }}/run-tests.sh
integration-test:
runs-on: ubuntu-22.04
needs:
- lint-chart
- build-matrix
strategy:
fail-fast: false
matrix:
k8s:
- v1.28.0
- v1.27.3
- v1.26.6
integrationtest:
- ${{ fromJson(needs.build-matrix.outputs.integrationtests) }}
steps:
- name: Checkout
uses: actions/[email protected]
- name: Set up Helm
uses: azure/[email protected]
with:
version: ${{ env.HELM_VERSION }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Create kind cluster
uses: helm/[email protected]
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
node_image: kindest/node:v1.26.4
config: .github/kind/conf/kind-config.yaml
verbosity: 1
- name: Install and test integration
run: |
kubectl create namespace spire-server
helm install -n spire-server spire-crds charts/spire-crds
${{ matrix.integrationtest }}/run-tests.sh
upgrade-test:
runs-on: ubuntu-22.04
@@ -279,7 +334,7 @@ jobs:
python-version: ${{ env.PYTHON_VERSION }}
- name: Create kind cluster
uses: helm/kind-action@v1.8.0
uses: helm/kind-action@v1.9.0
# Only build a kind cluster if there are chart changes to test.
with:
version: ${{ env.KIND_VERSION }}
+2 -2
View File
@@ -3,8 +3,8 @@ name: spire
description: >
A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager.
type: application
version: 0.17.2
appVersion: "1.8.7"
version: 0.18.0
appVersion: "1.9.0"
keywords: ["spiffe", "spire", "spire-server", "spire-agent", "oidc", "spire-controller-manager"]
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
sources:
+14 -7
View File
@@ -1,6 +1,6 @@
# spire
![Version: 0.17.2](https://img.shields.io/badge/Version-0.17.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.8.7](https://img.shields.io/badge/AppVersion-1.8.7-informational?style=flat-square)
![Version: 0.18.0](https://img.shields.io/badge/Version-0.18.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 1.9.0](https://img.shields.io/badge/AppVersion-1.9.0-informational?style=flat-square)
[![Development Phase](https://github.com/spiffe/spiffe/blob/main/.img/maturity/dev.svg)](https://github.com/spiffe/spiffe/blob/main/MATURITY.md#development)
A Helm chart for deploying the complete Spire stack including: spire-server, spire-agent, spiffe-csi-driver, spiffe-oidc-discovery-provider and spire-controller-manager.
@@ -34,12 +34,10 @@ global:
# Update these
clusterName: example-cluster
trustDomain: example.org
spire-server:
ca_subject:
# Update these
country: ARPA
organization: Example
common_name: example.org
caSubject:
country: ARPA
organization: Example
commonName: example.org
```
2. If you need a non default storageClass, append the following to the spire-server section and update:
@@ -77,6 +75,11 @@ kubectl delete crds clusterfederatedtrustdomains.spire.spiffe.io clusterspiffeid
We only support upgrading one major version at a time. Version skipping isn't supported.
### 0.18.x
- SPIRE no longer emits x509UniqueIdentifiers in x509-SVIDS by default. The old behavior can be reenabled with spire-server.credentialComposer.uniqueID.enabled=true. See https://github.com/spiffe/spire/pull/4862 for details.
- SPIRE agents will now automatically reattest when they can. The old behavior can be reenabled with spire-agent.disableReattestToRenew=true. See https://github.com/spiffe/spire/pull/4791 for details.
### 0.17.X
- If you set spire-server.replicaCount > 1, update it to 1 before upgrading and after upgrade you can set it back to its previous value.
@@ -209,6 +212,9 @@ Now you can interact with the Spire agent socket from your own application. The
| `global.spire.jwtIssuer` | The issuer for Spire JWT tokens. Defaults to oidc-discovery.$trustDomain if unset | `""` |
| `global.spire.trustDomain` | The trust domain for Spire install | `example.org` |
| `global.spire.upstreamServerAddress` | Set what address to use for the upstream server when using nested spire | `""` |
| `global.spire.caSubject.country` | Country for Spire server CA | `""` |
| `global.spire.caSubject.organization` | Organization for Spire server CA | `""` |
| `global.spire.caSubject.commonName` | Common Name for Spire server CA | `""` |
| `global.spire.recommendations.enabled` | Use recommended settings for production deployments. Default is off. | `false` |
| `global.spire.recommendations.namespaceLayout` | Set to true to use recommended values for installing across namespaces | `true` |
| `global.spire.recommendations.namespacePSS` | When chart namespace creation is enabled, label them with preffered Pod Security Standard labels | `true` |
@@ -228,6 +234,7 @@ Now you can interact with the Spire agent socket from your own application. The
| `global.spire.namespaces.server.labels` | Labels to apply to the Spire server Namespace. | `{}` |
| `global.spire.strictMode` | Check values, such as trustDomain, are overridden with a suitable value for production. | `false` |
| `global.spire.ingressControllerType` | Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""]. | `""` |
| `global.spire.tools.kubectl.tag` | Set to force the tag to use for all kubectl instances | `""` |
| `global.installAndUpgradeHooks.enabled` | Enable Helm hooks to autofix common install/upgrade issues (should be disabled when using `helm template`) | `true` |
| `global.deleteHooks.enabled` | Enable Helm hooks to autofix common delete issues (should be disabled when using `helm template`) | `true` |
+47 -44
View File
@@ -25,47 +25,50 @@ A Helm chart to install the SPIFFE CSI driver.
### SPIFFE CSI Driver Chart parameters
| Name | Description | Value |
| ---------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `pluginName` | Set the csi driver name deployed to Kubernetes. | `csi.spiffe.io` |
| `image.registry` | The OCI registry to pull the image from | `ghcr.io` |
| `image.repository` | The repository within the registry | `spiffe/spiffe-csi-driver` |
| `image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
| `resources` | Resource requests and limits for spiffe-csi-driver | `{}` |
| `healthChecks.port` | The healthcheck port for spiffe-csi-driver | `9809` |
| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` |
| `livenessProbe.timeoutSeconds` | Timeout value in seconds for livenessProbe | `5` |
| `imagePullSecrets` | Image pull secret details for spiffe-csi-driver | `[]` |
| `nameOverride` | Name override for spiffe-csi-driver | `""` |
| `namespaceOverride` | Namespace to install spiffe-csi-driver | `""` |
| `fullnameOverride` | Full name override for spiffe-csi-driver | `""` |
| `csiDriverLabels` | Labels to apply to the CSIDriver | `{}` |
| `initContainers` | Init Containers to apply to the CSI Driver DaemonSet | `[]` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated. | `""` |
| `podAnnotations` | Pod annotations for spiffe-csi-driver | `{}` |
| `podSecurityContext` | Security context for CSI driver pods | `{}` |
| `securityContext.readOnlyRootFilesystem` | Flag for read only root filesystem | `true` |
| `securityContext.privileged` | Flag for specifying privileged mode | `true` |
| `nodeSelector` | Node selector for CSI driver pods | `{}` |
| `tolerations` | Tolerations for CSI driver pods | `[]` |
| `affinity` | Node affinity | `{}` |
| `nodeDriverRegistrar.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` |
| `nodeDriverRegistrar.image.repository` | The repository within the registry | `sig-storage/csi-node-driver-registrar` |
| `nodeDriverRegistrar.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeDriverRegistrar.image.tag` | Overrides the image tag | `v2.9.3` |
| `nodeDriverRegistrar.resources` | Resource requests and limits for CSI driver pods | `{}` |
| `agentSocketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` |
| `kubeletPath` | Path to kubelet file | `/var/lib/kubelet` |
| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
| `restrictedScc.enabled` | Enables the creation of a SecurityContextConstraint based on the restricted SCC with CSI volume support | `false` |
| `restrictedScc.name` | Set the name of the restricted SCC with CSI support | `""` |
| `restrictedScc.version` | Version of the restricted SCC | `2` |
| `selinux.enabled` | Enable selinux support | `false` |
| `selinux.context` | Which selinux context to use | `container_file_t` |
| `selinux.image.registry` | The OCI registry to pull the image from | `registry.access.redhat.com` |
| `selinux.image.repository` | The repository within the registry | `ubi9` |
| `selinux.image.pullPolicy` | The image pull policy | `Always` |
| `selinux.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest` |
| Name | Description | Value |
| --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| `pluginName` | Set the csi driver name deployed to Kubernetes. | `csi.spiffe.io` |
| `image.registry` | The OCI registry to pull the image from | `ghcr.io` |
| `image.repository` | The repository within the registry | `spiffe/spiffe-csi-driver` |
| `image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `image.tag` | Overrides the image tag whose default is the chart appVersion | `""` |
| `resources` | Resource requests and limits for spiffe-csi-driver | `{}` |
| `healthChecks.port` | The healthcheck port for spiffe-csi-driver | `9809` |
| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` |
| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` |
| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` |
| `livenessProbe.timeoutSeconds` | Timeout value in seconds for livenessProbe | `5` |
| `imagePullSecrets` | Image pull secret details for spiffe-csi-driver | `[]` |
| `nameOverride` | Name override for spiffe-csi-driver | `""` |
| `namespaceOverride` | Namespace to install spiffe-csi-driver | `""` |
| `fullnameOverride` | Full name override for spiffe-csi-driver | `""` |
| `csiDriverLabels` | Labels to apply to the CSIDriver | `{}` |
| `initContainers` | Init Containers to apply to the CSI Driver DaemonSet | `[]` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated. | `""` |
| `podAnnotations` | Pod annotations for spiffe-csi-driver | `{}` |
| `podSecurityContext` | Security context for CSI driver pods | `{}` |
| `securityContext.readOnlyRootFilesystem` | Flag for read only root filesystem | `true` |
| `securityContext.privileged` | Flag for specifying privileged mode | `true` |
| `nodeSelector` | Node selector for CSI driver pods | `{}` |
| `tolerations` | Tolerations for CSI driver pods | `[]` |
| `affinity` | Node affinity | `{}` |
| `nodeDriverRegistrar.image.registry` | The OCI registry to pull the image from | `registry.k8s.io` |
| `nodeDriverRegistrar.image.repository` | The repository within the registry | `sig-storage/csi-node-driver-registrar` |
| `nodeDriverRegistrar.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeDriverRegistrar.image.tag` | Overrides the image tag | `v2.9.3` |
| `nodeDriverRegistrar.resources` | Resource requests and limits for CSI driver pods | `{}` |
| `agentSocketPath` | The unix socket path to the spire-agent | `/run/spire/agent-sockets/spire-agent.sock` |
| `kubeletPath` | Path to kubelet file | `/var/lib/kubelet` |
| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
| `restrictedScc.enabled` | Enables the creation of a SecurityContextConstraint based on the restricted SCC with CSI volume support | `false` |
| `restrictedScc.name` | Set the name of the restricted SCC with CSI support | `""` |
| `restrictedScc.version` | Version of the restricted SCC | `2` |
| `selinux.enabled` | Enable selinux support | `false` |
| `selinux.context` | Which selinux context to use | `container_file_t` |
| `selinux.image.registry` | The OCI registry to pull the image from | `registry.access.redhat.com` |
| `selinux.image.repository` | The repository within the registry | `ubi9` |
| `selinux.image.pullPolicy` | The image pull policy | `Always` |
| `selinux.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest` |
@@ -9,8 +9,17 @@ spec:
selector:
matchLabels:
{{- include "spiffe-csi-driver.selectorLabels" . | nindent 6 }}
{{- with .Values.updateStrategy }}
updateStrategy:
type: RollingUpdate
{{- if not (has .type (list "RollingUpdate" "OnDelete")) }}
{{- fail "updateStrategy.type can only be RollingUpdate or OnDelete"}}
{{- end }}
type: {{ .type }}
{{- if eq .type "RollingUpdate" }}
rollingUpdate:
maxUnavailable: {{ .rollingUpdate.maxUnavailable }}
{{- end }}
{{- end }}
template:
metadata:
{{- with .Values.podAnnotations }}
@@ -37,6 +37,13 @@ healthChecks:
## @param healthChecks.port The healthcheck port for spiffe-csi-driver
port: 9809
## @param updateStrategy.type The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete.
## @param updateStrategy.rollingUpdate.maxUnavailable Max unavailable pods during update. Can be a number or a percentage.
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe
## @param livenessProbe.timeoutSeconds Timeout value in seconds for livenessProbe
##
@@ -3,7 +3,7 @@ name: spiffe-oidc-discovery-provider
description: A Helm chart to install the SPIFFE OIDC discovery provider.
type: application
version: 0.1.0
appVersion: "1.8.7"
appVersion: "1.9.0"
keywords: ["spiffe", "oidc"]
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
sources:
@@ -69,7 +69,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider.
| `insecureScheme.nginx.image.registry` | The OCI registry to pull the image from. Only used when TLS is disabled. | `docker.io` |
| `insecureScheme.nginx.image.repository` | The repository within the registry. Only used when TLS is disabled. | `nginxinc/nginx-unprivileged` |
| `insecureScheme.nginx.image.pullPolicy` | The image pull policy. Only used when TLS is disabled. | `IfNotPresent` |
| `insecureScheme.nginx.image.tag` | Overrides the image tag whose default is the chart appVersion. Only used when TLS is disabled. | `1.25.3-alpine` |
| `insecureScheme.nginx.image.tag` | Overrides the image tag whose default is the chart appVersion. Only used when TLS is disabled. | `1.25.4-alpine` |
| `insecureScheme.nginx.resources` | Resource requests and limits | `{}` |
| `jwtIssuer` | Path to JWT issuer. Defaults to oidc-discovery.$trustDomain if unset | `""` |
| `config.logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` |
@@ -115,11 +115,11 @@ A Helm chart to install the SPIFFE OIDC discovery provider.
| `tests.bash.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` |
| `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f` |
| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669` |
| `tests.toolkit.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `tests.toolkit.image.repository` | The repository within the registry | `chainguard/slim-toolkit-debug` |
| `tests.toolkit.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:9198d9e7e83ab4078df6f53dfa3e8e1e8f60d5718cc21fefa2ccb6604283e049` |
| `tests.toolkit.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:606810cf1076a226dfb85fa4102ee0ed2d8e2b7c7a8a2a53f9788c65501ecca8` |
| `tests.step.image.registry` | The OCI registry to pull the image from | `docker.io` |
| `tests.step.image.repository` | The repository within the registry | `smallstep/step-cli` |
| `tests.step.image.pullPolicy` | The image pull policy | `IfNotPresent` |
@@ -164,7 +164,7 @@ insecureScheme:
registry: docker.io
repository: nginxinc/nginx-unprivileged
pullPolicy: IfNotPresent
tag: 1.25.3-alpine
tag: 1.25.4-alpine
## @param insecureScheme.nginx.resources Resource requests and limits
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
@@ -328,7 +328,7 @@ tests:
registry: cgr.dev
repository: chainguard/bash
pullPolicy: IfNotPresent
tag: latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f
tag: latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669
toolkit:
## @param tests.toolkit.image.registry The OCI registry to pull the image from
@@ -340,7 +340,7 @@ tests:
registry: cgr.dev
repository: chainguard/slim-toolkit-debug
pullPolicy: IfNotPresent
tag: latest@sha256:9198d9e7e83ab4078df6f53dfa3e8e1e8f60d5718cc21fefa2ccb6604283e049
tag: latest@sha256:606810cf1076a226dfb85fa4102ee0ed2d8e2b7c7a8a2a53f9788c65501ecca8
step:
## @param tests.step.image.registry The OCI registry to pull the image from
+1 -1
View File
@@ -3,7 +3,7 @@ name: spire-agent
description: A Helm chart to install the SPIRE agent.
type: application
version: 0.1.0
appVersion: "1.8.7"
appVersion: "1.9.0"
keywords: ["spiffe", "spire-agent"]
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
sources:
+23 -3
View File
@@ -40,12 +40,14 @@ A Helm chart to install the SPIRE agent.
| `serviceAccount.name` | The name of the service account to use. | `""` |
| `configMap.annotations` | Annotations to add to the SPIRE Agent ConfigMap | `{}` |
| `podAnnotations` | Annotations to add to pods | `{}` |
| `podLabels` | Labels to add to pods | `{}` |
| `podSecurityContext` | Pod security context | `{}` |
| `securityContext` | Security context | `{}` |
| `resources` | Resource requests and limits | `{}` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | List of tolerations | `[]` |
| `affinity` | Node affinity | `{}` |
| `authorizedDelegates` | A list of the authorized delegates SPIFFE IDs. See Delegated Identity API for more information. | `[]` |
| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` |
| `clusterName` | The name of the Kubernetes cluster (`kubeadm init --service-dns-domain`) | `example-cluster` |
| `trustDomain` | The trust domain to be used for the SPIFFE identifiers | `example.org` |
@@ -53,10 +55,13 @@ A Helm chart to install the SPIRE agent.
| `trustBundleFormat` | If using trustBundleURL, what format is the url. Choices are "pem" and "spiffe" | `pem` |
| `bundleConfigMap` | Configmap name for Spire bundle | `spire-bundle` |
| `availabilityTarget` | The minimum amount of time desired to gracefully handle SPIRE Server or Agent downtime. This configurable influences how aggressively X509 SVIDs should be rotated. If set, must be at least 24h. | `""` |
| `disableReattestToRenew` | Deprecated: Allow agent to renew certificate when it expires rather than reattest | `false` |
| `server.address` | Address for Spire server | `""` |
| `server.port` | Port number for Spire server | `8081` |
| `server.namespaceOverride` | Override the namespace for Spire server | `""` |
| `healthChecks.port` | override the host port used for health checking | `9982` |
| `updateStrategy.type` | The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete. | `RollingUpdate` |
| `updateStrategy.rollingUpdate.maxUnavailable` | Max unavailable pods during update. Can be a number or a percentage. | `1` |
| `livenessProbe.initialDelaySeconds` | Initial delay seconds for probe | `15` |
| `livenessProbe.periodSeconds` | Period seconds for probe | `60` |
| `readinessProbe.initialDelaySeconds` | Initial delay seconds for probe | `10` |
@@ -64,15 +69,27 @@ A Helm chart to install the SPIRE agent.
| `waitForIt.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `waitForIt.image.repository` | The repository within the registry | `chainguard/wait-for-it` |
| `waitForIt.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:64ba1b49313924643dec6a03e15a1c6cfc24046cff96b0b3c0003cabbad2f60d` |
| `waitForIt.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:caead414307e81dbdd86d30662fdfe1b999dd4ce8a10fa667dab3438d0eed193` |
| `waitForIt.resources` | Resource requests and limits | `{}` |
| `fsGroupFix.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `fsGroupFix.image.repository` | The repository within the registry | `chainguard/bash` |
| `fsGroupFix.image.pullPolicy` | The image pull policy | `Always` |
| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f` |
| `fsGroupFix.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669` |
| `fsGroupFix.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` |
| `keyManager.memory.enabled` | Enable the memory based Key Manager | `true` |
| `nodeAttestor.k8sPsat.enabled` | Enable Psat k8s Node Attestor | `true` |
| `nodeAttestor.tpmDirect.enabled` | Enable the direct TPM node attestor, a 3rd party plugin by Boxboat. This plugin is experimental. | `false` |
| `nodeAttestor.tpmDirect.plugin.image.registry` | The OCI registry to pull the image from | `docker.io` |
| `nodeAttestor.tpmDirect.plugin.image.repository` | The repository within the registry | `boxboat/spire-tpm-plugin-tpm-attestor-agent` |
| `nodeAttestor.tpmDirect.plugin.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeAttestor.tpmDirect.plugin.image.tag` | Overrides the image tag | `v1.8.7` |
| `nodeAttestor.tpmDirect.plugin.checksum` | The sha256 checksum of the plugin binary | `1d7c73ccac948ee86cbd78ddde2d30128a1838b403f7bb2100d38d916a252244` |
| `nodeAttestor.tpmDirect.plugin.path` | The filename in the container of the plugin | `/app/tpm_attestor_agent` |
| `nodeAttestor.tpmDirect.pubHash.enabled` | Enable Psat k8s nodeattestor | `true` |
| `nodeAttestor.tpmDirect.pubHash.image.registry` | The OCI registry to pull the image from | `docker.io` |
| `nodeAttestor.tpmDirect.pubHash.image.repository` | The repository within the registry | `boxboat/spire-tpm-plugin-get-tpm-pubhash` |
| `nodeAttestor.tpmDirect.pubHash.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeAttestor.tpmDirect.pubHash.image.tag` | Overrides the image tag | `v1.8.7` |
| `workloadAttestors.unix.enabled` | Enables the Unix workload attestor | `false` |
| `workloadAttestors.k8s.enabled` | Enables the Kubernetes workload attestor | `true` |
| `workloadAttestors.k8s.skipKubeletVerification` | If true, kubelet certificate verification is skipped | `true` |
@@ -93,7 +110,7 @@ A Helm chart to install the SPIRE agent.
| `socketAlternate.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `socketAlternate.image.repository` | The repository within the registry | `chainguard/bash` |
| `socketAlternate.image.pullPolicy` | The image pull policy | `Always` |
| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:07d2662ef699e9ceafab3f39624083193dfcb7b768ee86860dbdd5cb4473dcea` |
| `socketAlternate.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669` |
| `socketAlternate.resources` | Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ | `{}` |
| `priorityClassName` | Priority class assigned to daemonset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
| `extraEnvVars` | Extra environment variables to be added to the Spire Agent container | `[]` |
@@ -109,3 +126,6 @@ A Helm chart to install the SPIRE agent.
| `experimental.enabled` | Allow configuration of experimental features | `false` |
| `experimental.syncInterval` | Sync interval with SPIRE server with exponential backoff | `5s` |
| `experimental.featureFlags` | List of developer feature flags | `[]` |
| `sockets.hostBasePath` | Path on which the agent socket is made available when admin.mountOnHost is true | `/run/spire/agent/sockets` |
| `sockets.admin.enabled` | Enable the admin socket. Useful for admin tasks or the Delegated Identity API. | `false` |
| `sockets.admin.mountOnHost` | Enable the admin socket to be visible on the host. | `false` |
@@ -18,8 +18,21 @@
{{- end }}
{{- end }}
{{- end }}
{{- if hasPrefix (.Values.socketPath | dir | clean) (.Values.sockets.hostBasePath | clean) }}
{{- fail "The sockets.hostBasePath can not be located under the socketPath direcotry" }}
{{- end }}
{{- define "spire-agent.yaml-config" -}}
agent:
{{- if .Values.disableReattestToRenew }}
disable_reattest_to_renew: true
{{- end }}
{{- if .Values.sockets.admin.enabled }}
admin_socket_dir: /tmp/spire-agent/private/admin.sock
{{- end }}
{{- with .Values.authorizedDelegates }}
authorized_delegates:
{{- toYaml . | nindent 4 }}
{{- end }}
data_dir: "/run/spire"
log_level: {{ .Values.logLevel | quote }}
server_address: {{ include "spire-agent.server-address" . | trim | quote }}
@@ -66,6 +79,15 @@ plugins:
cluster: {{ include "spire-lib.cluster-name" . | quote }}
{{- $nodeAttestorUsed = add1 $nodeAttestorUsed }}
{{- end }}
{{- with .Values.nodeAttestor.tpmDirect }}
{{- if eq (.enabled | toString) "true" }}
tpm:
plugin_cmd: "/tpm/tpm_attestor_agent"
plugin_checksum: {{ .plugin.checksum }}
plugin_data: {}
{{- $nodeAttestorUsed = add1 $nodeAttestorUsed }}
{{- end }}
{{- end }}
{{- if ne $nodeAttestorUsed 1 }}
{{- fail (printf "You have to enable exactly one Node Attestor. There are %d enabled." $nodeAttestorUsed) }}
{{- end }}
@@ -1,5 +1,10 @@
{{- $configSum := (include (print $.Template.BasePath "/configmap.yaml") . | sha256sum) }}
{{- $podSecurityContext := fromYaml (include "spire-lib.podsecuritycontext" .) }}
{{- $mainSecurityContext := deepCopy .Values.securityContext }}
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
{{- $podSecurityContext = mergeOverwrite (dict "runAsUser" 0 "runAsGroup" 0) .Values.podSecurityContext }}
{{- $_ := set $mainSecurityContext "privileged" true }}
{{- end }}
{{- $cbh := eq (include "spire-agent.connect-by-hostname" .) "true" }}
{{- $socketAlternateNames := index (include "spire-agent.socket-alternate-names" . | fromYaml) "names" }}
{{- $socketPath := include "spire-agent.socket-path" . }}
@@ -14,6 +19,17 @@ spec:
selector:
matchLabels:
{{- include "spire-agent.selectorLabels" . | nindent 6 }}
{{- with .Values.updateStrategy }}
updateStrategy:
{{- if not (has .type (list "RollingUpdate" "OnDelete")) }}
{{- fail "updateStrategy.type can only be RollingUpdate or OnDelete"}}
{{- end }}
type: {{ .type }}
{{- if eq .type "RollingUpdate" }}
rollingUpdate:
maxUnavailable: {{ .rollingUpdate.maxUnavailable }}
{{- end }}
{{- end }}
template:
metadata:
annotations:
@@ -24,6 +40,9 @@ spec:
{{- end }}
labels:
{{- include "spire-agent.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
@@ -41,6 +60,47 @@ spec:
{{- toYaml .Values.hostAliases | nindent 8 }}
{{- end }}
initContainers:
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
{{- if .Values.nodeAttestor.tpmDirect.pubHash.enabled }}
- name: fingerprint-tpm
securityContext:
{{- $mainSecurityContext | toYaml | nindent 12 }}
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.nodeAttestor.tpmDirect.pubHash.image "global" .Values.global) }}
command:
- sh
- -c
- |
# Fetch the TPM's fingerprint from the TPM and output it on the Computers Console. This enables secure bootstrapping of the Node with the Server.
TPM=`/app/get_tpm_pubhash 2> /dev/null`
if [ $? -eq 0 ]; then
echo "TPM Fingerprint: $TPM"
(echo -n '<1>'; echo "TPM Fingerprint: $TPM") | tee /dev/kmsg
else
/app/get_tpm_pubhash
fi
volumeMounts:
- name: tpm
mountPath: /dev/tpmrm0
readOnly: true
- name: kmsg
mountPath: /dev/kmsg
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.pubHash.image.pullPolicy }}
{{- end }}
- name: init-tpm-direct
securityContext:
{{- .Values.securityContext | toYaml | nindent 12 }}
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.nodeAttestor.tpmDirect.plugin.image "global" .Values.global) }}
command:
- sh
- -ec
- |
# SPIRE must be able to fork the plugin directly within its container. Copy the plugin into a volume that can be mounted where SPIRE can execute it.
cp -a {{ .Values.nodeAttestor.tpmDirect.plugin.path }} /tpm/tpm_attestor_agent
volumeMounts:
- name: tpm-direct
mountPath: /tpm
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.plugin.image.pullPolicy }}
{{- end }}
- name: init
# This is a small image with wait-for-it, choose whatever image
# you prefer that waits for a service to be up. This image is built
@@ -48,16 +108,18 @@ spec:
image: {{ template "spire-lib.image" (dict "image" .Values.waitForIt.image "global" .Values.global) }}
imagePullPolicy: {{ .Values.waitForIt.image.pullPolicy }}
args: ["-t", "30", "-h", "{{ include "spire-agent.server-address" . | trim }}", "-p", {{ .Values.server.port | quote }}]
securityContext:
{{- .Values.securityContext | toYaml | nindent 12 }}
resources:
{{- toYaml .Values.waitForIt.resources | nindent 12 }}
securityContext:
{{ toYaml .Values.securityContext | nindent 12 }}
{{- toYaml .Values.securityContext | nindent 12 }}
{{- if gt (len $socketAlternateNames) 0 }}
- name: ensure-alternate-names
image: {{ template "spire-lib.image" (dict "image" .Values.socketAlternate.image "global" .Values.global) }}
imagePullPolicy: {{ .Values.socketAlternate.image.pullPolicy }}
command: ["bash", "-xc"]
{{/* 1. Look for symlinks pointing at the wrong place and remove them. 2. Make symlinks that don't exist. 3. If new socket is pointing at an existing symlink, remove old symlink. */}}
{{- /* 1. Look for symlinks pointing at the wrong place and remove them. 2. Make symlinks that don't exist. 3. If new socket is pointing at an existing symlink, remove old symlink. */}}
args:
- |
cd {{ $socketPath | dir }}
@@ -83,12 +145,14 @@ spec:
imagePullPolicy: {{ .Values.fsGroupFix.image.pullPolicy }}
command: ["bash", "-c"]
args:
- "chown -R {{ $podSecurityContext.runAsUser }}:{{ $podSecurityContext.fsGroup }} {{ $socketPath | dir }}"
- "chown -R {{ $podSecurityContext.runAsUser }}:{{ $podSecurityContext.fsGroup }} {{ $socketPath | dir }} /tmp/spire-agent/private"
resources:
{{- toYaml .Values.fsGroupFix.resources | nindent 12 }}
volumeMounts:
- name: spire-agent-socket-dir
mountPath: {{ $socketPath | dir }}
- name: spire-agent-admin-socket-dir
mountPath: /tmp/spire-agent/private
securityContext:
runAsUser: 0
runAsGroup: 0
@@ -102,7 +166,7 @@ spec:
imagePullPolicy: {{ .Values.image.pullPolicy }}
args: ["-config", "/opt/spire/conf/agent/agent.conf"]
securityContext:
{{ toYaml .Values.securityContext | nindent 12 }}
{{- $mainSecurityContext | toYaml | nindent 12 }}
env:
- name: PATH
value: "/opt/spire/bin:/bin"
@@ -126,11 +190,24 @@ spec:
- name: spire-config
mountPath: /opt/spire/conf/agent
readOnly: true
{{- if .Values.sockets.admin.enabled }}
- name: spire-agent-admin-socket-dir
mountPath: /tmp/spire-agent/private
readOnly: false
{{- end }}
{{- if eq (len .Values.trustBundleURL) 0 }}
- name: spire-bundle
mountPath: /run/spire/bundle
readOnly: true
{{- end }}
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
- name: tpm-direct
mountPath: /tpm
readOnly: true
- name: tpm
mountPath: /dev/tpmrm0
readOnly: true
{{- end }}
- name: spire-agent-socket-dir
mountPath: /tmp/spire-agent/public
readOnly: false
@@ -170,11 +247,24 @@ spec:
- name: spire-config
configMap:
name: {{ include "spire-agent.fullname" . }}
{{- if .Values.sockets.admin.mountOnHost }}
- name: spire-agent-admin-socket-dir
hostPath:
hostPath: {{ .Values.sockets.hostBasePath }}/{{ if .Values.upstream }}upstream.csi.spiffe.io{{ else }}csi.spiffe.io{{ end }}/admin
type: DirectoryOrCreate
{{- else }}
- name: spire-agent-admin-socket-dir
emptyDir: {}
{{- end }}
{{- if eq (len .Values.trustBundleURL) 0 }}
- name: spire-bundle
configMap:
name: {{ include "spire-lib.bundle-configmap" . }}
{{- end }}
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
- name: tpm-direct
emptyDir: {}
{{- end }}
- name: spire-token
projected:
sources:
@@ -186,6 +276,16 @@ spec:
hostPath:
path: {{ $socketPath | dir }}
type: DirectoryOrCreate
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
- name: tpm
hostPath:
path: /dev/tpmrm0
type: CharDevice
- name: kmsg
hostPath:
path: /dev/kmsg
type: CharDevice
{{- end }}
{{- if gt (len .Values.extraVolumes) 0 }}
{{- toYaml .Values.extraVolumes | nindent 8 }}
{{- end }}
@@ -17,6 +17,7 @@ volumes:
- hostPath
- projected
- secret
- emptyDir
allowHostDirVolumePlugin: true
allowHostIPC: true
allowHostNetwork: true
+58 -3
View File
@@ -45,6 +45,9 @@ configMap:
## @param podAnnotations [object] Annotations to add to pods
podAnnotations: {}
## @param podLabels [object] Labels to add to pods
podLabels: {}
## @param podSecurityContext [object] Pod security context
podSecurityContext: {}
# fsGroup: 2000
@@ -80,6 +83,8 @@ tolerations: []
## @param affinity [object] Node affinity
affinity: {}
## @param authorizedDelegates A list of the authorized delegates SPIFFE IDs. See Delegated Identity API for more information.
authorizedDelegates: []
## @param logLevel The log level, valid values are "debug", "info", "warn", and "error"
logLevel: info
## @param clusterName The name of the Kubernetes cluster (`kubeadm init --service-dns-domain`)
@@ -95,6 +100,9 @@ bundleConfigMap: spire-bundle
## @param availabilityTarget The minimum amount of time desired to gracefully handle SPIRE Server or Agent downtime. This configurable influences how aggressively X509 SVIDs should be rotated. If set, must be at least 24h.
availabilityTarget: ""
## @param disableReattestToRenew Deprecated: Allow agent to renew certificate when it expires rather than reattest
disableReattestToRenew: false
## @skip upstream
upstream: false
@@ -111,6 +119,13 @@ healthChecks:
## @param healthChecks.port override the host port used for health checking
port: 9982
## @param updateStrategy.type The update strategy to use to replace existing DaemonSet pods with new pods. Can be RollingUpdate or OnDelete.
## @param updateStrategy.rollingUpdate.maxUnavailable Max unavailable pods during update. Can be a number or a percentage.
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
## @param livenessProbe.initialDelaySeconds Initial delay seconds for probe
## @param livenessProbe.periodSeconds Period seconds for probe
##
@@ -135,7 +150,7 @@ waitForIt:
registry: cgr.dev
repository: chainguard/wait-for-it
pullPolicy: IfNotPresent
tag: latest@sha256:64ba1b49313924643dec6a03e15a1c6cfc24046cff96b0b3c0003cabbad2f60d
tag: latest@sha256:caead414307e81dbdd86d30662fdfe1b999dd4ce8a10fa667dab3438d0eed193
## @param waitForIt.resources [object] Resource requests and limits
resources: {}
@@ -152,7 +167,7 @@ fsGroupFix:
registry: cgr.dev
repository: chainguard/bash
pullPolicy: Always
tag: latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f
tag: latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669
## @param fsGroupFix.resources Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
resources: {}
@@ -166,6 +181,37 @@ nodeAttestor:
k8sPsat:
## @param nodeAttestor.k8sPsat.enabled Enable Psat k8s Node Attestor
enabled: true
tpmDirect:
## @param nodeAttestor.tpmDirect.enabled Enable the direct TPM node attestor, a 3rd party plugin by Boxboat. This plugin is experimental.
enabled: false
plugin:
## @param nodeAttestor.tpmDirect.plugin.image.registry The OCI registry to pull the image from
## @param nodeAttestor.tpmDirect.plugin.image.repository The repository within the registry
## @param nodeAttestor.tpmDirect.plugin.image.pullPolicy The image pull policy
## @param nodeAttestor.tpmDirect.plugin.image.tag Overrides the image tag
##
image:
registry: docker.io
repository: boxboat/spire-tpm-plugin-tpm-attestor-agent
pullPolicy: IfNotPresent
tag: "v1.8.7"
## @param nodeAttestor.tpmDirect.plugin.checksum The sha256 checksum of the plugin binary
checksum: 1d7c73ccac948ee86cbd78ddde2d30128a1838b403f7bb2100d38d916a252244
## @param nodeAttestor.tpmDirect.plugin.path The filename in the container of the plugin
path: /app/tpm_attestor_agent
pubHash:
## @param nodeAttestor.tpmDirect.pubHash.enabled Enable Psat k8s nodeattestor
enabled: true
## @param nodeAttestor.tpmDirect.pubHash.image.registry The OCI registry to pull the image from
## @param nodeAttestor.tpmDirect.pubHash.image.repository The repository within the registry
## @param nodeAttestor.tpmDirect.pubHash.image.pullPolicy The image pull policy
## @param nodeAttestor.tpmDirect.pubHash.image.tag Overrides the image tag
##
image:
registry: docker.io
repository: boxboat/spire-tpm-plugin-get-tpm-pubhash
pullPolicy: IfNotPresent
tag: "v1.8.7"
# workloadAttestors determine a workload's properties and then generate a set of selectors associated with it.
workloadAttestors:
@@ -229,7 +275,7 @@ socketAlternate:
registry: cgr.dev
repository: chainguard/bash
pullPolicy: Always
tag: latest@sha256:07d2662ef699e9ceafab3f39624083193dfcb7b768ee86860dbdd5cb4473dcea
tag: latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669
## @param socketAlternate.resources Specify resource needs as per https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
resources: {}
@@ -281,3 +327,12 @@ experimental:
syncInterval: 5s
## @param experimental.featureFlags [array] List of developer feature flags
featureFlags: []
sockets:
## @param sockets.hostBasePath Path on which the agent socket is made available when admin.mountOnHost is true
hostBasePath: /run/spire/agent/sockets
## @param sockets.admin.enabled Enable the admin socket. Useful for admin tasks or the Delegated Identity API.
## @param sockets.admin.mountOnHost Enable the admin socket to be visible on the host.
admin:
enabled: false
mountOnHost: false
+1 -1
View File
@@ -3,7 +3,7 @@ name: spire-server
description: A Helm chart to install the SPIRE server.
type: application
version: 0.1.0
appVersion: "1.8.7"
appVersion: "1.9.0"
keywords: ["spiffe", "spire-server", "spire-controller-manager"]
home: https://github.com/spiffe/helm-charts-hardened/tree/main/charts/spire
sources:
+19 -2
View File
@@ -95,6 +95,7 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated. | `""` |
| `podAnnotations` | Annotations to add to pods | `{}` |
| `podLabels` | Labels to add to pods | `{}` |
| `podSecurityContext` | Pod security context | `{}` |
| `securityContext` | Security context | `{}` |
| `priorityClassName` | Priority class assigned to statefulset pods. Can be auto set with global.recommendations.priorityClassName. | `""` |
@@ -133,6 +134,8 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `dataStore.sql.externalSecret.enabled` | Enable external secret for datastore creds | `false` |
| `dataStore.sql.externalSecret.name` | The name of the secret object | `""` |
| `dataStore.sql.externalSecret.key` | The key of the secret object whose value is the dataStore.sql password | `""` |
| `adminIDs` | SPIFFE IDs that, when present in a caller’s X509-SVID, grant that caller admin privileges. | `[]` |
| `auditLogEnabled` | If true, enables audit logging | `false` |
| `logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` |
| `jwtIssuer` | The JWT issuer domain. Defaults to oidc-discovery.$trustDomain if unset | `""` |
| `clusterName` | Set the name of the Kubernetes cluster. (`kubeadm init --service-dns-domain`) | `example-cluster` |
@@ -165,6 +168,7 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `ca_subject.country` | Country for Spire server CA | `ARPA` |
| `ca_subject.organization` | Organization for Spire server CA | `Example` |
| `ca_subject.common_name` | Common Name for Spire server CA | `example.org` |
| `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` |
| `keyManager.awsKMS.enabled` | Flag to enable keyManager in memory | `false` |
@@ -231,7 +235,7 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `controllerManager.image.registry` | The OCI registry to pull the image from | `ghcr.io` |
| `controllerManager.image.repository` | The repository within the registry | `spiffe/spire-controller-manager` |
| `controllerManager.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `controllerManager.image.tag` | Overrides the image tag whose default is the chart appVersion | `0.4.2` |
| `controllerManager.image.tag` | Overrides the image tag whose default is the chart appVersion | `0.4.3` |
| `controllerManager.resources` | Resource requests and limits for controller manager | `{}` |
| `controllerManager.securityContext` | Security context | `{}` |
| `controllerManager.service.type` | Service type for controller manager | `ClusterIP` |
@@ -239,6 +243,9 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `controllerManager.service.annotations` | Annotations for service resource | `{}` |
| `controllerManager.configMap.annotations` | Annotations to add to the Controller Manager ConfigMap | `{}` |
| `controllerManager.ignoreNamespaces` | These namespaces are ignored by controller manager | `[]` |
| `controllerManager.reconcile.clusterSPIFFEIDs` | Enable reconciliation of clusterSPIFFEIDs from K8s to the SPIRE server | `true` |
| `controllerManager.reconcile.clusterStaticEntries` | Enable reconciliation of clusterStaticEntries from K8s to the SPIRE server | `true` |
| `controllerManager.reconcile.clusterFederatedTrustDomains` | Enable reconciliation of clusterFederatedTrustDomains from K8s to the SPIRE server | `true` |
| `controllerManager.identities.clusterSPIFFEIDs.default.enabled` | Enable this identity for controller manager | `true` |
| `controllerManager.identities.clusterSPIFFEIDs.default.spiffeIDTemplate` | Spiffe ID template for identities | `spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}` |
| `controllerManager.identities.clusterSPIFFEIDs.default.podSelector` | Selector for pods to issue identity | `{}` |
@@ -290,6 +297,15 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `nodeAttestor.k8sPsat.enabled` | Enable Psat k8s nodeattestor | `true` |
| `nodeAttestor.k8sPsat.serviceAccountAllowList` | Allowed service accounts for Psat nodeattestor | `[]` |
| `nodeAttestor.joinToken.enabled` | Enable the join_token nodeattestor | `false` |
| `nodeAttestor.tpmDirect.enabled` | Enable the direct TPM node attestor, a 3rd party plugin by Boxboat. This plugin is experimental. | `false` |
| `nodeAttestor.tpmDirect.image.registry` | The OCI registry to pull the image from | `docker.io` |
| `nodeAttestor.tpmDirect.image.repository` | The repository within the registry | `boxboat/spire-tpm-plugin-tpm-attestor-server` |
| `nodeAttestor.tpmDirect.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `nodeAttestor.tpmDirect.image.tag` | Overrides the image tag | `v1.8.7` |
| `nodeAttestor.tpmDirect.checksum` | The sha256 checksum of the plugin binary | `f39ef9cdd2b3dd74112bfe827b79d6721c59215d0d5f4c2e34fa09bbc60d36d2` |
| `nodeAttestor.tpmDirect.pluginPath` | The filename in the container of the plugin | `/app/tpm_attestor_server` |
| `nodeAttestor.tpmDirect.cas` | A dictionary of TPM CA PEM or DER files that are allowed to connect. | `{}` |
| `nodeAttestor.tpmDirect.hashes` | A list of TPM hashes that are allowed to connect. | `[]` |
### Tornjak
@@ -327,6 +343,7 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `tornjak.resources` | Resource requests and limits | `{}` |
| `tornjak.securityContext` | Security Context to use | `{}` |
| `customPlugins.bundlePublisher` | Custom plugins of type BundlePublisher are configured here | `{}` |
| `customPlugins.credentialComposer` | Custom plugins of type CredentialComposer are configured here | `{}` |
| `customPlugins.keyManager` | Custom plugins of type KeyManager are configured here | `{}` |
| `customPlugins.nodeAttestor` | Custom plugins of type NodeAttestor are configured here | `{}` |
| `customPlugins.upstreamAuthority` | Custom plugins of type upstreamAuthority are configured here | `{}` |
@@ -340,4 +357,4 @@ In order to run Tornjak with simple HTTP Connection only, make sure you don't cr
| `tests.bash.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` |
| `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f` |
| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669` |
@@ -264,3 +264,18 @@ The code below determines what connection type should be used.
{{- .Release.Namespace }}-{{ default .Release.Name .Values.crNameOverride }}
{{- end -}}
{{- end -}}
{{- define "spire-server.ca-subject-country" }}
{{- $g := dig "spire" "caSubject" "country" "" .Values.global }}
{{- default .Values.ca_subject.country $g }}
{{- end }}
{{- define "spire-server.ca-subject-organization" }}
{{- $g := dig "spire" "caSubject" "organization" "" .Values.global }}
{{- default .Values.ca_subject.organization $g }}
{{- end }}
{{- define "spire-server.ca-subject-common-name" }}
{{- $g := dig "spire" "caSubject" "commonName" "" .Values.global }}
{{- default .Values.ca_subject.common_name $g }}
{{- end }}
@@ -1,11 +1,11 @@
{{- include "spire-lib.check-strict-mode" (list . "clusterName must be set" (eq (include "spire-lib.cluster-name" .) "example-cluster"))}}
{{- include "spire-lib.check-strict-mode" (list . "trustDomain must be set" (eq (include "spire-lib.trust-domain" .) "example.org"))}}
{{- include "spire-lib.check-strict-mode" (list . "jwtIssuer must be set" (eq (include "spire-lib.jwt-issuer" .) "https://oidc-discovery.example.org"))}}
{{- include "spire-lib.check-strict-mode" (list . "ca_subject.county must be set" (eq .Values.ca_subject.country "ARPA"))}}
{{- include "spire-lib.check-strict-mode" (list . "ca_subject.organization must be set" (eq .Values.ca_subject.organization "Example"))}}
{{- include "spire-lib.check-strict-mode" (list . "ca_subject.common_name must be set" (eq .Values.ca_subject.common_name "example.org"))}}
{{- include "spire-lib.check-strict-mode" (list . "ca_subject.county must be set" (eq (include "spire-server.ca-subject-country" .) "ARPA"))}}
{{- include "spire-lib.check-strict-mode" (list . "ca_subject.organization must be set" (eq (include "spire-server.ca-subject-organization" .) "Example"))}}
{{- include "spire-lib.check-strict-mode" (list . "ca_subject.common_name must be set" (eq (include "spire-server.ca-subject-common-name" .) "example.org"))}}
{{- range $type, $tvals := .Values.customPlugins }}
{{- if not (has $type (list "bundlePublisher" "keyManager" "nodeAttestor" "upstreamAuthority" "notifier")) }}
{{- if not (has $type (list "bundlePublisher" "credentialComposer" "keyManager" "nodeAttestor" "upstreamAuthority" "notifier")) }}
{{- fail (printf "Unknown plugin type specified: %s" $type) }}
{{- end }}
{{- range $name, $nval := $tvals }}
@@ -40,12 +40,17 @@
{{- $keyManagerUsed := 0 }}
{{- $root := . }}
server:
{{- with .Values.adminIDs }}
admin_ids:
{{- toYaml . | nindent 4}}
{{- end }}
bind_address: "0.0.0.0"
bind_port: "8081"
trust_domain: {{ include "spire-lib.trust-domain" . | quote }}
data_dir: "/run/spire/data"
log_level: {{ .Values.logLevel | quote }}
jwt_issuer: {{ include "spire-lib.jwt-issuer" . | quote }}
audit_log_enabled: {{ .Values.auditLogEnabled }}
ca_key_type: {{ .Values.caKeyType | quote }}
ca_ttl: {{ .Values.caTTL | quote }}
@@ -54,11 +59,9 @@ server:
default_jwt_svid_ttl: {{ .Values.defaultJwtSvidTTL | quote }}
ca_subject:
{{- with .Values.ca_subject }}
- country: [{{ .country | quote }}]
organization: [{{ .organization | quote }}]
common_name: {{ .common_name | quote }}
{{- end }}
- country: [{{ include "spire-server.ca-subject-country" . | quote }}]
organization: [{{ include "spire-server.ca-subject-organization" . | quote }}]
common_name: {{ include "spire-server.ca-subject-common-name" . | quote }}
{{- with .Values.federation }}
{{- if eq (.enabled | toString) "true" }}
@@ -82,12 +85,17 @@ server:
{{- end }}
plugins:
{{- if .Values.credentialComposer.uniqueID.enabled }}
CredentialComposer:
uniqueid: {}
{{- end }}
DataStore:
sql:
plugin_data:
{{ include "spire-server.datastore-config" . | nindent 10 }}
{{- if or .Values.nodeAttestor.k8sPsat.enabled .Values.nodeAttestor.joinToken.enabled }}
{{- if or .Values.nodeAttestor.k8sPsat.enabled .Values.nodeAttestor.joinToken.enabled .Values.nodeAttestor.tpmDirect.enabled }}
NodeAttestor:
{{- with .Values.nodeAttestor.k8sPsat }}
{{- if eq (.enabled | toString) "true" }}
@@ -104,6 +112,24 @@ plugins:
plugin_data: {}
{{- end }}
{{- end }}
{{- with .Values.nodeAttestor.tpmDirect }}
{{- if eq (.enabled | toString) "true" }}
tpm:
plugin_cmd: "/tpm/tpm_attestor_server"
plugin_checksum: {{ .checksum }}
plugin_data:
{{- if ne (len .cas) 0 }}
ca_path: /tpm-direct-cas
{{- else }}
ca_path: /run/spire/data/tpm-direct/certs
{{- end }}
{{- if ne (len .hashes) 0 }}
hash_path: /tmp-direct-hashes
{{- else }}
hash_path: /run/spire/data/tpm-direct/hashes
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- with .Values.keyManager.disk }}
@@ -42,4 +42,8 @@ data:
className: {{ include "spire-server.controller-manager-class-name" . | quote}}
watchClassless: {{ .Values.controllerManager.watchClassless | toYaml }}
parentIDTemplate: {{ .Values.controllerManager.parentIDTemplate | quote }}
{{- with .Values.reconcile }}
reconcile:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- end }}
@@ -1,6 +1,9 @@
{{- if .Values.federation.enabled }}
{{- if .Values.federation.ingress.enabled -}}
{{- $svcName := include "spire-server.fullname" . }}
{{- $path := "/"}}
{{- $pathType := "Prefix" }}
{{- $tlsSection := true }}
{{/* Until https://github.com/spiffe/spire/issues/2202 is resolved, use ingress to implement cert-manager and externalSecret support. */}}
{{- $federationIngress := deepCopy .Values.federation.ingress }}
{{- if .Values.federation.tls.certManager.enabled }}
@@ -11,7 +14,6 @@
{{- $_ := set $federationIngress "tlsSecret" .Values.federation.tls.externalSecret.secretName }}
{{- end }}
{{- $ingressControllerType := include "spire-lib.ingress-controller-type" (dict "global" .Values.global "ingress" .Values.federation.ingress) }}
{{- $tlsSection := true }}
{{- $annotations := deepCopy .Values.federation.ingress.annotations }}
{{- if eq $ingressControllerType "ingress-nginx" }}
{{- $_ := set $annotations "nginx.ingress.kubernetes.io/ssl-redirect" "true" }}
@@ -42,6 +44,6 @@ metadata:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{ include "spire-lib.ingress-spec" (dict "ingress" $federationIngress "svcName" $svcName "port" .Values.federation.bundleEndpoint.port "path" "/" "pathType" "Prefix" "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{ include "spire-lib.ingress-spec" (dict "ingress" $federationIngress "svcName" $svcName "port" .Values.federation.bundleEndpoint.port "path" $path "pathType" $pathType "tlsSection" $tlsSection "Values" .Values) | nindent 2 }}
{{- end }}
{{- end }}
@@ -43,6 +43,9 @@ spec:
component: server
release: {{ .Release.Name }}
release-namespace: {{ .Release.Namespace }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
@@ -53,8 +56,28 @@ spec:
securityContext:
{{- include "spire-lib.podsecuritycontext" . | 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) }}
{{- if or (gt (len .Values.initContainers) 0) (and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create) .Values.nodeAttestor.tpmDirect.enabled }}
initContainers:
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
- name: init-tpm-direct
securityContext:
{{- include "spire-lib.securitycontext" . | nindent 12 }}
image: {{ template "spire-lib.image" (dict "appVersion" $.Chart.AppVersion "image" .Values.nodeAttestor.tpmDirect.image "global" .Values.global) }}
command:
- sh
- -ec
- |
# SPIRE must be able to fork the plugin directly within its container. Copy the plugin into a volume that can be mounted where SPIRE can execute it.
cp -a {{ .Values.nodeAttestor.tpmDirect.pluginPath }} /tpm/tpm_attestor_server
mkdir -p /run/spire/data/tpm-direct/certs
mkdir -p /run/spire/data/tpm-direct/hashes
volumeMounts:
- name: tpm-direct
mountPath: /tpm
- name: spire-data
mountPath: /run/spire/data
imagePullPolicy: {{ .Values.nodeAttestor.tpmDirect.image.pullPolicy }}
{{- end }}
{{- if and .Values.upstreamAuthority.certManager.enabled .Values.upstreamAuthority.certManager.ca.create }}
- name: wait
securityContext:
@@ -158,6 +181,19 @@ spec:
- name: spire-data
mountPath: /run/spire/data
readOnly: false
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
- name: tpm-direct
mountPath: /tpm
readOnly: true
{{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }}
- name: tpm-direct-cas
mountPath: /tpm-direct-cas
{{- end }}
{{- if ne (len .Values.nodeAttestor.tpmDirect.hashes) 0 }}
- name: tpm-direct-hashes
mountPath: /tmp-direct-hashes
{{- end }}
{{- end }}
{{- if eq (.Values.upstreamAuthority.disk.enabled | toString) "true" }}
- name: upstream-ca
mountPath: /run/spire/upstream_ca
@@ -191,6 +227,9 @@ spec:
{{- if gt (len .Values.extraVolumeMounts) 0 }}
{{- toYaml .Values.extraVolumeMounts | nindent 12 }}
{{- end }}
- name: server-tmp
mountPath: /tmp
readOnly: false
{{- if eq (.Values.controllerManager.enabled | toString) "true" }}
- name: spire-controller-manager
securityContext:
@@ -314,6 +353,8 @@ spec:
{{- toYaml . | nindent 8 }}
{{- end }}
volumes:
- name: server-tmp
emptyDir: {}
- name: spire-config
configMap:
name: {{ include "spire-server.fullname" . }}
@@ -321,6 +362,20 @@ spec:
emptyDir: {}
- name: spire-controller-manager-tmp
emptyDir: {}
{{- if .Values.nodeAttestor.tpmDirect.enabled }}
- name: tpm-direct
emptyDir: {}
{{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }}
- name: tpm-direct-cas
configMap:
name: {{ include "spire-server.fullname" . }}-tpm-direct-ca
{{- end }}
{{- if ne (len .Values.nodeAttestor.tpmDirect.hashes) 0 }}
- name: tpm-direct-hashes
configMap:
name: {{ include "spire-server.fullname" . }}-tpm-direct-hash
{{- end }}
{{- end }}
{{- if or (eq (include "spire-tornjak.connectionType" .) "tls") (eq (include "spire-tornjak.connectionType" .) "mtls") }}
- name: server-cert
secret:
@@ -0,0 +1,24 @@
{{- if ne (len .Values.nodeAttestor.tpmDirect.cas) 0 }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "spire-server.fullname" . }}-tpm-direct-ca
namespace: {{ include "spire-server.namespace" . }}
data:
{{- range $key, $value := .Values.nodeAttestor.tpmDirect.cas }}
{{ $key }}: |
{{ $value | nindent 4 }}
{{- end }}
{{- end }}
---
{{- if ne (len .Values.nodeAttestor.tpmDirect.hashes) 0 }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "spire-server.fullname" . }}-tpm-direct-hash
namespace: {{ include "spire-server.namespace" . }}
data:
{{- range .Values.nodeAttestor.tpmDirect.hashes }}
{{ . }}: ""
{{- end }}
{{- end }}
+45 -2
View File
@@ -47,6 +47,9 @@ serviceAccount:
## @param podAnnotations [object] Annotations to add to pods
podAnnotations: {}
## @param podLabels [object] Labels to add to pods
podLabels: {}
## @param podSecurityContext [object] Pod security context
podSecurityContext: {}
# fsGroup: 2000
@@ -173,6 +176,10 @@ dataStore:
## @param dataStore.sql.externalSecret.key The key of the secret object whose value is the dataStore.sql password
key: ""
## @param adminIDs SPIFFE IDs that, when present in a caller’s X509-SVID, grant that caller admin privileges.
adminIDs: []
## @param auditLogEnabled If true, enables audit logging
auditLogEnabled: false
## @param logLevel The log level, valid values are "debug", "info", "warn", and "error"
logLevel: info
## @param jwtIssuer The JWT issuer domain. Defaults to oidc-discovery.$trustDomain if unset
@@ -280,6 +287,11 @@ ca_subject:
## @param ca_subject.common_name Common Name for Spire server CA
common_name: example.org
credentialComposer:
uniqueID:
## @param credentialComposer.uniqueID.enabled Add the x509UniqueIdentifier attribute to workload X509-SVIDs
enabled: false
keyManager:
disk:
## @param keyManager.disk.enabled Flag to enable keyManager on disk
@@ -448,7 +460,7 @@ controllerManager:
registry: ghcr.io
repository: spiffe/spire-controller-manager
pullPolicy: IfNotPresent
tag: "0.4.2"
tag: "0.4.3"
## @param controllerManager.resources [object] Resource requests and limits for controller manager
resources: {}
@@ -491,6 +503,13 @@ controllerManager:
- kube-public
- local-path-storage
## @param controllerManager.reconcile.clusterSPIFFEIDs Enable reconciliation of clusterSPIFFEIDs from K8s to the SPIRE server
## @param controllerManager.reconcile.clusterStaticEntries Enable reconciliation of clusterStaticEntries from K8s to the SPIRE server
## @param controllerManager.reconcile.clusterFederatedTrustDomains Enable reconciliation of clusterFederatedTrustDomains from K8s to the SPIRE server
reconcile:
clusterSPIFFEIDs: true
clusterStaticEntries: true
clusterFederatedTrustDomains: true
identities:
clusterSPIFFEIDs:
# NOTE you can add multiple uniquely named entries to create multiple ClusterSPIFFEID objects. See example below.
@@ -684,6 +703,27 @@ nodeAttestor:
joinToken:
## @param nodeAttestor.joinToken.enabled Enable the join_token nodeattestor
enabled: false
tpmDirect:
## @param nodeAttestor.tpmDirect.enabled Enable the direct TPM node attestor, a 3rd party plugin by Boxboat. This plugin is experimental.
enabled: false
## @param nodeAttestor.tpmDirect.image.registry The OCI registry to pull the image from
## @param nodeAttestor.tpmDirect.image.repository The repository within the registry
## @param nodeAttestor.tpmDirect.image.pullPolicy The image pull policy
## @param nodeAttestor.tpmDirect.image.tag Overrides the image tag
##
image:
registry: docker.io
repository: boxboat/spire-tpm-plugin-tpm-attestor-server
pullPolicy: IfNotPresent
tag: "v1.8.7"
## @param nodeAttestor.tpmDirect.checksum The sha256 checksum of the plugin binary
checksum: f39ef9cdd2b3dd74112bfe827b79d6721c59215d0d5f4c2e34fa09bbc60d36d2
## @param nodeAttestor.tpmDirect.pluginPath The filename in the container of the plugin
pluginPath: /app/tpm_attestor_server
## @param nodeAttestor.tpmDirect.cas A dictionary of TPM CA PEM or DER files that are allowed to connect.
cas: {}
## @param nodeAttestor.tpmDirect.hashes A list of TPM hashes that are allowed to connect.
hashes: []
## @section Tornjak
tornjak:
@@ -800,18 +840,21 @@ tornjak:
## @skip unsupportedBuiltInPlugins
unsupportedBuiltInPlugins:
bundlePublisher: {}
credentialComposer: {}
keyManager: {}
nodeAttestor: {}
upstreamAuthority: {}
notifier: {}
## @param customPlugins.bundlePublisher Custom plugins of type BundlePublisher are configured here
## @param customPlugins.credentialComposer Custom plugins of type CredentialComposer are configured here
## @param customPlugins.keyManager Custom plugins of type KeyManager are configured here
## @param customPlugins.nodeAttestor Custom plugins of type NodeAttestor are configured here
## @param customPlugins.upstreamAuthority Custom plugins of type upstreamAuthority are configured here
## @param customPlugins.notifier Custom plugins of type notifier are configured here
customPlugins:
bundlePublisher: {}
credentialComposer: {}
keyManager: {}
nodeAttestor: {}
upstreamAuthority: {}
@@ -843,4 +886,4 @@ tests:
registry: cgr.dev
repository: chainguard/bash
pullPolicy: IfNotPresent
tag: latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f
tag: latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669
@@ -98,4 +98,4 @@ port forwarding. See the chart NOTES output for more details.
| `tests.bash.image.registry` | The OCI registry to pull the image from | `cgr.dev` |
| `tests.bash.image.repository` | The repository within the registry | `chainguard/bash` |
| `tests.bash.image.pullPolicy` | The image pull policy | `IfNotPresent` |
| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f` |
| `tests.bash.image.tag` | Overrides the image tag whose default is the chart appVersion | `latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669` |
@@ -154,4 +154,4 @@ tests:
registry: cgr.dev
repository: chainguard/bash
pullPolicy: IfNotPresent
tag: latest@sha256:1b4e8389d2582d0b013fad55d7ad799a67bbdcbfbae0a053258ae24c8b03a19f
tag: latest@sha256:81f0b434b297453ff101de0b5f4f5cd8d4af1c015a1d34162e9ae9a4a9f38669
+10 -6
View File
@@ -168,12 +168,16 @@ rules:
{{- end }}
{{- define "spire-lib.kubectl-image" }}
{{- $root := deepCopy . }}
{{- $tag := $root.image.tag | toString }}
{{- if eq (len $tag) 0 }}
{{- $_ := set $root.image "tag" (regexReplaceAll "^(v?\\d+\\.\\d+\\.\\d+).*" $root.KubeVersion "${1}") }}
{{- end }}
{{- include "spire-lib.image" $root }}
{{- $root := deepCopy . }}
{{- $tag := $root.image.tag | toString }}
{{- if eq (len $tag) 0 }}
{{- if dig "spire" "tools" "kubectl" "tag" "" $root.global }}
{{- $_ := set $root.image "tag" $root.global.spire.tools.kubectl.tag }}
{{- else }}
{{- $_ := set $root.image "tag" (regexReplaceAll "^(v?\\d+\\.\\d+\\.\\d+).*" $root.KubeVersion "${1}") }}
{{- end }}
{{- end }}
{{- include "spire-lib.image" $root }}
{{- end }}
{{/*
+13
View File
@@ -21,6 +21,14 @@ global:
## @param global.spire.upstreamServerAddress Set what address to use for the upstream server when using nested spire
upstreamServerAddress: ""
## @param global.spire.caSubject.country Country for Spire server CA
## @param global.spire.caSubject.organization Organization for Spire server CA
## @param global.spire.caSubject.commonName Common Name for Spire server CA
caSubject:
country: ""
organization: ""
commonName: ""
## @param global.spire.recommendations.enabled Use recommended settings for production deployments. Default is off.
## @param global.spire.recommendations.namespaceLayout Set to true to use recommended values for installing across namespaces
## @param global.spire.recommendations.namespacePSS When chart namespace creation is enabled, label them with preffered Pod Security Standard labels
@@ -69,6 +77,11 @@ global:
## @param global.spire.ingressControllerType Specify what type of ingress controller you're using to add the necessary annotations accordingly. If blank, autodetection is attempted. If other, no annotations will be added. Must be one of [ingress-nginx, openshift, other, ""].
ingressControllerType: ""
tools:
kubectl:
## @param global.spire.tools.kubectl.tag Set to force the tag to use for all kubectl instances
tag: ""
installAndUpgradeHooks:
## @param global.installAndUpgradeHooks.enabled Enable Helm hooks to autofix common install/upgrade issues (should be disabled when using `helm template`)
enabled: true
@@ -0,0 +1,67 @@
# keycloak-config-cli using spire
> [!WARNING]
> This example uses
> the [`SidecarContainers`](https://kubernetes.io/docs/concepts/workloads/pods/sidecar-containers/#enabling-sidecar-containers)
> feature. This is only enabled by default in Kubernetes 1.29+.
This example shows how to leverage SPIRE in establishing an mTLS connection
between [Keycloak](https://www.keycloak.org/) and [keycloak-config-cli](https://github.com/adorsys/keycloak-config-cli),
a tool to configure Keycloak.
## Setup
1. Create a local cluster for testing
```shell
kind create cluster --image kindest/node:v1.29.0
```
2. Install CRDs
```shell
helm upgrade --install -n spire-server spire-crds ../../charts/spire-crds --create-namespace
```
3. Install `spire-server`
```shell
helm upgrade --install -n spire-server spire ../../charts/spire --create-namespace -f spire-values.yaml
```
4. Install `keycloak` (this also configures Keycloak for client certificate authentication)
```shell
helm upgrade --install keycloak oci://registry-1.docker.io/bitnamicharts/keycloak -f keycloak-values.yaml
```
5. Install `keycloak-config-cli`
```shell
kubectl apply -f keycloak-config-cli.yaml
```
6. Verify the realm config at the bottom of [keycloak-config-cli.yaml](./keycloak-config-cli.yaml) has been created!
7. Cleanup
```shell
kind delete cluster
```
## Notes
### java-spiffe-helper as Keycloak initContainer
This example uses [java-spiffe-helper](https://github.com/spiffe/java-spiffe/tree/main/java-spiffe-helper) as an
initContainer for Keycloak. It fetches the certificates from the `spire-agent` and conveniently provides them to
Keycloak in `pkcs12` format.
> [!IMPORTANT]
> Keycloak does not rotate the certificates like SPIRE does. If you want to run the `keycloak-config-cli`
> job again, you need to make sure Keycloak is also restarted/provided with non-expired certificates.
### Common name as username
This example is configured to read the username from the common name (`CN`) from the client certificate. Keycloak has
some options there, this looked like the easiest one. SPIRE joins the values from `dnsNameTemplates` in the
common name section of the certificate, so make sure you can somehow extract the username from it.
@@ -0,0 +1,84 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: keycloak-config-cli
labels:
app: keycloak-config-cli
spec:
backoffLimit: 1
template:
metadata:
labels:
app: keycloak-config-cli
app.kubernetes.io/instance: keycloak-config-cli # This needs to match the podSelector for the SpiffeID
spec:
initContainers:
- name: ghostunnel
image: ghostunnel/ghostunnel:v1.7.3
imagePullPolicy: IfNotPresent
restartPolicy: Always
args:
- client
- --use-workload-api-addr
- unix:///run/spire/agent-sockets/spire-agent.sock # The filename depends on what the spire-agent uses
- --listen
- localhost:8080 # Listen on local http
- --target
- keycloak:8443 # Tunnel via https
- --status
- http://0.0.0.0:6060
ports:
- containerPort: 8080
name: listen
protocol: TCP
- containerPort: 6060
name: readiness
protocol: TCP
readinessProbe:
httpGet:
path: /_status
port: readiness
volumeMounts:
- name: spire-sockets
mountPath: /run/spire/agent-sockets
readOnly: true
containers:
- name: keycloak-config-cli
image: adorsys/keycloak-config-cli:latest
imagePullPolicy: IfNotPresent
env:
- name: KEYCLOAK_URL
value: "http://127.0.0.1:8080"
- name: KEYCLOAK_USER
value: "keycloak-config-cli"
- name: KEYCLOAK_PASSWORD
value: "doesn't matter, since we are authenticated via the client certificate"
- name: KEYCLOAK_CLIENTID
value: "keycloak-config-cli" # This is the client created on bootstrapping Keycloak via the keycloak-config-cli sidecar
volumeMounts:
- name: realm
mountPath: /config
restartPolicy: OnFailure
volumes:
- name: realm
configMap:
name: keycloak-config-cli
- name: spire-sockets
hostPath:
path: /run/spire/agent-sockets # This needs to match the path mounted by the spire-agent
type: DirectoryOrCreate
---
apiVersion: v1
kind: ConfigMap
metadata:
name: keycloak-config-cli
labels:
app: keycloak-config-cli
data:
keycloak-config-cli.json: |
{
"id": "keycloak-config-cli",
"realm": "keycloak-config-cli",
"enabled": true
}
@@ -0,0 +1,134 @@
extraDeploy:
- apiVersion: v1
kind: ConfigMap
metadata:
name: java-spiffe-helper-properties
data:
java-spiffe-helper.properties: |
keyStorePath=/certs/keystore.p12
keyStorePass=password
keyPass=password
trustStorePath=/certs/truststore.p12
trustStorePass=password
keyStoreType=pkcs12
keyAlias=spiffe
spiffeSocketPath=unix:/run/spire/agent-sockets/spire-agent.sock
service:
extraPorts:
- name: https
port: 8443
targetPort: 8443
extraEnvVars:
- name: KC_HTTPS_CLIENT_AUTH
value: "request"
- name: KC_HTTPS_KEY_STORE_FILE
value: "/certs/keystore.p12"
- name: KC_HTTPS_KEY_STORE_PASSWORD
value: "password"
- name: KC_HTTPS_KEY_STORE_TYPE
value: "pkcs12"
- name: KC_HTTPS_TRUST_STORE_FILE
value: "/certs/truststore.p12"
- name: KC_HTTPS_TRUST_STORE_PASSWORD
value: "password"
- name: KC_HTTPS_TRUST_STORE_TYPE
value: "pkcs12"
initContainers:
- name: java-spiffe-helper
image: ghcr.io/spiffe/java-spiffe-helper:0.8.5
imagePullPolicy: IfNotPresent
restartPolicy: Always
readinessProbe:
exec:
command:
- ls
- /certs/truststore.p12
volumeMounts:
- name: java-spiffe-helper-properties
mountPath: /app/java-spiffe-helper.properties
subPath: java-spiffe-helper.properties
- name: spire-sockets
mountPath: /run/spire/agent-sockets
readOnly: true
- name: certs
mountPath: /certs
extraVolumeMounts:
- name: certs
mountPath: /certs
extraVolumes:
- name: java-spiffe-helper-properties
configMap:
name: java-spiffe-helper-properties
- name: spire-sockets
hostPath:
path: /run/spire/agent-sockets
type: DirectoryOrCreate
- name: certs
emptyDir: {}
auth:
adminPassword: "password"
keycloakConfigCli:
enabled: true
configuration:
master.json: |
{
"id": "master",
"realm": "master",
"enabled": true,
"users": [
{
"username": "keycloak-config-cli",
"enabled": true,
"realmRoles": [
"admin"
],
"credentials": [
{
"type": "password",
"value": "it-really-doesn't-matter-what-you-put-here"
}
]
}
],
"authenticationFlows": [
{
"alias": "direct grant x509",
"providerId": "basic-flow",
"topLevel": true,
"builtIn": false,
"authenticationExecutions": [
{
"authenticatorConfig": "username",
"authenticator": "direct-grant-auth-x509-username",
"requirement": "REQUIRED",
"priority": 0
}
]
}
],
"authenticatorConfig": [
{
"alias": "username",
"config": {
"x509-cert-auth.regular-expression": "CN=(keycloak-config-cli)",
"x509-cert-auth.mapper-selection": "Username or Email",
"x509-cert-auth.mapping-source-selection": "Match SubjectDN using regular expression"
}
}
],
"clients": [
{
"clientId": "keycloak-config-cli",
"name": "keycloak-config-cli",
"enabled": true,
"standardFlowEnabled": false,
"directAccessGrantsEnabled": true,
"publicClient": true,
"authenticationFlowBindingOverrides": {
"direct_grant": "direct grant x509"
},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": 0
}
]
}
@@ -0,0 +1,26 @@
spire-server:
controllerManager:
identities:
clusterSPIFFEIDs:
default:
enabled: false
keycloak:
spiffeIDTemplate: spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
podSelector:
matchLabels:
app.kubernetes.io/instance: keycloak
dnsNameTemplates:
- keycloak
keycloak-config-cli:
spiffeIDTemplate: spiffe://{{ .TrustDomain }}/ns/{{ .PodMeta.Namespace }}/sa/{{ .PodSpec.ServiceAccountName }}
namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: default
podSelector:
matchLabels:
app.kubernetes.io/instance: keycloak-config-cli
dnsNameTemplates:
- keycloak-config-cli # This is the common name used for the certificate. In this case, the username
+15
View File
@@ -0,0 +1,15 @@
spire-agent:
nodeAttestor:
k8sPsat:
enabled: false
tpmDirect:
enabled: true
spire-server:
controllerManager:
# K8s labels have a 63 character limit. TPM hashes are 64 chars. So you need to label the node with two labels with half of the tpm's hash each. The 'node-restriction.kubernetes.io/' prefix is so that the
# nodes can't update the hash themselves, an important security constraint.
parentIDTemplate: 'spiffe://{{ .TrustDomain }}/spire/agent/tpm/{{ index .NodeMeta.Labels "node-restriction.kubernetes.io/tpm-pubhash" }}{{ index .NodeMeta.Labels "node-restriction.kubernetes.io/tpm-pubhash2" }}'
nodeAttestor:
tpmDirect:
enabled: true
+4 -2
View File
@@ -1,11 +1,13 @@
module github.com/spiffe/helm-charts/tests
go 1.20
go 1.21
toolchain go1.21.5
require (
github.com/onsi/ginkgo/v2 v2.15.0
github.com/onsi/gomega v1.31.1
helm.sh/helm/v3 v3.14.0
helm.sh/helm/v3 v3.14.2
)
require (
+8 -2
View File
@@ -19,7 +19,9 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI=
github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
@@ -67,6 +69,7 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -95,6 +98,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
@@ -102,6 +106,7 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -113,6 +118,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
@@ -205,8 +211,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
helm.sh/helm/v3 v3.14.0 h1:TaZIH6uOchn7L27ptwnnuHJiFrT/BsD4dFdp/HLT2nM=
helm.sh/helm/v3 v3.14.0/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424=
helm.sh/helm/v3 v3.14.2 h1:V71fv+NGZv0icBlr+in1MJXuUIHCiPG1hW9gEBISTIA=
helm.sh/helm/v3 v3.14.2/go.mod h1:2itvvDv2WSZXTllknfQo6j7u3VVgMAvm8POCDgYH424=
k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A=
k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA=
k8s.io/apiextensions-apiserver v0.29.0 h1:0VuspFG7Hj+SxyF/Z/2T0uFbI5gb5LRgEyUVE3Q4lV0=
+13
View File
@@ -144,6 +144,19 @@ spire-agent:
objs, err := ValueStringRender(chart, `
spire-server:
enabled: false
`)
Expect(err).Should(Succeed())
notes := objs["spire/templates/NOTES.txt"]
Expect(notes).Should(ContainSubstring("Installed"))
})
})
Describe("spire-server.credentialComposer.uniqueID", func() {
It("spire server uniqueid credential composer", func() {
objs, err := ValueStringRender(chart, `
spire-server:
credentialComposer:
uniqueID:
enabled: true
`)
Expect(err).Should(Succeed())
notes := objs["spire/templates/NOTES.txt"]