mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
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:
commit
f26cf38a50
@ -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")
|
||||
}
|
||||
|
@ -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{
|
||||
|
Loading…
Reference in New Issue
Block a user