mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-10-31 22:01:06 +00:00
Provide OIDC discovery endpoints
- Add handlers for service account issuer metadata. - Add option to manually override JWKS URI. - Add unit and integration tests. - Add a separate ServiceAccountIssuerDiscovery feature gate. Additional notes: - If not explicitly overridden, the JWKS URI will be based on the API server's external address and port. - The metadata server is configured with the validating key set rather than the signing key set. This allows for key rotation because tokens can still be validated by the keys exposed in the JWKs URL, even if the signing key has been rotated (note this may still be a short window if tokens have short lifetimes). - The trust model of OIDC discovery requires that the relying party fetch the issuer metadata via HTTPS; the trust of the issuer metadata comes from the server presenting a TLS certificate with a trust chain back to the from the relying party's root(s) of trust. For tests, we use a local issuer (https://kubernetes.default.svc) for the certificate so that workloads within the cluster can authenticate it when fetching OIDC metadata. An API server cannot validly claim https://kubernetes.io, but within the cluster, it is the authority for kubernetes.default.svc, according to the in-cluster config. Co-authored-by: Michael Taufen <mtaufen@google.com>
This commit is contained in:
committed by
Michael Taufen
parent
7a506ff342
commit
5a176ac772
@@ -191,6 +191,11 @@ type ExtraConfig struct {
|
||||
ServiceAccountIssuer serviceaccount.TokenGenerator
|
||||
ServiceAccountMaxExpiration time.Duration
|
||||
|
||||
// ServiceAccountIssuerDiscovery
|
||||
ServiceAccountIssuerURL string
|
||||
ServiceAccountJWKSURI string
|
||||
ServiceAccountPublicKeys []interface{}
|
||||
|
||||
VersionedInformers informers.SharedInformerFactory
|
||||
}
|
||||
|
||||
@@ -342,6 +347,39 @@ func (c completedConfig) New(delegationTarget genericapiserver.DelegationTarget)
|
||||
routes.Logs{}.Install(s.Handler.GoRestfulContainer)
|
||||
}
|
||||
|
||||
if utilfeature.DefaultFeatureGate.Enabled(features.ServiceAccountIssuerDiscovery) {
|
||||
// Metadata and keys are expected to only change across restarts at present,
|
||||
// so we just marshal immediately and serve the cached JSON bytes.
|
||||
md, err := serviceaccount.NewOpenIDMetadata(
|
||||
c.ExtraConfig.ServiceAccountIssuerURL,
|
||||
c.ExtraConfig.ServiceAccountJWKSURI,
|
||||
c.GenericConfig.ExternalAddress,
|
||||
c.ExtraConfig.ServiceAccountPublicKeys,
|
||||
)
|
||||
if err != nil {
|
||||
// If there was an error, skip installing the endpoints and log the
|
||||
// error, but continue on. We don't return the error because the
|
||||
// metadata responses require additional, backwards incompatible
|
||||
// validation of command-line options.
|
||||
msg := fmt.Sprintf("Could not construct pre-rendered responses for"+
|
||||
" ServiceAccountIssuerDiscovery endpoints. Endpoints will not be"+
|
||||
" enabled. Error: %v", err)
|
||||
if c.ExtraConfig.ServiceAccountIssuerURL != "" {
|
||||
// The user likely expects this feature to be enabled if issuer URL is
|
||||
// set and the feature gate is enabled. In the future, if there is no
|
||||
// longer a feature gate and issuer URL is not set, the user may not
|
||||
// expect this feature to be enabled. We log the former case as an Error
|
||||
// and the latter case as an Info.
|
||||
klog.Error(msg)
|
||||
} else {
|
||||
klog.Info(msg)
|
||||
}
|
||||
} else {
|
||||
routes.NewOpenIDMetadataServer(md.ConfigJSON, md.PublicKeysetJSON).
|
||||
Install(s.Handler.GoRestfulContainer)
|
||||
}
|
||||
}
|
||||
|
||||
m := &Master{
|
||||
GenericAPIServer: s,
|
||||
ClusterAuthenticationInfo: c.ExtraConfig.ClusterAuthenticationInfo,
|
||||
|
||||
Reference in New Issue
Block a user