Render Gateway spec.infrastructure (labels/annotations) so Gateway API
controllers propagate the metadata onto the provisioned Service/Deployment,
e.g. AWS internal NLB annotations. Purely additive: guarded by `with`, so
the default {} renders no change.
- spire-lib: toYaml passthrough in the shared Gateway helper
- spire, spire-nested: add the values param; regenerate READMEs
- tests/unit: cover the positive passthrough case
Signed-off-by: sabsari <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
The PodMonitor targeted the port name prom-cm, but controller-manager
containers expose pm-cm (and auto-suffixed/overridable names for external
managers), so their metrics were never scraped. Resolve port names through
a shared helper and enumerate every controller-manager in the PodMonitor.
Signed-off-by: sabsari <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
* fix(spire-server): support postgres TLS client-certificate (passwordless) auth
The postgres datastore always injected a password into the connection
string, always created the -dbpw Secret, and always set the DBPW env var,
with no way to use TLS client-certificate (or IAM) authentication. This
forced a dummy password (e.g. "unused") when authenticating with certs.
- Map dataStore.sql.rootCAPath / clientCertPath / clientKeyPath to the
postgres connection-string options sslrootcert / sslcert / sslkey
(previously these were mysql-only and rejected for postgres). MySQL keeps
using the root_ca_path / client_cert_path / client_key_path plugin fields,
now correctly gated to mysql/aws_mysql only.
- For postgres/aws_postgres, when dataStore.sql.password is empty, omit
"password=${DBPW}" from the connection string and skip creating the -dbpw
Secret and the DBPW/RODBPW env vars (mirrors the existing gcp_mysql_sa_iam
passwordless behavior).
- Add a guard: for postgres, dataStore.sql.password and clientCertPath are
mutually exclusive.
- Fix a stray tab in the mysql client_key_path config field.
- Update value docs and regenerate the README.
Existing configurations with a password set are unaffected.
Signed-off-by: Michael Munch <[email protected]>
* 🐛 fix(spire-server): keep postgres password when external secret is used
The postgres passwordless path keyed only on an empty password, so
enabling dataStore.sql.externalSecret (or readOnly.externalSecret) with
an empty password dropped the password token from the connection string
and skipped the DBPW/RODBPW env vars, breaking external-secret auth.
- Add shared passwordless predicates that also require external secrets
to be disabled, evaluated independently for read-write and read-only.
- Use the predicates in datastore-config, secret.yaml, and
server-resource.yaml so the gating cannot drift.
- Add unit tests for postgres with read-write and read-only external
secrets plus the cert-auth passwordless case.
Signed-off-by: Michael Munch <[email protected]>
* 🔁 ci: re-trigger checks
Re-run CI; the previous spiffe-step-ssh integration job failed on an
unrelated flaky SSH host-key verification on k8s v1.35.1 (passed on
v1.33.7 and v1.34.3).
Signed-off-by: Michael Munch <[email protected]>
---------
Signed-off-by: Michael Munch <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
* fix(spiffe-oidc-discovery-provider): run under restricted PSA/SCC on OpenShift
The OIDC discovery provider does not require any elevated privileges: it
runs fine under OpenShift's built-in restricted-v2 SCC (non-root, no
privilege escalation, all capabilities dropped, RuntimeDefault seccomp,
read-only root filesystem) and mounts only restricted-compatible volumes
(csi, configMap, emptyDir, secret, projected, downwardAPI).
Despite this, on OpenShift the chart:
- downgraded the spire-server namespace from restricted to privileged PSA
whenever the OIDC provider was enabled, and
- created a fully privileged SecurityContextConstraints (host network/IPC/
PID, privileged container, hostPath, arbitrary seccomp, RunAsAny) bound
to the provider's ServiceAccount.
Both contradict the chart's own Namespaces documentation, which specifies
restricted PSA for spire-server, and violate least privilege for an
internet-facing OIDC endpoint.
Remove the privileged PSA override for the OIDC provider (spire-server
stays restricted; the scc.podSecurityLabelSync=false label is retained)
and drop the privileged SCC so the provider falls through to restricted-v2.
With spire-server enforcing restricted PSA, the inline-CSI PodSecurity
check reads the cluster-scoped CSIDriver's
security.openshift.io/csi-ephemeral-volume-profile label. If the CSIDriver
is not committed before the spire-server StatefulSet (which mounts the
inline upstream.csi.spiffe.io volume) is admitted, the profile defaults to
privileged and admission is denied. Under ArgoCD the CSIDriver and the
server StatefulSet can land in the same sync wave, racing admission.
Annotate the CSIDriver with argocd.argoproj.io/sync-wave: "-1" (OpenShift
only) so it is applied before the default-wave server workloads; the
annotation is inert for plain helm installs.
Signed-off-by: Michael Munch <[email protected]>
* ✨ make CSIDriver sync-wave ordering configurable
Add syncWave and csiDriverAnnotations values to the spiffe-csi-driver
chart so the OpenShift argocd.argoproj.io/sync-wave annotation number
can be overridden (e.g. when the chart is nested) and arbitrary
annotations can be applied to the CSIDriver.
Signed-off-by: Michael Munch <[email protected]>
---------
Signed-off-by: Michael Munch <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
* Allow sqlite3 in memory when kind is deployment
Signed-off-by: Daniel Schlatter <[email protected]>
* Warn on unsafe in-memory datastore combinations
Signed-off-by: Daniel Schlatter <[email protected]>
---------
Signed-off-by: Daniel Schlatter <[email protected]>
Add jwtSVIDExec as a fourth exactly-one kubeConfigs source: the chart
generates an exec-credential kubeconfig that authenticates to an external
cluster with short-lived SPIFFE JWT-SVIDs instead of a static credential.
Signed-off-by: sabsari <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
* feat(spire-server): support x509pop externalPKI ca bundle
Add externalPKI mode support to the x509pop node attestor configuration.
Allows operators to configure CA bundles for external PKI-based node
attestation via two approaches:
- Inline PEM content (chart creates and manages ConfigMap)
- Reference to existing ConfigMap with ca-bundle.pem key
Includes volume/volumeMount definitions for CA bundle mounting at
/run/spire/data/x509pop-ca-bundle.pem and unit tests for both modes.
Signed-off-by: Savitha Ganapathi <[email protected]>
* refactor: simplify x509pop externalPKI template guard logic
Remove nested conditional guard for ca_bundle_path rendering. When
externalPKI mode is enabled, ca_bundle_path is always rendered; if no
CA bundle is provided, SPIRE will fail at startup with a clear error.
Drop unit tests pending fix to the unit test framework (which currently
has issues loading values from chart, forcing overly-defensive template
guards for test compatibility). Tests can be re-added once framework is
fixed.
Signed-off-by: Savitha Ganapathi <[email protected]>
* refactor: simplify x509pop volume/volumeMount guard logic
Remove nested caBundle existence checks from volume and volumeMount
guard conditions. When externalPKI mode is enabled, volume/volumeMount
are created; if no CA bundle is provided, SPIRE fails at startup with
clear error (missing mount).
Signed-off-by: Savitha Ganapathi <[email protected]>
* refactor: reorder if/with clauses for clarity
Move if condition checks to outer scope before entering with blocks.
This is more idiomatic Helm pattern and avoids unnecessary context
switching if condition fails.
Signed-off-by: Savitha Ganapathi <[email protected]>
* refactor: simplify conditionals to match chart patterns
Replace complex toString/eq comparisons with simpler boolean checks that
match existing patterns in the chart (e.g., federation.tls.certManager.enabled).
Changes:
- .enabled checks: remove toString wrapping, use simple boolean test
- .mode checks: remove toString, use simple eq comparison
- .caBundle checks: simplify from 'ne (... | default "") ""' to simple boolean test
This aligns with chart conventions and avoids tripping broken unit test
framework that struggles with complex conditionals.
Signed-off-by: Savitha Ganapathi <[email protected]>
* test: resurrect x509POP unit tests with simplified conditionals
Re-add unit tests for externalPKI mode now that template conditionals
have been simplified to match chart patterns. Simplified conditionals
should be less fragile with unit test framework.
Tests cover:
- externalPKI with chart-managed CA bundle (inline)
- externalPKI with existing ConfigMap reference
Signed-off-by: Savitha Ganapathi <[email protected]>
* docs: regenerate spire-server README for x509pop caBundle params
Updated parameter documentation for nodeAttestor.x509POP section to
include new caBundle configuration options (inline bundle and existing
ConfigMap reference).
Auto-generated documentation based on @param comments in values.yaml.
Signed-off-by: Savitha Ganapathi <[email protected]>
---------
Signed-off-by: Savitha Ganapathi <[email protected]>
Co-authored-by: Savitha Ganapathi <[email protected]>
Replace the hardcoded `User: spire-root` subject with an `externalServerSubject`
block (`kind`/`name`/`namespace`) so the downstream RBAC can bind to a User,
Group, or ServiceAccount. Defaults preserve the previous behavior.
Signed-off-by: sabsari <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
Allow each kubeConfigs entry to reference an externally-managed Secret
(externalSecret{name,key}) instead of embedding the kubeconfig in values.
Entries may reference different Secrets and mix inline with external ones.
The kubeconfigs volume becomes a projected volume; consumer mount paths are
unchanged. Each entry must set exactly one of kubeConfig, kubeConfigBase64,
or externalSecret.
Signed-off-by: sabsari <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
Add support for the EJBCA UpstreamAuthority plugin, allowing the SPIRE
server to use an EJBCA instance as its upstream CA over mTLS.
- Add upstreamAuthority.ejbca values (hostname, caName, endEntityProfileName,
certificateProfileName, optional endEntityName and accountBindingId).
- Render the ejbca UpstreamAuthority block in the server config and count it
toward the single-upstream-authority guard.
- Mount the mTLS client credentials (and optional CA cert) from a secret,
either chart-created (secret.create) or externally provided.
- Gate ca_cert_path on secret.data.caCert, mirroring the disk plugin's bundle
handling for deterministic rendering.
- Regenerate the chart README and add a unit render test.
Signed-off-by: sabsari <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
The SPIRE OIDC Discovery Provider binary supports a top-level
`jwt_issuer` configuration key. When set, the provider returns that
exact string as the `issuer` field in the OIDC discovery document
(`.well-known/openid-configuration`) regardless of how the request was
routed. When unset, it derives `issuer` from the inbound HTTP Host
header. This chart did not render that key into the OIDC provider
config, leaving the discovery document Host-derived even when the
operator had a fixed issuer in mind.
Why this matters
OpenID Connect Discovery requires the discovery doc's `issuer` to be
byte-equal to the JWT `iss` claim. Conformant verifiers reject the chain
when the two differ. Production OIDC consumers routinely reach the
discovery endpoint at a URL different from the canonical issuer:
- a load balancer, ingress, or NodePort exposes the provider on an
IP or host different from the canonical issuer name;
- TLS terminates at a hostname different from the one advertised to
clients;
- the discovery URL is fetched by an internal service (e.g. the API
server in a private cluster) over a different DNS view than
external clients use;
- a pinned issuer URL is contractually required and must survive
infrastructure changes that move the actual service endpoint.
In all of these the JWT's `iss` claim is a logical, stable URL; the
discovery doc must report that same value, or downstream verifiers
reject the tokens.
Current chart behavior
The chart already has `global.spire.jwtIssuer` (and a subchart-local
`jwtIssuer`), resolved by the `spire-lib.jwt-issuer` helper to
`global.spire.jwtIssuer` -> subchart-local `jwtIssuer` ->
`https://oidc-discovery.<trustDomain>`. The spire-server subchart writes
that helper's result unconditionally as `jwt_issuer:` into the server's
config -- this controls the `iss` claim of every JWT-SVID the server
mints. In the OIDC subchart, however, the same helper was only used for
two things:
1. as the strict-mode assertion gate (fails the render when the
resolved value is the `example.org` default);
2. as the default source for `config.jwtDomain` (the Host
allow-list).
It was never written into the rendered OIDC provider configuration file.
The asymmetry means the chart shipped a structurally invalid OIDC setup
by default: the spire-server signs JWTs with `iss = <resolved issuer>`,
while the OIDC discovery endpoint advertises whatever Host header was
used to reach it. The only way to correct that today is to patch the
rendered ConfigMap out of band (`kubectl patch`, a CMP, a kustomize
post-renderer), which defeats the purpose of the chart.
Backward compatibility and behavior changes
Operators who set `global.spire.jwtIssuer` will see one additional
`jwt_issuer:` line in the rendered OIDC ConfigMap. The discovery doc's
`issuer` will start returning that pinned value instead of being
Host-derived, bringing the chain into spec compliance; this is a fix for
any spec-compliant verifier that previously rejected tokens. Operators
who only set the OIDC subchart-local `jwtIssuer` see the same fix
applied via the helper's fallback chain. Operators with nothing set will
see the new line default to `https://oidc-discovery.<trustDomain>`,
matching what the spire-server config already emits today.
Signed-off-by: Guillermo Gaston <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
* Exit code from diff indicating changes should not block commit.
Signed-off-by: Kevin Fox <[email protected]>
* Push the changes that update-tags creates
Signed-off-by: Kevin Fox <[email protected]>
* Add plugin support to the spire agent
This adapts the existing spire server plugin support to be usable by
the agent as well.
Signed-off-by: Kevin Fox <[email protected]>
* Fix notes
Signed-off-by: Kevin Fox <[email protected]>
* Add plugin support to the spire agent
This adapts the existing spire server plugin support to be usable by
the agent as well.
Signed-off-by: Kevin Fox <[email protected]>
* Fix notes
Signed-off-by: Kevin Fox <[email protected]>
* Update documentation
Signed-off-by: Kevin Fox <[email protected]>
* Update example
Signed-off-by: Kevin Fox <[email protected]>
---------
Signed-off-by: Kevin Fox <[email protected]>
Signed-off-by: kfox1111 <[email protected]>
Current configmap template renders to a wrong KeyManager and
UpstreamAuthority configurarion when aws_kms and aws_pca are enabled and
container is crashing. The proposed changes will fix the issue.
---------
Signed-off-by: unufree <[email protected]>
Signed-off-by: unufr33 <[email protected]>
Co-authored-by: Faisal Memon <[email protected]>
This patch enables end users to configure external plugins in the
spire-server config. Unsupported internal plugins are not able to be
set.
---------
Signed-off-by: Kevin Fox <[email protected]>
Signed-off-by: kfox1111 <[email protected]>
Co-authored-by: Edwin Buck <[email protected]>
Co-authored-by: Faisal Memon <[email protected]>