Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions api/v1alpha1/organization_types.go
100644 β†’ 100755
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,18 @@ type OIDCConfig struct {
// OAuth2ClientRedirectURIs are a registered set of redirect URIs. When redirecting from the idproxy to
// the client application, the URI requested to redirect to must be contained in this list.
OAuth2ClientRedirectURIs []string `json:"oauth2ClientRedirectURIs,omitempty"`
// ExtraClaims contains additional configuration for extra claims.
ExtraConfig *OIDCExtraConfig `json:"extraConfig,omitempty"`
}

type OIDCExtraConfig struct {
// InsecureSkipEmailVerified allows to skip the verification of the "email_verified" claim in ID tokens.
// +kubebuilder:default:=false
// +kubebuilder:validation:Enum:=true;false
InsecureSkipEmailVerified bool `json:"insecureSkipEmailVerified,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this option.

since dex in greenhouse is used for k8s auth… in structured authentication when using expression claims.email it implicitly needs claims.email_verified to be true

https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-authentication-configuration

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes you are right, but when an OIDC provider returns email claim without "email_verified" field, this is assumed to be false by Dex, and newly generated claim is with email_verified=false.

Some enterprise providers return claims without email_verified, when they had no usage of emails verification in enrollement process. Like Okta, CloudFoundry, EntraID.

Kubernetes changed it's original behavior in this PR: kubernetes/kubernetes#61508 to set email_verified=true if the claim is not present, but on Dex side the PR is still open, and original behavior remained: dexidp/dex#3811

Copy link
Contributor

@abhijith-darshan abhijith-darshan Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the PR you referenced for k8s is for the legacy OIDC config and not for the structured auth anymore.

In structured auth when using claims.expression (and not claimMappings) email_verified is required.
https://github.com/kubernetes/kubernetes/blob/3daf280c464c712f38fe2a24d9434fcf2670c251/staging/src/k8s.io/apiserver/pkg/apis/apiserver/validation/validation.go#L417-L420

But Okta and EntraID (https://learn.microsoft.com/en-us/entra/external-id/customers/reference-oidc-claims-mapping-customers#claim-and-attribute-mappings) have the email_verfied claim and in Okta there should be a toggle to turn it on for each user.

The verification is anyway part of the enrollment process during sign-up. If users are added programmatically then the email_verified can also be set during that process.

Also when dex config changes with new properties being introduced, the sig alg may change and there will be auth issues.

Here is what I would propose -

move InsecureSkipEmailVerified and UserIDClaim to either map[string]string or a *struct (for easy nil checks)

That way no config changes are introduced on the existing connectors and only during enabling a new config these properties if available are considered.

sounds good?

// UserIDClaim is the claim to be used as user ID.
// +kubebuilder:default:="login_name"
UserIDClaim string `json:"userIDClaim,omitempty"`
}

type SCIMConfig struct {
Expand Down
20 changes: 20 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions charts/manager/crds/greenhouse.sap_organizations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@ spec:
- key
- name
type: object
extraConfig:
description: ExtraClaims contains additional configuration
for extra claims.
properties:
insecureSkipEmailVerified:
default: false
description: InsecureSkipEmailVerified allows to skip
the verification of the "email_verified" claim in ID
tokens.
enum:
- true
- false
type: boolean
userIDClaim:
default: login_name
description: UserIDClaim is the claim to be used as user
ID.
type: string
type: object
issuer:
description: Issuer is the URL of the identity service.
type: string
Expand Down
2 changes: 2 additions & 0 deletions config/samples/organization/demo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,5 @@ spec:
name: demo-oidc
issuer: https://global.accounts.dev
redirectURI: https://bogus.accounts.foo
insecureSkipEmailVerified: true
userIDClaim: email
55 changes: 55 additions & 0 deletions docs/reference/api/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1807,6 +1807,61 @@ <h3 id="greenhouse.sap/v1alpha1.OIDCConfig">OIDCConfig
the client application, the URI requested to redirect to must be contained in this list.</p>
</td>
</tr>
<tr>
<td>
<code>extraConfig</code><br>
<em>
<a href="#greenhouse.sap/v1alpha1.OIDCExtraConfig">
OIDCExtraConfig
</a>
</em>
</td>
<td>
<p>ExtraClaims contains additional configuration for extra claims.</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<h3 id="greenhouse.sap/v1alpha1.OIDCExtraConfig">OIDCExtraConfig
</h3>
<p>
(<em>Appears on:</em>
<a href="#greenhouse.sap/v1alpha1.OIDCConfig">OIDCConfig</a>)
</p>
<div class="md-typeset__scrollwrap">
<div class="md-typeset__table">
<table>
<thead>
<tr>
<th>Field</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<code>insecureSkipEmailVerified</code><br>
<em>
bool
</em>
</td>
<td>
<p>InsecureSkipEmailVerified allows to skip the verification of the &ldquo;email_verified&rdquo; claim in ID tokens.</p>
</td>
</tr>
<tr>
<td>
<code>userIDClaim</code><br>
<em>
string
</em>
</td>
<td>
<p>UserIDClaim is the claim to be used as user ID.</p>
</td>
</tr>
</tbody>
</table>
</div>
Expand Down
15 changes: 15 additions & 0 deletions docs/reference/api/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,21 @@ components:
- key
- name
type: object
extraConfig:
description: ExtraClaims contains additional configuration for extra claims.
properties:
insecureSkipEmailVerified:
default: false
description: InsecureSkipEmailVerified allows to skip the verification of the "email_verified" claim in ID tokens.
enum:
- true
- false
type: boolean
userIDClaim:
default: login_name
description: UserIDClaim is the claim to be used as user ID.
type: string
type: object
issuer:
description: Issuer is the URL of the identity service.
type: string
Expand Down
27 changes: 19 additions & 8 deletions internal/controller/organization/dex.go
100644 β†’ 100755
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,26 @@ func (r *OrganizationReconciler) reconcileDexConnector(ctx context.Context, org
if err != nil {
return err
}
var userNameKey = "login_name"
var skipEmailVerified = false
if org.Spec.Authentication.OIDCConfig.ExtraConfig != nil {
if org.Spec.Authentication.OIDCConfig.ExtraConfig.UserIDClaim == "" {
userNameKey = org.Spec.Authentication.OIDCConfig.ExtraConfig.UserIDClaim
}
if org.Spec.Authentication.OIDCConfig.ExtraConfig != nil {
skipEmailVerified = org.Spec.Authentication.OIDCConfig.ExtraConfig.InsecureSkipEmailVerified
}
}
oidcConfig := &oidc.Config{
Issuer: org.Spec.Authentication.OIDCConfig.Issuer,
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURI: redirectURL,
UserNameKey: "login_name",
UserIDKey: "login_name",
InsecureSkipVerify: true,
InsecureEnableGroups: true,
Issuer: org.Spec.Authentication.OIDCConfig.Issuer,
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURI: redirectURL,
UserNameKey: userNameKey,
UserIDKey: userNameKey,
InsecureSkipEmailVerified: skipEmailVerified,
InsecureSkipVerify: true,
InsecureEnableGroups: true,
}
configByte, err := json.Marshal(oidcConfig)
if err != nil {
Expand Down
11 changes: 11 additions & 0 deletions types/typescript/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,12 @@ export interface components {
/** @description Name of the secret in the same namespace. */
name: string;
};
/**
* @description InsecureSkipEmailVerified allows to skip the verification of the "email_verified" claim in ID tokens.
* @default false
* @enum {boolean}
*/
insecureSkipEmailVerified: true | false;
/** @description Issuer is the URL of the identity service. */
issuer: string;
/**
Expand All @@ -545,6 +551,11 @@ export interface components {
* If none is specified, the Greenhouse ID proxy will be used.
*/
redirectURI?: string;
/**
* @description UserIDClaim is the claim to be used as user ID.
* @default login_name
*/
userIDClaim: string;
};
/** @description SCIMConfig configures the SCIM client. */
scim?: {
Expand Down
Loading