cd17bdb5f7
Proof-of-concept implementation of a potential new Supervisor feature which allows arbitrary upstream ID token claims to be mapped into a new top-level claim in the ID tokens issued by the Supervisor.
345 lines
20 KiB
YAML
345 lines
20 KiB
YAML
---
|
|
apiVersion: apiextensions.k8s.io/v1
|
|
kind: CustomResourceDefinition
|
|
metadata:
|
|
annotations:
|
|
controller-gen.kubebuilder.io/version: v0.8.0
|
|
creationTimestamp: null
|
|
name: oidcidentityproviders.idp.supervisor.pinniped.dev
|
|
spec:
|
|
group: idp.supervisor.pinniped.dev
|
|
names:
|
|
categories:
|
|
- pinniped
|
|
- pinniped-idp
|
|
- pinniped-idps
|
|
kind: OIDCIdentityProvider
|
|
listKind: OIDCIdentityProviderList
|
|
plural: oidcidentityproviders
|
|
singular: oidcidentityprovider
|
|
scope: Namespaced
|
|
versions:
|
|
- additionalPrinterColumns:
|
|
- jsonPath: .spec.issuer
|
|
name: Issuer
|
|
type: string
|
|
- jsonPath: .status.phase
|
|
name: Status
|
|
type: string
|
|
- jsonPath: .metadata.creationTimestamp
|
|
name: Age
|
|
type: date
|
|
name: v1alpha1
|
|
schema:
|
|
openAPIV3Schema:
|
|
description: OIDCIdentityProvider describes the configuration of an upstream
|
|
OpenID Connect identity provider.
|
|
properties:
|
|
apiVersion:
|
|
description: 'APIVersion defines the versioned schema of this representation
|
|
of an object. Servers should convert recognized schemas to the latest
|
|
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
|
type: string
|
|
kind:
|
|
description: 'Kind is a string value representing the REST resource this
|
|
object represents. Servers may infer this from the endpoint the client
|
|
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
|
type: string
|
|
metadata:
|
|
type: object
|
|
spec:
|
|
description: Spec for configuring the identity provider.
|
|
properties:
|
|
authorizationConfig:
|
|
description: AuthorizationConfig holds information about how to form
|
|
the OAuth2 authorization request parameters to be used with this
|
|
OIDC identity provider.
|
|
properties:
|
|
additionalAuthorizeParameters:
|
|
description: additionalAuthorizeParameters are extra query parameters
|
|
that should be included in the authorize request to your OIDC
|
|
provider in the authorization request during an OIDC Authorization
|
|
Code Flow. By default, no extra parameters are sent. The standard
|
|
parameters that will be sent are "response_type", "scope", "client_id",
|
|
"state", "nonce", "code_challenge", "code_challenge_method",
|
|
and "redirect_uri". These parameters cannot be included in this
|
|
setting. Additionally, the "hd" parameter cannot be included
|
|
in this setting at this time. The "hd" parameter is used by
|
|
Google's OIDC provider to provide a hint as to which "hosted
|
|
domain" the user should use during login. However, Pinniped
|
|
does not yet support validating the hosted domain in the resulting
|
|
ID token, so it is not yet safe to use this feature of Google's
|
|
OIDC provider with Pinniped. This setting does not influence
|
|
the parameters sent to the token endpoint in the Resource Owner
|
|
Password Credentials Grant. The Pinniped Supervisor requires
|
|
that your OIDC provider returns refresh tokens to the Supervisor
|
|
from the authorization flows. Some OIDC providers may require
|
|
a certain value for the "prompt" parameter in order to properly
|
|
request refresh tokens. See the documentation of your OIDC provider's
|
|
authorization endpoint for its requirements for what to include
|
|
in the request in order to receive a refresh token in the response,
|
|
if anything. If your provider requires the prompt parameter
|
|
to request a refresh token, then include it here. Also note
|
|
that most providers also require a certain scope to be requested
|
|
in order to receive refresh tokens. See the additionalScopes
|
|
setting for more information about using scopes to request refresh
|
|
tokens.
|
|
items:
|
|
description: Parameter is a key/value pair which represents
|
|
a parameter in an HTTP request.
|
|
properties:
|
|
name:
|
|
description: The name of the parameter. Required.
|
|
minLength: 1
|
|
type: string
|
|
value:
|
|
description: The value of the parameter.
|
|
type: string
|
|
required:
|
|
- name
|
|
type: object
|
|
type: array
|
|
x-kubernetes-list-map-keys:
|
|
- name
|
|
x-kubernetes-list-type: map
|
|
additionalScopes:
|
|
description: 'additionalScopes are the additional scopes that
|
|
will be requested from your OIDC provider in the authorization
|
|
request during an OIDC Authorization Code Flow and in the token
|
|
request during a Resource Owner Password Credentials Grant.
|
|
Note that the "openid" scope will always be requested regardless
|
|
of the value in this setting, since it is always required according
|
|
to the OIDC spec. By default, when this field is not set, the
|
|
Supervisor will request the following scopes: "openid", "offline_access",
|
|
"email", and "profile". See https://openid.net/specs/openid-connect-core-1_0.html#ScopeClaims
|
|
for a description of the "profile" and "email" scopes. See https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess
|
|
for a description of the "offline_access" scope. This default
|
|
value may change in future versions of Pinniped as the standard
|
|
evolves, or as common patterns used by providers who implement
|
|
the standard in the ecosystem evolve. By setting this list to
|
|
anything other than an empty list, you are overriding the default
|
|
value, so you may wish to include some of "offline_access",
|
|
"email", and "profile" in your override list. If you do not
|
|
want any of these scopes to be requested, you may set this list
|
|
to contain only "openid". Some OIDC providers may also require
|
|
a scope to get access to the user''s group membership, in which
|
|
case you may wish to include it in this list. Sometimes the
|
|
scope to request the user''s group membership is called "groups",
|
|
but unfortunately this is not specified in the OIDC standard.
|
|
Generally speaking, you should include any scopes required to
|
|
cause the appropriate claims to be the returned by your OIDC
|
|
provider in the ID token or userinfo endpoint results for those
|
|
claims which you would like to use in the oidcClaims settings
|
|
to determine the usernames and group memberships of your Kubernetes
|
|
users. See your OIDC provider''s documentation for more information
|
|
about what scopes are available to request claims. Additionally,
|
|
the Pinniped Supervisor requires that your OIDC provider returns
|
|
refresh tokens to the Supervisor from these authorization flows.
|
|
For most OIDC providers, the scope required to receive refresh
|
|
tokens will be "offline_access". See the documentation of your
|
|
OIDC provider''s authorization and token endpoints for its requirements
|
|
for what to include in the request in order to receive a refresh
|
|
token in the response, if anything. Note that it may be safe
|
|
to send "offline_access" even to providers which do not require
|
|
it, since the provider may ignore scopes that it does not understand
|
|
or require (see https://datatracker.ietf.org/doc/html/rfc6749#section-3.3).
|
|
In the unusual case that you must avoid sending the "offline_access"
|
|
scope, then you must override the default value of this setting.
|
|
This is required if your OIDC provider will reject the request
|
|
when it includes "offline_access" (e.g. GitLab''s OIDC provider).'
|
|
items:
|
|
type: string
|
|
type: array
|
|
allowPasswordGrant:
|
|
description: allowPasswordGrant, when true, will allow the use
|
|
of OAuth 2.0's Resource Owner Password Credentials Grant (see
|
|
https://datatracker.ietf.org/doc/html/rfc6749#section-4.3) to
|
|
authenticate to the OIDC provider using a username and password
|
|
without a web browser, in addition to the usual browser-based
|
|
OIDC Authorization Code Flow. The Resource Owner Password Credentials
|
|
Grant is not officially part of the OIDC specification, so it
|
|
may not be supported by your OIDC provider. If your OIDC provider
|
|
supports returning ID tokens from a Resource Owner Password
|
|
Credentials Grant token request, then you can choose to set
|
|
this field to true. This will allow end users to choose to present
|
|
their username and password to the kubectl CLI (using the Pinniped
|
|
plugin) to authenticate to the cluster, without using a web
|
|
browser to log in as is customary in OIDC Authorization Code
|
|
Flow. This may be convenient for users, especially for identities
|
|
from your OIDC provider which are not intended to represent
|
|
a human actor, such as service accounts performing actions in
|
|
a CI/CD environment. Even if your OIDC provider supports it,
|
|
you may wish to disable this behavior by setting this field
|
|
to false when you prefer to only allow users of this OIDCIdentityProvider
|
|
to log in via the browser-based OIDC Authorization Code Flow.
|
|
Using the Resource Owner Password Credentials Grant means that
|
|
the Pinniped CLI and Pinniped Supervisor will directly handle
|
|
your end users' passwords (similar to LDAPIdentityProvider),
|
|
and you will not be able to require multi-factor authentication
|
|
or use the other web-based login features of your OIDC provider
|
|
during Resource Owner Password Credentials Grant logins. allowPasswordGrant
|
|
defaults to false.
|
|
type: boolean
|
|
type: object
|
|
claims:
|
|
description: Claims provides the names of token claims that will be
|
|
used when inspecting an identity from this OIDC identity provider.
|
|
properties:
|
|
additionalClaimMappings:
|
|
additionalProperties:
|
|
type: string
|
|
description: AdditionalClaimMappings allows for additional arbitrary
|
|
upstream claim values to be mapped into the "additionalClaims"
|
|
claim of the ID tokens generated by the Supervisor. This should
|
|
be specified as a map of new claim names as the keys, and upstream
|
|
claim names as the values. These new claim names will be nested
|
|
under the top-level "additionalClaims" claim in ID tokens generated
|
|
by the Supervisor when this OIDCIdentityProvider was used for
|
|
user authentication. This feature is not required for using
|
|
the Supervisor to provide authentication for Kubernetes clusters,
|
|
but can be used when using the Supervisor for other authentication
|
|
purposes. When this map is empty, the "additionalClaims" claim
|
|
will be excluded from the ID tokens generated by the Supervisor.
|
|
type: object
|
|
groups:
|
|
description: Groups provides the name of the ID token claim or
|
|
userinfo endpoint response claim that will be used to ascertain
|
|
the groups to which an identity belongs. By default, the identities
|
|
will not include any group memberships when this setting is
|
|
not configured.
|
|
type: string
|
|
username:
|
|
description: Username provides the name of the ID token claim
|
|
or userinfo endpoint response claim that will be used to ascertain
|
|
an identity's username. When not set, the username will be an
|
|
automatically constructed unique string which will include the
|
|
issuer URL of your OIDC provider along with the value of the
|
|
"sub" (subject) claim from the ID token.
|
|
type: string
|
|
type: object
|
|
client:
|
|
description: OIDCClient contains OIDC client information to be used
|
|
used with this OIDC identity provider.
|
|
properties:
|
|
secretName:
|
|
description: SecretName contains the name of a namespace-local
|
|
Secret object that provides the clientID and clientSecret for
|
|
an OIDC client. If only the SecretName is specified in an OIDCClient
|
|
struct, then it is expected that the Secret is of type "secrets.pinniped.dev/oidc-client"
|
|
with keys "clientID" and "clientSecret".
|
|
type: string
|
|
required:
|
|
- secretName
|
|
type: object
|
|
issuer:
|
|
description: Issuer is the issuer URL of this OIDC identity provider,
|
|
i.e., where to fetch /.well-known/openid-configuration.
|
|
minLength: 1
|
|
pattern: ^https://
|
|
type: string
|
|
tls:
|
|
description: TLS configuration for discovery/JWKS requests to the
|
|
issuer.
|
|
properties:
|
|
certificateAuthorityData:
|
|
description: X.509 Certificate Authority (base64-encoded PEM bundle).
|
|
If omitted, a default set of system roots will be trusted.
|
|
type: string
|
|
type: object
|
|
required:
|
|
- client
|
|
- issuer
|
|
type: object
|
|
status:
|
|
description: Status of the identity provider.
|
|
properties:
|
|
conditions:
|
|
description: Represents the observations of an identity provider's
|
|
current state.
|
|
items:
|
|
description: Condition status of a resource (mirrored from the metav1.Condition
|
|
type added in Kubernetes 1.19). In a future API version we can
|
|
switch to using the upstream type. See https://github.com/kubernetes/apimachinery/blob/v0.19.0/pkg/apis/meta/v1/types.go#L1353-L1413.
|
|
properties:
|
|
lastTransitionTime:
|
|
description: lastTransitionTime is the last time the condition
|
|
transitioned from one status to another. This should be when
|
|
the underlying condition changed. If that is not known, then
|
|
using the time when the API field changed is acceptable.
|
|
format: date-time
|
|
type: string
|
|
message:
|
|
description: message is a human readable message indicating
|
|
details about the transition. This may be an empty string.
|
|
maxLength: 32768
|
|
type: string
|
|
observedGeneration:
|
|
description: observedGeneration represents the .metadata.generation
|
|
that the condition was set based upon. For instance, if .metadata.generation
|
|
is currently 12, but the .status.conditions[x].observedGeneration
|
|
is 9, the condition is out of date with respect to the current
|
|
state of the instance.
|
|
format: int64
|
|
minimum: 0
|
|
type: integer
|
|
reason:
|
|
description: reason contains a programmatic identifier indicating
|
|
the reason for the condition's last transition. Producers
|
|
of specific condition types may define expected values and
|
|
meanings for this field, and whether the values are considered
|
|
a guaranteed API. The value should be a CamelCase string.
|
|
This field may not be empty.
|
|
maxLength: 1024
|
|
minLength: 1
|
|
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
|
type: string
|
|
status:
|
|
description: status of the condition, one of True, False, Unknown.
|
|
enum:
|
|
- "True"
|
|
- "False"
|
|
- Unknown
|
|
type: string
|
|
type:
|
|
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
|
--- Many .condition.type values are consistent across resources
|
|
like Available, but because arbitrary conditions can be useful
|
|
(see .node.status.conditions), the ability to deconflict is
|
|
important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
|
|
maxLength: 316
|
|
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
|
type: string
|
|
required:
|
|
- lastTransitionTime
|
|
- message
|
|
- reason
|
|
- status
|
|
- type
|
|
type: object
|
|
type: array
|
|
x-kubernetes-list-map-keys:
|
|
- type
|
|
x-kubernetes-list-type: map
|
|
phase:
|
|
default: Pending
|
|
description: Phase summarizes the overall status of the OIDCIdentityProvider.
|
|
enum:
|
|
- Pending
|
|
- Ready
|
|
- Error
|
|
type: string
|
|
type: object
|
|
required:
|
|
- spec
|
|
type: object
|
|
served: true
|
|
storage: true
|
|
subresources:
|
|
status: {}
|
|
status:
|
|
acceptedNames:
|
|
kind: ""
|
|
plural: ""
|
|
conditions: []
|
|
storedVersions: []
|