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]>
* feat(spire-server): add terminationGracePeriodSeconds and lifecycle support
Adds two new top-level values to the spire-server chart:
- `terminationGracePeriodSeconds` (nullable, pod-spec level): overrides the
default 30s termination grace period. Useful when the server is behind a
load balancer that needs time to deregister the target (e.g. AWS NLB with
a deregistration delay > 30s).
- `lifecycle` (object, container level): lifecycle hooks for the spire-server
container. The primary use case is a preStop hook to hold the pod alive
while the load balancer deregisters the target before SIGTERM is sent:
lifecycle:
preStop:
sleep:
seconds: 60
Both fields default to their absent/empty equivalents (null and {}) so
existing deployments are unaffected.
Signed-off-by: Bronson Mirafuentes <[email protected]>
* Bump docker/login-action from 4.1.0 to 4.2.0 (#836)
Bumps [docker/login-action](https://github.com/docker/login-action) from 4.1.0 to 4.2.0.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v4.1.0...v4.2.0)
---
updated-dependencies:
- dependency-name: docker/login-action
dependency-version: 4.2.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: Bronson Mirafuentes <[email protected]>
* feat(spire-server): remove lifecycle hook support
Lifecycle hooks are not needed for the terminationGracePeriodSeconds
use case; preStop semantics can be handled outside the chart.
Signed-off-by: Bronson Mirafuentes <[email protected]>
* update README
Signed-off-by: Bronson Mirafuentes <[email protected]>
* update README
Signed-off-by: Bronson Mirafuentes <[email protected]>
---------
Signed-off-by: Bronson Mirafuentes <[email protected]>
Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* Add set_key_use configuration option
Add a setKeyUse boolean configuration option to control the set_key_use
field in the SPIFFE OIDC Discovery Provider configuration.
When enabled, this adds the 'use': 'sig' field to JWKS keys, which is
required for compatibility with Keycloak's SPIFFE identity provider.
Defaults to false to maintain backward compatibility.
Signed-off-by: Alan Cha <[email protected]>
* Fix docs
Signed-off-by: Kevin Fox <[email protected]>
---------
Signed-off-by: Alan Cha <[email protected]>
Signed-off-by: Kevin Fox <[email protected]>
Co-authored-by: Kevin Fox <[email protected]>
* Check each conditional of gather host cert in case a command to create the host cert fails
Signed-off-by: Daniel Schlatter <[email protected]>
* Change curl command to use --cacert in gather-host-cert init container
--capath is for directories. --cacert is the correct option for a single cert.
Signed-off-by: Daniel Schlatter <[email protected]>
---------
Signed-off-by: Daniel Schlatter <[email protected]>
* Fix duplicate port names in controller-manager containers
Multiple controller-manager containers were using the same "heathz" port
name, causing Kubernetes warnings about duplicate ports in the
StatefulSet. This also affected the prometheus port "prom-cm".
Changes:
* Renamed healthz port to hp-cm (health port - controller manager)
* Renamed prom-cm to pm-cm for consistency
* Addedd {{ .portSuffix }} variable to differentiate external controller
ports
* Implemented port suffix logic
The suffix logic handles cluster names by:
1. Names <9 chars: use full name as suffic
* e.g.: child01 -> -child01
2. Names with trailing numbers: preserve the number format users chose
* Detects 1-2 digit numbers with optional hyphen
* Truncates base name to fit within 15 chars
* e.g.: verlongcluster-01 -> -verylo-01
3. Names without numbers: use SHA-256 hash for uniqueness
* Trunactes name to 5 chars and appends 3-char hash
* e.g.: verlongclustername -> -veryl-a3f
The logic separates container suffix (full name) from port suffix
(truncated) so container names remain descriptive while port names stay
compliant.
Fixes#525#655
Signed-off-by: Rowan Ruseler <[email protected]>
* Add optional port name overrides for ext. controller
The auto-generated port name suffixes for external controller manager
can collide when cluster names are similar, as the 3-character has
provides only 4,096 possibilities. With the optional healthPortName and
prometheusPortName fields to cluster configuration, allows users to
explicity set port names when automatica generation creates collisions.
Signed-off-by: Rowan Ruseler <[email protected]>
* Fix portSuffix generation
Changed from "and" to "or", so portSuffic is calculated when either
healthPortName or prometheusPortName is unset.
Signed-off-by: Rowan Ruseler <[email protected]>
---------
Signed-off-by: Rowan Ruseler <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
* Add configurable hostNetwork parameter for spire-agent
Adds `hostNetwork` as a configurable parameter in the spire-agent chart.
We can now explicitly control whether the spire-agent daemonset uses
host networking.
Changes:
* Updated daemonset template
* Changed `dnsPolicy` logic to follow the computed `hostNetwork` instead
of kubelet mode directly
* Updated documentation
Behaviour:
If you leave `hostNetwork` empty (the default), it behaves like PR #705:
* automatically disables when using hostname or hostip kubelet modes
* automatically enables for localhost
If you set it explicitly to `true` or `false`, that overrides the
automatic behaviour. When `hostNetwork` is enabled and you haven't set a
custom `dnsPolicy`, it defaults to `ClusterFirstWithHostNet`.
Fixes#704
Signed-off-by: Rowan Ruseler <[email protected]>
* Fix merge conflict, different default value for fsGroupFix.image.tag
Signed-off-by: Rowan Ruseler <[email protected]>
---------
Signed-off-by: Rowan Ruseler <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
* Add ContainerResource scaling to spire-server HPA
Signed-off-by: Jayme Howard <[email protected]>
* Amend flag name to address feedback
Signed-off-by: Jayme Howard <[email protected]>
---------
Signed-off-by: Jayme Howard <[email protected]>
Co-authored-by: kfox1111 <[email protected]>
spiffe-csi-driver and spiffe-oidc-discovery provider are now brought in
line with spire-server and spire-agent, which already support podLabels.
Changes:
* Add podLabels parameter
Fixes#719
Signed-off-by: Rowan Ruseler <[email protected]>
Co-authored-by: kfox1111 <[email protected]>