Change:
Disallow setting all and namespaced extra info in custom ways for now. /assign aramase enj /sig auth
/triage accepted

Discussion:
if mapping.Key != strings.ToLower(mapping.Key) { allErrs = append(allErrs, field.Invalid(fldPath.Child("key"), mapping.Key, "key must be lowercase")) } <ins> 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")) } </ins> if seenExtraKeys.Has(mapping.Key) { allErrs = append(allErrs, field.Duplicate(fldPath.Child("key"), mapping.Key)) continue

return allErrs } <ins> 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 "" } </ins> func usesEmailClaim(ast *celgo.Ast) bool { return hasSelectExp(ast.Expr(), "claims", "email") }

want:                          `issuer.claimMappings.extra[0].key: Invalid value: "example.org/Foo": key must be lowercase`, }, { <ins> 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:                          "", }, { </ins> name: "valid claim mappings but uses email without verification", in: api.ClaimMappings{ Username: api.PrefixedClaimOrExpression{Expression: "claims.email"},