Skip to content

Commit ec551eb

Browse files
committed
Fixes according to codereview comments
Signed-off-by: m.nabokikh <[email protected]>
1 parent e9b3ee0 commit ec551eb

File tree

1 file changed

+68
-41
lines changed
  • keps/sig-auth/3331-structured-config-for-oidc-authentication

1 file changed

+68
-41
lines changed

keps/sig-auth/3331-structured-config-for-oidc-authentication/README.md

Lines changed: 68 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ Items marked with (R) are required *prior to targeting to a milestone / release*
126126
## Summary
127127

128128
This enhancement proposal covers implementing the structured configuration for the OIDC authenticator.
129-
OIDC authentication is essential part of Kubernetes, yet it has limitations in its current state.
129+
OIDC authentication is important part of Kubernetes, yet it has limitations in its current state.
130130
Bellow we will discuss that limitation and propose solutions.
131131

132132
# Motivation
@@ -139,11 +139,10 @@ better support various features that have been requested.
139139

140140
There are features users want to tune. We need to provide customization of the following:
141141

142-
- Claims validation rules: current OIDC provider supports only audience claim validation and only by exact values
143-
- Claim mappings: it is only possible to pick a single value from a single claim and prefix groups
144-
- Use more than one OIDC provider: the only option, for now, is to use [Dex](https://dexidp.io/) (or similar software)
145-
as a lightweight OIDC proxy to connect many providers to Kubernetes
146-
- Change authenticator settings without restarting kube-apiserver
142+
- *Claims validation rules*: current OIDC provider supports only audience claim validation and only by exact values.
143+
- *Claim mappings*: it is only possible to pick a single value from a single claim and prefix groups.
144+
- *Use more than one OIDC provider*: the only option, for now, is to use an external OIDC provider that handles multiplexing support for multiple providers.
145+
- Change authenticator settings without restarting kube-apiserver.
147146

148147
### Non-Goals
149148

@@ -171,7 +170,7 @@ The main part of this proposal is a configuration file. It contains an array of
171170
type OIDCConfiguration struct {
172171
metav1.TypeMeta
173172
// Providers is a list of OIDC providers to authenticate Kubernetes users.
174-
Providers []Provider
173+
Providers []Provider `json:"providers"`
175174
}
176175
```
177176

@@ -180,16 +179,16 @@ Each provider has several properties that will be described in detail below.
180179
```go
181180
type Provider struct {
182181
// Issuer is a basic OIDC provider connection options.
183-
Issuer Issuer
182+
Issuer Issuer `json:"issuer"`
184183
// ClaimValidationRules are rules that are applied to validate ID token claims to authorize users.
185184
// +optional
186-
ClaimValidationRules []ClaimValidationRule
185+
ClaimValidationRules []ClaimValidationRule `json:"claimValidationRules,omitempty"`
187186
// ClaimMappings points claims of an ID token to be treated as user attributes.
188187
// All mappings are logical expressions that is written in CEL https://github.com/google/cel-go.
189-
ClaimMappings UserAttributes
188+
ClaimMappings UserAttributes `json:"claimMappings"`
190189
// ClaimsFilter allows unmarshalling only required claims which positively affects performance.
191190
// +optional
192-
ClaimsFilter []string
191+
ClaimsFilter []string `json:"claimFilters,omitempty"`
193192
}
194193
```
195194

@@ -200,34 +199,46 @@ type Provider struct {
200199
```go
201200
type Issuer struct {
202201
// URL points to the issuer URL in a format schema://url/path.
203-
URL string
204-
// CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority
205-
CertificateAuthorityData []byte
202+
// Not required to be unique because users may want to have the API server trust multiple
203+
// client IDs (kubernetes dashboard, kubectl, etc.) from the same provider.
204+
URL string `json:"url,omitempty"`
205+
// CertificateAuthorityData contains PEM-encoded certificate authority certificates. Overrides CertificateAuthority.
206+
// +optional
207+
CertificateAuthorityData []byte `json:"certificateAuthorityData,omitempty"`
206208
// ClientID the JWT must be issued for, the "sub" field. This plugin only trusts a single
207209
// client to ensure the plugin can be used with public providers.
208210
// Do not affect anything with the SkipOIDCValidations option enabled.
209211
// +optional
210-
ClientID string
212+
ClientID string `json:"clientID,omitempty"`
211213
// SkipOIDCValidations is a flag to turn off issuer validation, client id validation.
212214
// OIDC related checks.
215+
//
216+
// Validations that will be skipped:
217+
// - ClientID validation
218+
// - URL schema equals to HTTPS
219+
// - Issuer URL check
220+
// - Expiry validation
221+
//
213222
// +optional
214-
SkipOIDCValidations bool
223+
SkipOIDCValidations bool `json:"skipOIDCValidations,omitempty"`
215224
}
216225
```
217226
218-
2. `ClaimValidationRules` - additional rules for authorization.
227+
2. `ClaimValidationRules` - additional authentication policies. These policies are applied after generic OIDC validations, e.g., checking the token signature, issuer URL, etc. Rules are applicable to distributed claims.
219228
```go
220229
type ClaimValidationRule struct {
221230
// Rule is a logical expression that is written in CEL https://github.com/google/cel-go.
222-
Rule string
231+
Rule string `json:"rule"`
223232
// Message customize returning message for validation error of the particular rule.
224233
// +optional
225-
Message string
234+
Message string `json:"message,omitempty"`
226235
}
227236
```
228237
229238
For validation expressions, the CEL is used. They are similar to validations functions for [Custom Resources](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#resource-use-by-validation-functions).
230239
`Rule` expression should always evaluate a boolean. Token `claims` are passed to CEL expressions as a dynamic map `decls.NewMapType(decls.String, decls.Dyn)`.
240+
241+
> NOTE: If a rule returns `false` after evaluation, the `401 Unauthorized` error will be returned. If the evaluation is failed in runtime, the `500 Internal Sever Error` error will be returned with a message to kube-apiserver logs.
231242
232243
You can find a snippet of validation rules below:
233244
@@ -237,31 +248,31 @@ type Provider struct {
237248
- rule: 'claims.aud == "charmander" || claims.aud == "bulbasaur"'
238249
message: clients other than charmander or bulbasaur are not allowed
239250
240-
- rule: 'claims.roles.exists(r, r == "kubernetes-user")'
241-
message: only kubernetes-user group members can access the cluster
251+
- rule: 'claims.exp - claims.nbf > 86400'
252+
message: total token lifetime must not exceed 24 hours
242253
```
243254
244255
3. `ClaimMappings` - rules to map claims from a token to Kubernetes user attributes.
245256
```go
246257
type UserAttributes struct {
247258
// Username represents an option for the username attribute.
248-
Username string
259+
Username string `json:"username"`
249260
// Groups represents an option for the groups attribute.
250261
// +optional
251-
Groups string
262+
Groups string `json:"groups,omitempty"`
252263
// UID represents an option for the uid attribute.
253264
// +optional
254-
UID string
265+
UID string `json:"uid,omitempty"`
255266
// Extra represents an option for the extra attribute.
256267
// +optional
257-
Extra []ExtraMapping
268+
Extra []ExtraMapping `json:"extra,omitempty"`
258269
}
259270
260271
type ExtraMapping struct {
261272
// Key is a CEL expression to extract extra attribute key.
262-
Key string
263-
// Expression is a CEL expression to extract extra attribute value.
264-
Expression string
273+
Key string `json:"key"`
274+
// Value is a CEL expression to extract extra attribute value.
275+
Value string `json:"value"`
265276
}
266277
```
267278
@@ -303,20 +314,30 @@ type Provider struct {
303314
know the structure of the token and the exact claims they will use in CEL expressions.
304315
This option helps to reduce system load and operate only with required claims.
305316
317+
> TODO: Think about prefixes. The flag-based OIDC authenticator implementation allows to prefix usernames and groups to avoid collisions with system groups or names.
318+
> 1. This is a common use case. Users can benefit from not using CEL for it.
319+
> 2. Not only enforcing prefixes is useful. It is also possible to reject tokens if there are groups with the `system:` prefix.
320+
306321
### More about CEL
307322
308-
* CEL runtime should be compiled only once if structured OIDC config option is enabled
309-
* To make working with strings more convinient, `strings` and `encoding` [CEL extensions](https://github.com/google/cel-go/tree/v0.9.0/ext) should be enabled,
310-
e.g, to be able to split a string with comma separated fields and use them as a single array
311-
* Benchmarks are required to see how different CEL expressions affects authentication time
312-
* CEL expressions are called on each request. We should properly investigate the influence of these calls on the system
313-
latency and, if necessary, prove caching or other mechanisms to improve performance.
323+
* CEL runtime should be compiled only once if structured OIDC config option is enabled.
324+
* Two variables will be available in to use in rules:
325+
* `claim` for token claims
326+
* `now` for the current time in UNIX format to be able to customize the expiration validation (e.g., `Rule: "claims.exp < now", Message: "Token is expired"`)
327+
* To make working with strings more convenient, `strings` and `encoding` [CEL extensions](https://github.com/google/cel-go/tree/v0.9.0/ext) should be enabled,
328+
e.g, to be able to split a string with comma separated fields and use them as a single array.
329+
* Benchmarks are required to see how different CEL expressions affects authentication time.
330+
* CEL expressions are called on each request. We should properly investigate the influence of these calls on the system.
331+
latency and, if necessary, prove caching or other mechanisms to improve performance. The possibility of applying caching mechanisms should be considered.
314332
315333
### Flags
316334
317335
The only flag requires to enable the feature is the `--oidc-configuration-path` flag. It points to the configuration file.
318336
On startup, kube-apiserver enables the file watcher for the configuration file and reacts to any file change.
319337
338+
> NOTE: This KEP is aimed at implementing a new Kubernetes authenticator.
339+
> It will be possible to simultaneously enable a flag-based OIDC provider authenticator and a structured-config OIDC authenticator.
340+
320341
### Test Plan
321342
322343
<!--
@@ -334,7 +355,7 @@ when drafting this test plan.
334355
existing tests to make this code solid enough prior to committing the changes necessary
335356
to implement this enhancement.
336357
337-
TBA
358+
https://github.com/kubernetes/kubernetes/issues/110782
338359
339360
##### Prerequisite testing updates
340361
@@ -403,10 +424,10 @@ We expect no non-infra related flakes in the last month as a GA graduation crite
403424
404425
- Gather feedback from developers and surveys
405426
- Complete benchmarks
427+
- Add metrics
406428
407429
#### GA
408430
409-
- Add metrics
410431
- Add a full documentation with examples for the most popular providers, e.g., Okta, Dex, Auth0
411432
- Migration guide
412433
- Deprecation warnings for non-structured OIDC provider configuration
@@ -450,21 +471,27 @@ No.
450471

451472
###### Can the feature be disabled once it has been enabled (i.e. can we roll back the enablement)?
452473

453-
Yes, but disable means also deleting the flag from the kube-apiserver manifest.
474+
Yes.
454475

455476
###### What happens if we reenable the feature if it was previously rolled back?
456477

457478
No impact.
458479

459480
###### Are there any tests for feature enablement/disablement?
460481

461-
Not required.
482+
Feature enablement/disablement tests will be added as part of https://github.com/kubernetes/kubernetes/issues/110782
483+
484+
> An example test could be: unit test that demonstrates that when the featuregate is false, the validation function on the Options type reports a failure when the flag is set.
462485
463486
### Rollout, Upgrade and Rollback Planning
464487

465488
###### How can a rollout or rollback fail? Can it impact already running workloads?
466489

467-
It cannot fail.
490+
It cannot fail until a bug in kube-apiserver connected to parsing structured config file occurs.
491+
492+
Possible consequences are:
493+
* A cluster administrator rolls out the feature with the addition of some validation rules that may allow access to previously restricted users.
494+
* Other cluster components can depend on claim validations. Rolling back would mean losing validation functionality.
468495

469496
###### What specific metrics should inform a rollback?
470497

@@ -530,7 +557,7 @@ These goals will help you determine what you need to measure (SLIs) in the next
530557
question.
531558
-->
532559

533-
The feature should work 99.9% of the time.
560+
The feature should work 99.9% of the time (SLOs for actual requests should not change in any way compared to the flag-based OIDC configuration).
534561

535562
###### What are the SLIs (Service Level Indicators) an operator can use to determine the health of the service?
536563

@@ -629,7 +656,7 @@ TBA.
629656

630657
## Drawbacks
631658

632-
Nothing can hold us. Everyone agrees that we have to implement this feature to fulfill user expectations.
659+
- This feature will be the first adoption of using CEL for a config file.
633660

634661
## Alternatives
635662

0 commit comments

Comments
 (0)