Merge pull request #126553 from aramase/aramase/c/kep_3331_disallow_k8s_io_prefix

Disallow `k8s.io` and `kubernetes.io` namespaced extra key in structured authn config
This commit is contained in:
Kubernetes Prow Robot 2024-08-15 11:01:51 -07:00 committed by GitHub
commit f26cf38a50
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 86 additions and 0 deletions

View File

@ -355,6 +355,11 @@ func validateClaimMappings(compiler authenticationcel.Compiler, state *validatio
if mapping.Key != strings.ToLower(mapping.Key) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("key"), mapping.Key, "key must be lowercase"))
}
if isKubernetesDomainPrefix(mapping.Key) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("key"), mapping.Key, "k8s.io, kubernetes.io and their subdomains are reserved for Kubernetes use"))
}
if seenExtraKeys.Has(mapping.Key) {
allErrs = append(allErrs, field.Duplicate(fldPath.Child("key"), mapping.Key))
continue
@ -394,6 +399,24 @@ func validateClaimMappings(compiler authenticationcel.Compiler, state *validatio
return allErrs
}
func isKubernetesDomainPrefix(key string) bool {
domainPrefix := getDomainPrefix(key)
if domainPrefix == "kubernetes.io" || strings.HasSuffix(domainPrefix, ".kubernetes.io") {
return true
}
if domainPrefix == "k8s.io" || strings.HasSuffix(domainPrefix, ".k8s.io") {
return true
}
return false
}
func getDomainPrefix(key string) string {
if parts := strings.SplitN(key, "/", 2); len(parts) == 2 {
return parts[0]
}
return ""
}
func usesEmailClaim(ast *celgo.Ast) bool {
return hasSelectExp(ast.Expr(), "claims", "email")
}

View File

@ -1363,6 +1363,69 @@ func TestValidateClaimMappings(t *testing.T) {
structuredAuthnFeatureEnabled: true,
want: `issuer.claimMappings.extra[0].key: Invalid value: "example.org/Foo": key must be lowercase`,
},
{
name: "extra mapping key prefix is k8.io",
in: api.ClaimMappings{
Username: api.PrefixedClaimOrExpression{Expression: "claims.username"},
Groups: api.PrefixedClaimOrExpression{Expression: "claims.groups"},
Extra: []api.ExtraMapping{
{Key: "k8s.io/foo", ValueExpression: "claims.extra"},
},
},
structuredAuthnFeatureEnabled: true,
want: `issuer.claimMappings.extra[0].key: Invalid value: "k8s.io/foo": k8s.io, kubernetes.io and their subdomains are reserved for Kubernetes use`,
},
{
name: "extra mapping key prefix contains k8.io",
in: api.ClaimMappings{
Username: api.PrefixedClaimOrExpression{Expression: "claims.username"},
Groups: api.PrefixedClaimOrExpression{Expression: "claims.groups"},
Extra: []api.ExtraMapping{
{Key: "example.k8s.io/foo", ValueExpression: "claims.extra"},
},
},
structuredAuthnFeatureEnabled: true,
want: `issuer.claimMappings.extra[0].key: Invalid value: "example.k8s.io/foo": k8s.io, kubernetes.io and their subdomains are reserved for Kubernetes use`,
},
{
name: "extra mapping key prefix is kubernetes.io",
in: api.ClaimMappings{
Username: api.PrefixedClaimOrExpression{Expression: "claims.username"},
Groups: api.PrefixedClaimOrExpression{Expression: "claims.groups"},
Extra: []api.ExtraMapping{
{Key: "kubernetes.io/foo", ValueExpression: "claims.extra"},
},
},
structuredAuthnFeatureEnabled: true,
want: `issuer.claimMappings.extra[0].key: Invalid value: "kubernetes.io/foo": k8s.io, kubernetes.io and their subdomains are reserved for Kubernetes use`,
},
{
name: "extra mapping key prefix contains kubernetes.io",
in: api.ClaimMappings{
Username: api.PrefixedClaimOrExpression{Expression: "claims.username"},
Groups: api.PrefixedClaimOrExpression{Expression: "claims.groups"},
Extra: []api.ExtraMapping{
{Key: "example.kubernetes.io/foo", ValueExpression: "claims.extra"},
},
},
structuredAuthnFeatureEnabled: true,
want: `issuer.claimMappings.extra[0].key: Invalid value: "example.kubernetes.io/foo": k8s.io, kubernetes.io and their subdomains are reserved for Kubernetes use`,
},
{
name: "extra mapping key prefix with ak8s.io, *.ak8s.io, bkubernetes.io, *.bkubernetes.io are still valid",
in: api.ClaimMappings{
Username: api.PrefixedClaimOrExpression{Expression: "claims.username"},
Groups: api.PrefixedClaimOrExpression{Expression: "claims.groups"},
Extra: []api.ExtraMapping{
{Key: "ak8s.io/foo", ValueExpression: "claims.extra"},
{Key: "example.ak8s.io/foo", ValueExpression: "claims.extra"},
{Key: "bkubernetes.io/foo", ValueExpression: "claims.extra"},
{Key: "example.bkubernetes.io/foo", ValueExpression: "claims.extra"},
},
},
structuredAuthnFeatureEnabled: true,
want: "",
},
{
name: "valid claim mappings but uses email without verification",
in: api.ClaimMappings{