Configure jwt_issuer in SPIRE OIDC Provider (#829)
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]>
This commit is contained in:
co-authored by
kfox1111
parent
4c56498e59
commit
4f8ac5af06
@@ -79,6 +79,10 @@ kubectl delete crds clusterfederatedtrustdomains.spire.spiffe.io clusterspiffeid
|
||||
|
||||
We only support upgrading one major/minor version at a time. Version skipping isn't supported. Please see <https://spiffe.io/docs/latest/spire-helm-charts-hardened-about/upgrading/> for details.
|
||||
|
||||
### 0.30.X
|
||||
|
||||
- The OIDC discovery issuer is now set automatically. We do not anticipate any negative impact; however, please verify your OIDC provider's integration with other services during your upgrade testing.
|
||||
|
||||
### 0.26.X
|
||||
|
||||
- The notifier.k8sBundle plugin has been deprecated in favor of bundlePublisher.k8sConfigMap. The only features it does not provide are the settings `apiServiceLabel` and `webhookLabel`. If you are using either of these two features, set the chart to use the notifier.k8sBundle plugin again, and let us know. We don't think anyone is using these features.
|
||||
@@ -277,7 +281,7 @@ Now you can interact with the Spire agent socket from your own application. The
|
||||
| `global.k8s.clusterDomain` | Cluster domain name configured for Spire install | `cluster.local` |
|
||||
| `global.spire.bundleConfigMap` | A configmap containing the Spire bundle | `""` |
|
||||
| `global.spire.clusterName` | The name of the k8s cluster for Spire install | `example-cluster` |
|
||||
| `global.spire.jwtIssuer` | The issuer for Spire JWT tokens. Defaults to oidc-discovery.$trustDomain if unset | `""` |
|
||||
| `global.spire.jwtIssuer` | Issuer URL used for both the JWT-SVID `iss` claim minted by spire-server and the `issuer` field advertised by the OIDC discovery document. 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 | `""` |
|
||||
|
||||
@@ -79,7 +79,7 @@ A Helm chart to install the SPIFFE OIDC discovery provider.
|
||||
| `insecureScheme.nginx.image.tag` | Overrides the image tag whose default is the chart appVersion. Only used when TLS is disabled. | `1.30.0-alpine` |
|
||||
| `insecureScheme.nginx.ipMode` | IP modes supported by the cluster. Must be one of [ipv4, ipv6, both] | `both` |
|
||||
| `insecureScheme.nginx.resources` | Resource requests and limits | `{}` |
|
||||
| `jwtIssuer` | Path to JWT issuer. Defaults to oidc-discovery.$trustDomain if unset | `""` |
|
||||
| `jwtIssuer` | Issuer URL used for the `issuer` field advertised by the OIDC discovery document. Defaults to oidc-discovery.$trustDomain if unset | `""` |
|
||||
| `config.logLevel` | The log level, valid values are "debug", "info", "warn", and "error" | `info` |
|
||||
| `config.logFormat` | The log format, valid values are "text" and "json" | `text` |
|
||||
| `config.jwtDomain` | The JWT domain. Defaults to oidc-discovery.$jwtIssuer URL-parsed host if unset | `""` |
|
||||
|
||||
@@ -56,6 +56,8 @@ server_path_prefix: {{ .Values.config.serverPathPrefix | quote }}
|
||||
set_key_use: true
|
||||
{{- end }}
|
||||
|
||||
jwt_issuer: {{ include "spire-lib.jwt-issuer" . | quote }}
|
||||
|
||||
{{- if eq .Values.bundleSource "ConfigMap" }}
|
||||
file:
|
||||
path: /bundle/bundle.spiffe
|
||||
|
||||
@@ -203,7 +203,7 @@ insecureScheme:
|
||||
# cpu: 100m
|
||||
# memory: 64Mi
|
||||
|
||||
## @param jwtIssuer Path to JWT issuer. Defaults to oidc-discovery.$trustDomain if unset
|
||||
## @param jwtIssuer Issuer URL used for the `issuer` field advertised by the OIDC discovery document. Defaults to oidc-discovery.$trustDomain if unset
|
||||
jwtIssuer: ""
|
||||
|
||||
config:
|
||||
|
||||
@@ -17,7 +17,7 @@ global:
|
||||
bundleConfigMap: ""
|
||||
## @param global.spire.clusterName The name of the k8s cluster for Spire install
|
||||
clusterName: example-cluster
|
||||
## @param global.spire.jwtIssuer The issuer for Spire JWT tokens. Defaults to oidc-discovery.$trustDomain if unset
|
||||
## @param global.spire.jwtIssuer Issuer URL used for both the JWT-SVID `iss` claim minted by spire-server and the `issuer` field advertised by the OIDC discovery document. Defaults to oidc-discovery.$trustDomain if unset
|
||||
jwtIssuer: ""
|
||||
## @param global.spire.trustDomain The trust domain for Spire install
|
||||
trustDomain: example.org
|
||||
|
||||
Reference in New Issue
Block a user