Skip to content

Commit ad808e6

Browse files
committed
KEP-3221: Promote StructuredAuthorizationConfiguration to GA
1 parent ded7ad5 commit ad808e6

File tree

13 files changed

+496
-81
lines changed

13 files changed

+496
-81
lines changed

pkg/features/versioned_kube_features.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
308308
genericfeatures.StructuredAuthorizationConfiguration: {
309309
{Version: version.MustParse("1.29"), Default: false, PreRelease: featuregate.Alpha},
310310
{Version: version.MustParse("1.30"), Default: true, PreRelease: featuregate.Beta},
311+
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.GA, LockToDefault: true},
311312
},
312313

313314
genericfeatures.UnauthenticatedHTTP2DOSMitigation: {

staging/src/k8s.io/apiserver/pkg/apis/apiserver/load/load_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,45 @@ apiVersion: apiserver.config.k8s.io/v1beta1
265265
kind: AuthorizationConfiguration
266266
authorizers:
267267
- type: Webhook
268+
`),
269+
expectConfig: &api.AuthorizationConfiguration{
270+
Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
271+
},
272+
},
273+
{
274+
name: "v1 - json",
275+
data: []byte(`{
276+
"apiVersion":"apiserver.config.k8s.io/v1",
277+
"kind":"AuthorizationConfiguration",
278+
"authorizers":[{"type":"Webhook"}]}`),
279+
expectConfig: &api.AuthorizationConfiguration{
280+
Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},
281+
},
282+
},
283+
{
284+
name: "v1 - defaults",
285+
data: []byte(`{
286+
"apiVersion":"apiserver.config.k8s.io/v1",
287+
"kind":"AuthorizationConfiguration",
288+
"authorizers":[{"type":"Webhook","name":"default","webhook":{}}]}`),
289+
expectConfig: &api.AuthorizationConfiguration{
290+
Authorizers: []api.AuthorizerConfiguration{{
291+
Type: "Webhook",
292+
Name: "default",
293+
Webhook: &api.WebhookConfiguration{
294+
AuthorizedTTL: metav1.Duration{Duration: 5 * time.Minute},
295+
UnauthorizedTTL: metav1.Duration{Duration: 30 * time.Second},
296+
},
297+
}},
298+
},
299+
},
300+
{
301+
name: "v1 - yaml",
302+
data: []byte(`
303+
apiVersion: apiserver.config.k8s.io/v1
304+
kind: AuthorizationConfiguration
305+
authorizers:
306+
- type: Webhook
268307
`),
269308
expectConfig: &api.AuthorizationConfiguration{
270309
Authorizers: []api.AuthorizerConfiguration{{Type: "Webhook"}},

staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/defaults.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,12 @@ func SetDefaults_KMSConfiguration(obj *KMSConfiguration) {
4848
obj.CacheSize = &defaultCacheSize
4949
}
5050
}
51+
52+
func SetDefaults_WebhookConfiguration(obj *WebhookConfiguration) {
53+
if obj.AuthorizedTTL.Duration == 0 {
54+
obj.AuthorizedTTL.Duration = 5 * time.Minute
55+
}
56+
if obj.UnauthorizedTTL.Duration == 0 {
57+
obj.UnauthorizedTTL.Duration = 30 * time.Second
58+
}
59+
}

staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/register.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func init() {
4747
func addKnownTypes(scheme *runtime.Scheme) error {
4848
scheme.AddKnownTypes(SchemeGroupVersion,
4949
&AdmissionConfiguration{},
50+
&AuthorizationConfiguration{},
5051
&EncryptionConfiguration{},
5152
)
5253
// also register into the v1 group as EncryptionConfig (due to a docs bug)

staging/src/k8s.io/apiserver/pkg/apis/apiserver/v1/types.go

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,122 @@ type AdmissionPluginConfiguration struct {
4848
// +optional
4949
Configuration *runtime.Unknown `json:"configuration"`
5050
}
51+
52+
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
53+
54+
type AuthorizationConfiguration struct {
55+
metav1.TypeMeta
56+
57+
// Authorizers is an ordered list of authorizers to
58+
// authorize requests against.
59+
// This is similar to the --authorization-modes kube-apiserver flag
60+
// Must be at least one.
61+
Authorizers []AuthorizerConfiguration `json:"authorizers"`
62+
}
63+
64+
const (
65+
TypeWebhook AuthorizerType = "Webhook"
66+
FailurePolicyNoOpinion string = "NoOpinion"
67+
FailurePolicyDeny string = "Deny"
68+
AuthorizationWebhookConnectionInfoTypeKubeConfigFile string = "KubeConfigFile"
69+
AuthorizationWebhookConnectionInfoTypeInCluster string = "InClusterConfig"
70+
)
71+
72+
type AuthorizerType string
73+
74+
type AuthorizerConfiguration struct {
75+
// Type refers to the type of the authorizer
76+
// "Webhook" is supported in the generic API server
77+
// Other API servers may support additional authorizer
78+
// types like Node, RBAC, ABAC, etc.
79+
Type string `json:"type"`
80+
81+
// Name used to describe the webhook
82+
// This is explicitly used in monitoring machinery for metrics
83+
// Note: Names must be DNS1123 labels like `myauthorizername` or
84+
// subdomains like `myauthorizer.example.domain`
85+
// Required, with no default
86+
Name string `json:"name"`
87+
88+
// Webhook defines the configuration for a Webhook authorizer
89+
// Must be defined when Type=Webhook
90+
// Must not be defined when Type!=Webhook
91+
Webhook *WebhookConfiguration `json:"webhook,omitempty"`
92+
}
93+
94+
type WebhookConfiguration struct {
95+
// The duration to cache 'authorized' responses from the webhook
96+
// authorizer.
97+
// Same as setting `--authorization-webhook-cache-authorized-ttl` flag
98+
// Default: 5m0s
99+
AuthorizedTTL metav1.Duration `json:"authorizedTTL"`
100+
// The duration to cache 'unauthorized' responses from the webhook
101+
// authorizer.
102+
// Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag
103+
// Default: 30s
104+
UnauthorizedTTL metav1.Duration `json:"unauthorizedTTL"`
105+
// Timeout for the webhook request
106+
// Maximum allowed value is 30s.
107+
// Required, no default value.
108+
Timeout metav1.Duration `json:"timeout"`
109+
// The API version of the authorization.k8s.io SubjectAccessReview to
110+
// send to and expect from the webhook.
111+
// Same as setting `--authorization-webhook-version` flag
112+
// Valid values: v1beta1, v1
113+
// Required, no default value
114+
SubjectAccessReviewVersion string `json:"subjectAccessReviewVersion"`
115+
// MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview
116+
// version the CEL expressions are evaluated against
117+
// Valid values: v1
118+
// Required, no default value
119+
MatchConditionSubjectAccessReviewVersion string `json:"matchConditionSubjectAccessReviewVersion"`
120+
// Controls the authorization decision when a webhook request fails to
121+
// complete or returns a malformed response or errors evaluating
122+
// matchConditions.
123+
// Valid values:
124+
// - NoOpinion: continue to subsequent authorizers to see if one of
125+
// them allows the request
126+
// - Deny: reject the request without consulting subsequent authorizers
127+
// Required, with no default.
128+
FailurePolicy string `json:"failurePolicy"`
129+
130+
// ConnectionInfo defines how we talk to the webhook
131+
ConnectionInfo WebhookConnectionInfo `json:"connectionInfo"`
132+
133+
// matchConditions is a list of conditions that must be met for a request to be sent to this
134+
// webhook. An empty list of matchConditions matches all requests.
135+
// There are a maximum of 64 match conditions allowed.
136+
//
137+
// The exact matching logic is (in order):
138+
// 1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.
139+
// 2. If ALL matchConditions evaluate to TRUE, then the webhook is called.
140+
// 3. If at least one matchCondition evaluates to an error (but none are FALSE):
141+
// - If failurePolicy=Deny, then the webhook rejects the request
142+
// - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped
143+
MatchConditions []WebhookMatchCondition `json:"matchConditions"`
144+
}
145+
146+
type WebhookConnectionInfo struct {
147+
// Controls how the webhook should communicate with the server.
148+
// Valid values:
149+
// - KubeConfigFile: use the file specified in kubeConfigFile to locate the
150+
// server.
151+
// - InClusterConfig: use the in-cluster configuration to call the
152+
// SubjectAccessReview API hosted by kube-apiserver. This mode is not
153+
// allowed for kube-apiserver.
154+
Type string `json:"type"`
155+
156+
// Path to KubeConfigFile for connection info
157+
// Required, if connectionInfo.Type is KubeConfig
158+
KubeConfigFile *string `json:"kubeConfigFile"`
159+
}
160+
161+
type WebhookMatchCondition struct {
162+
// expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
163+
// CEL expressions have access to the contents of the SubjectAccessReview in v1 version.
164+
// If version specified by subjectAccessReviewVersion in the request variable is v1beta1,
165+
// the contents would be converted to the v1 version before evaluating the CEL expression.
166+
//
167+
// Documentation on CEL: https://kubernetes.io/docs/reference/using-api/cel/
168+
Expression string `json:"expression"`
169+
}

0 commit comments

Comments
 (0)