Skip to content

Commit 06d47f6

Browse files
authored
feat: oidc access (#88)
* implement oidc access logic * implement oidc resource deletion * fix typo * fix tests * fix bug * add tests for oidc accessrequests * use K8sNameUUID instead of K8sNameHash * task generate * task generate * bump dependency
1 parent a5aa87f commit 06d47f6

File tree

15 files changed

+1118
-237
lines changed

15 files changed

+1118
-237
lines changed

api/core/v1alpha1/constants/reasons.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const (
44
// ReasonGardenClusterInteractionProblem is used when the garden cluster cannot be reached.
55
ReasonGardenClusterInteractionProblem = "GardenClusterInteractionProblem"
66
// ReasonShootClusterInteractionProblem is used when the shoot cluster cannot be reached.
7-
ReasonShootClusterInteractionProblem = "GardenClusterInteractionProblem"
7+
ReasonShootClusterInteractionProblem = "ShootClusterInteractionProblem"
88
// ReasonKubeconfigError indicates that the rest config could not be created.
99
ReasonKubeconfigError = "KubeconfigError"
1010
// ReasonInvalidReference indicates that a reference points to a non-existing or otherwise wrong resource.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-FileCopyrightText: 2021 SAP SE or an SAP affiliate company and Gardener contributors
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
// Package v1alpha1 contains API Schema definitions for the authentication v1alpha1 API group
6+
// +kubebuilder:object:generate=true
7+
// +groupName=authentication.gardener.cloud
8+
package v1alpha1
9+
10+
import (
11+
"k8s.io/apimachinery/pkg/runtime/schema"
12+
"sigs.k8s.io/controller-runtime/pkg/scheme"
13+
)
14+
15+
var (
16+
// GroupVersion is group version used to register these objects
17+
GroupVersion = schema.GroupVersion{Group: "authentication.gardener.cloud", Version: "v1alpha1"}
18+
19+
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
20+
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
21+
22+
// AddToScheme adds the types in this group-version to the given scheme.
23+
AddToScheme = SchemeBuilder.AddToScheme
24+
)
Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
// SPDX-FileCopyrightText: 2021 SAP SE or an SAP affiliate company and Gardener contributors
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package v1alpha1
6+
7+
import (
8+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
9+
)
10+
11+
// +kubebuilder:object:root=true
12+
// +kubebuilder:subresource:status
13+
// +kubebuilder:resource:path=openidconnects,scope=Cluster,shortName=oidc;oidcs
14+
// +kubebuilder:printcolumn:name="Issuer",type=string,JSONPath=`.spec.issuerURL`,description="Issuer is the URL the provider signs ID Tokens as"
15+
// +kubebuilder:printcolumn:name="Client ID",type=string,JSONPath=`.spec.clientID`,description="ClientID is the audience for which this ID Token is issued for"
16+
// +kubebuilder:printcolumn:name="Username Claim",type=string,JSONPath=`.spec.usernameClaim`,description="Username claim is the JWT field to use as the user's username"
17+
// +kubebuilder:printcolumn:name="Groups Claim",type=string,JSONPath=`.spec.groupsClaim`,description="Groups claim is the JWT field to use as the user's groups"
18+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=`.metadata.creationTimestamp`,description="CreationTimestamp is a timestamp representing the server time when this object was created"
19+
20+
// OpenIDConnect allows to dynamically register OpenID Connect providers used
21+
// to authenticate against the kube-apiserver.
22+
type OpenIDConnect struct {
23+
metav1.TypeMeta `json:",inline"`
24+
25+
metav1.ObjectMeta `json:"metadata,omitempty"`
26+
27+
Spec OIDCAuthenticationSpec `json:"spec"`
28+
Status OIDCAuthenticationStatus `json:"status,omitempty"`
29+
}
30+
31+
// +kubebuilder:object:root=true
32+
33+
// OpenIDConnectList contains a list of OpenIDConnect
34+
type OpenIDConnectList struct {
35+
metav1.TypeMeta `json:",inline"`
36+
metav1.ListMeta `json:"metadata,omitempty"`
37+
Items []OpenIDConnect `json:"items"`
38+
}
39+
40+
// OIDCAuthenticationSpec defines the desired state of OpenIDConnect
41+
type OIDCAuthenticationSpec struct {
42+
43+
// +kubebuilder:validation:Required
44+
// +kubebuilder:validation:Pattern=`^https:\/\/`
45+
46+
// IssuerURL is the URL the provider signs ID Tokens as. This will be the "iss"
47+
// field of all tokens produced by the provider and is used for configuration
48+
// discovery.
49+
//
50+
// The URL is usually the provider's URL without a path, for example
51+
// "https://foo.com" or "https://example.com".
52+
//
53+
// The provider must implement configuration discovery.
54+
// See: https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig
55+
IssuerURL string `json:"issuerURL"`
56+
57+
// +kubebuilder:validation:Required
58+
// +kubebuilder:validation:MinLength=1
59+
60+
// ClientID is the audience for which the JWT must be issued for, the "aud" field.
61+
//
62+
// The plugin supports the "authorized party" OpenID Connect claim, which allows
63+
// specialized providers to issue tokens to a client for a different client.
64+
// See: https://openid.net/specs/openid-connect-core-1_0.html#IDToken
65+
ClientID string `json:"clientID"`
66+
67+
// +kubebuilder:validation:Required
68+
// +kubebuilder:validation:MinLength=1
69+
70+
// UsernameClaim is the JWT field to use as the user's username.
71+
UsernameClaim *string `json:"usernameClaim"`
72+
73+
// +optional
74+
75+
// UsernamePrefix, if specified, causes claims mapping to username to be prefix with
76+
// the provided value. A value "oidc:" would result in usernames like "oidc:john".
77+
//
78+
// If not provided, the prefix defaults to "( .metadata.name )/".
79+
// The value "-" can be used to disable all prefixing.
80+
UsernamePrefix *string `json:"usernamePrefix,omitempty"`
81+
82+
// +optional
83+
84+
// GroupsClaim, if specified, causes the OIDCAuthenticator to try to populate the user's
85+
// groups with an ID Token field. If the GroupsClaim field is present in an ID Token the value
86+
// must be a string or list of strings.
87+
GroupsClaim *string `json:"groupsClaim,omitempty"`
88+
89+
// +optional
90+
91+
// GroupsPrefix, if specified, causes claims mapping to group names to be prefixed with the
92+
// value. A value "oidc:" would result in groups like "oidc:engineering" and "oidc:marketing".
93+
//
94+
// If not provided, the prefix defaults to "( .metadata.name )/".
95+
// The value "-" can be used to disable all prefixing.
96+
GroupsPrefix *string `json:"groupsPrefix,omitempty"`
97+
98+
// +kubebuilder:default={RS256}
99+
100+
// SupportedSigningAlgs sets the accepted set of JOSE signing algorithms that
101+
// can be used by the provider to sign tokens.
102+
//
103+
// https://tools.ietf.org/html/rfc7518#section-3.1
104+
//
105+
// This value defaults to RS256, the value recommended by the OpenID Connect
106+
// spec:
107+
//
108+
// https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation
109+
SupportedSigningAlgs []SigningAlgorithm `json:"supportedSigningAlgs,omitempty"`
110+
111+
// +optional
112+
113+
// RequiredClaims, if specified, causes the OIDCAuthenticator to verify that all the
114+
// required claims key value pairs are present in the ID Token.
115+
RequiredClaims map[string]string `json:"requiredClaims,omitempty"`
116+
117+
// +optional
118+
119+
// ExtraClaims, if specified, causes the OIDCAuthenticator to copy listed claims to the
120+
// user Extra field.
121+
// Claims will be converted to lower case and prefixed with "gardener.cloud/user/" before being copied.
122+
// If any of the extra claims is not present in the token then the token will be rejected.
123+
ExtraClaims []string `json:"extraClaims,omitempty"`
124+
125+
// +optional
126+
127+
// CABundle is a PEM encoded CA bundle which will be used to validate the OpenID server's certificate.
128+
// If unspecified, system's trusted certificates are used.
129+
CABundle []byte `json:"caBundle,omitempty"`
130+
131+
// +optional
132+
133+
// JWKS if specified, provides an option to specify JWKS keys offline.
134+
JWKS JWKSSpec `json:"jwks,omitempty"`
135+
136+
// +optional
137+
138+
// MaxTokenExpirationSeconds if specified, sets a limit in seconds to the maximum validity duration of a token.
139+
// Tokens issued with validity greater that this value will not be verified.
140+
// Setting this will require that the tokens have the "iat" and "exp" claims.
141+
MaxTokenExpirationSeconds *int64 `json:"maxTokenExpirationSeconds,omitempty"`
142+
}
143+
144+
// +kubebuilder:validation:Enum=RS256;RS384;RS512;ES256;ES384;ES512;PS256;PS384;PS512
145+
146+
// SigningAlgorithm is JOSE asymmetric signing algorithm value as defined by RFC 7518
147+
type SigningAlgorithm string
148+
149+
// JWKSSpec defines the configuration for specifying JWKS keys offline.
150+
type JWKSSpec struct {
151+
// `keys` is a base64 encoded JSON webkey Set. If specified, the OIDCAuthenticator skips the request to the issuer's jwks_uri endpoint to retrieve the keys.
152+
Keys []byte `json:"keys,omitempty"`
153+
154+
// +kubebuilder:default=true
155+
// `distributedClaims` enables the OIDCAuthenticator to return references to claims that are asserted by external Claims providers.
156+
DistributedClaims *bool `json:"distributedClaims,omitempty"`
157+
}
158+
159+
const (
160+
// RS256 is RSASSA-PKCS-v1.5 using SHA-256
161+
// This is the default value.
162+
RS256 SigningAlgorithm = "RS256"
163+
// RS384 is RSASSA-PKCS-v1.5 using SHA-384
164+
RS384 SigningAlgorithm = "RS384"
165+
// RS512 is RSASSA-PKCS-v1.5 using SHA-512
166+
RS512 SigningAlgorithm = "RS512"
167+
// ES256 is ECDSA using P-256 and SHA-256
168+
ES256 SigningAlgorithm = "ES256"
169+
// ES384 is ECDSA using P-384 and SHA-384
170+
ES384 SigningAlgorithm = "ES384"
171+
// ES512 is ECDSA using P-521 and SHA-512
172+
ES512 SigningAlgorithm = "ES512"
173+
// PS256 is RSASSA-PSS using SHA256 and MGF1-SHA256
174+
PS256 SigningAlgorithm = "PS256"
175+
// PS384 is RSASSA-PSS using SHA384 and MGF1-SHA384
176+
PS384 SigningAlgorithm = "PS384"
177+
// PS512 is RSASSA-PSS using SHA512 and MGF1-SHA512
178+
PS512 SigningAlgorithm = "PS512"
179+
)
180+
181+
const (
182+
// ClaimPrefixingDisabled indicates that username or groups claim should not be
183+
// prefixed automatically.
184+
ClaimPrefixingDisabled = "-"
185+
186+
// SystemPrefix is a forbidden prefix. Usernames and groups starting with this value will be ignored.
187+
SystemPrefix = "system:"
188+
)
189+
190+
// OIDCAuthenticationStatus is the status of a OpenIDConnect resource.
191+
type OIDCAuthenticationStatus struct{}
192+
193+
func init() {
194+
SchemeBuilder.Register(&OpenIDConnect{}, &OpenIDConnectList{})
195+
}

0 commit comments

Comments
 (0)