Dex Federated OpenID Connect Provider
repository·master·Indexed 27 days ago
https://github.com/dexidp/dexDex is a federated OpenID Connect (OIDC) provider that allows applications to authenticate users against various upstream identity providers—such as LDAP, SAML, GitHub, Google, and Microsoft—using a single, unified OIDC interface. It issues signed JSON Web Tokens (JWTs) as ID Tokens and can be run natively on Kubernetes clusters using Custom Resource Definitions (CRDs). Dex includes a gRPC API for programmatically managing clients, passwords, connectors, authentication sessions, user identities, and multi-factor authentication (MFA).
What's inside Dex
- Dex is a federated OpenID Connect (OIDC) provider that acts as an identity service to drive authentication for applications. It serves as a portal to various upstream identity providers (LDAP, SAML, GitHub, Google, etc.) through a system of "connectors." This allows client applications to implement authentication logic once using the OIDC protocol, while Dex handles the specific protocols required by different backend identity providers.
Overview of CEL (Common Expression Language) Integration in Dex
masterDex is integrating [CEL (Common Expression Language)][cel-spec] as a first-class expression engine to handle policy evaluation, claim mapping, and token customization. This integration allows operators to define complex rules declaratively via expressions rather than requiring new Go code or configuration fields for every new requirement.
Key capabilities being introduced include:
- Authentication Policies: Control who can log in (e.g., restricting connectors to specific clients, enforcing group membership, or denying logins based on email domains).
- Token Policies: Customize issued tokens (e.g., adding extra claims to ID tokens, restricting scopes per client, or modifying
audclaims). - Advanced Claim Mapping: Replace ad-hoc OIDC connector configuration (like
ClaimMappingorFilterGroupClaims) with powerful, composable CEL expressions. - Global and Per-Client Rules: Apply policies at a global level or specifically to individual OAuth2 clients.
CEL Integration Constraints and Scope
masterWhen using CEL in Dex, be aware of the following design boundaries:
- Single-expression scope: CEL in Dex is limited to single-expression evaluation. Each expression is a standalone, stateless computation. It does not support intermediate variables, chaining, or multi-step transformations.
- Not a full policy engine: CEL is scoped specifically to identity and token operations. It is not intended to replace external engines like OPA or Kyverno for general authorization.
- Additive/Opt-in: The integration is designed to be additive. Existing configuration fields (such as
ClaimMappingandClaimMutations) will continue to function as they did before.
Propose a Dex Enhancement Proposal (DEP)
masterDex Enhancement Proposals (DEPs) are design documents used to propose major new features or significant changes to Dex. Use this process to describe, track, and document changes to the project.
Before starting
- Search GitHub for existing issues, discussions, and DEPs to avoid duplication.
- If no discussion exists, open a new discussion.
- Discuss your proposed change with the community to ensure a formal DEP is necessary.
Writing the proposal
- Fork the repository.
- Copy the template located at
docs/enhancements/_title-YYYY-MM-DD-#issue.mdand rename it appropriately. - Complete all sections in the template, providing as much detail as possible.
- Submit a Pull Request (PR) and engage in discussion with the Dex team.
Configure Token Policies (Claims and Filters) using CEL
masterDex allows operators to mutate ID tokens or restrict token issuance using CEL in the
tokenPolicyconfiguration. This can be applied globally or per-client.claims: Adds or overrides claims in the issued ID token. Each claim has akey(the claim name), avalue(the CEL expression for the value), and an optionalcondition(the claim is only included if this expression istrue).filter: Validates the token request. If the expression evaluates tofalse, the request is denied.
Note: Certain OIDC/OAuth2 claims (e.g.,
iss,sub,aud,exp,iat,nbf,jti,auth_time,nonce,at_hash,c_hash) are reserved and cannot be set or overridden via CEL.tokenPolicy: # Global mutations claims: - key: "'role'" value: "identity.groups.exists(g, g == 'admin') ? 'admin' : 'user'" - key: "'idp'" value: "request.connector_id" - key: "'department'" value: "identity.extra['department']" condition: "'department' in identity.extra" staticClients: - id: internal-api name: Internal API secret: ... redirectURIs: [...] tokenPolicy: claims: - key: "'custom-claim.company.com/team'" value: "identity.extra['team'].orValue('engineering')" - key: "'on_call'" value: "true" condition: "identity.groups.exists(g, g == 'ops')" # Restrict scopes filter: expression: "request.scopes.all(s, s in ['openid', 'email', 'profile'])" message: "'Unsupported scope requested'"Enable Auth Sessions via Feature Flag
masterTo enable the Auth Sessions feature in Dex, set the
DEX_SESSIONS_ENABLEDenvironment variable totrue. When disabled (default), Dex does not create, read, or validate sessions, and all authorization requests will require connector authentication on every request without SSO.DEX_SESSIONS_ENABLED=truePerform Token Exchange via RFC 8693
masterDex supports the OAuth2 Token Exchange grant type (
urn:ietf:params:oauth:grant-type:token-exchange). This allows programmatic clients (like CI/CD jobs or machine identities) to exchange a valid token obtained from an upstream Identity Provider (IDP) for a Dex access token, avoiding the need for browser-based login flows or long-lived static secrets.To perform an exchange, make a
POSTrequest to the Dex/tokenendpoint usingapplication/x-www-form-urlencodedparameters.Configure Authentication Policies using CEL
masterOperators can define global and per-client authentication policies in the Dex configuration using Common Expression Language (CEL). Each expression must evaluate to a
bool. If an expression evaluates totrue, the request is denied. Expressions are evaluated in order; the first match wins.Global Policy: Applies to all authentication requests. Per-client Policy: Defined within a
staticClientand applies only to that specific client.# Global authentication policy authPolicy: - expression: "!identity.email.endsWith('@example.com')" message: "'Login restricted to example.com domain'" - expression: "!identity.email_verified" message: "'Email must be verified'" staticClients: - id: admin-app name: Admin Application secret: ... redirectURIs: [...] # Per-client policy authPolicy: - expression: "!(request.connector_id in ['okta', 'ldap'])" message: "'This application requires Okta or LDAP login'" - expression: "!('admin' in identity.groups)" message: "'Admin group membership required'"Implement SSO session sharing via SSOSharedWith
masterSingle Sign-On (SSO) is achieved by allowing clients to share sessions. When a user accesses a client, Dex checks if an existing
AuthSessioncontains an active state for a client that is permitted to share with the target client.To allow a client to share its session with others, configure its
SSOSharedWithlist:- Use
"*"to allow the client to share its session with all other clients. - Use a specific
targetClientIDto allow sharing only with that specific client.
SSO Logic Flow:
- Dex retrieves the
AuthSessionvia the browser cookie. - It iterates through
ClientStatesin the session. - For each active/non-expired state, it checks if the
sourceClientconfiguration'sSSOSharedWithlist contains thetargetClientIDor"*". - If a match is found, the authentication state is copied to the target client's state in the session.
- Use
Map OIDC Connector Claims using CEL
masterIn OIDC connectors, you can replace legacy
claimMappingandclaimModificationswithclaimMappingExpressions. This allows for powerful, logic-based mapping of upstream IdP claims to Dex identity fields.Available variable:
claims(amap(string, dyn)containing raw upstream claims).connectors: - type: oidc id: corporate-idp name: Corporate IdP config: issuer: https://idp.example.com clientID: dex-client clientSecret: ... # CEL-based claim mapping claimMappingExpressions: username: "claims.preferred_username.orValue(claims.email)" email: "claims.email" groups: > claims.groups .filter(g, g.startsWith('dex:')) .map(g, g.trimPrefix('dex:')) emailVerified: "claims.email_verified.orValue(true)" extra: department: "claims.department.orValue('unknown')" cost_center: "claims.cost_center.orValue('')"Enable and Configure Auth Sessions in Dex
masterAuth Sessions (DEP 4560) allow for Single Sign-On (SSO) between clients by sharing authentication sessions. To use this feature, you must first enable it via an environment variable.
Enable the feature
Set the following environment variable:
DEX_SESSIONS_ENABLED=trueConfigure session settings
Use the
sessionsblock in yourconfig.yamlto manage cookie names and lifetimes. Note that security settings likeHttpOnly,Secure, andSameSiteare automatically set to secure defaults and are not configurable.Configuration Options
Key Type Default Description cookieNamestring "dex_session"The name of the session cookie. absoluteLifetimeduration "24h"Maximum session lifetime. validIfNotUsedForduration "1h"Session expires if not used within this duration. ssoSharedWithDefaultstring "none"Default SSO policy for clients without explicit ssoSharedWithconfig. Options:"all"(realm-wide SSO) or"none".rememberMeCheckedByDefaultboolean falseWhether the "Remember Me" checkbox is pre-checked in login/approval forms. # Enable via environment variable # DEX_SESSIONS_ENABLED=true # Configuration in config.yaml sessions: cookieName: "dex_session" absoluteLifetime: "24h" validIfNotUsedFor: "1h" ssoSharedWithDefault: "none" rememberMeCheckedByDefault: falseEnable Auth Sessions via environment variable
masterTo enable the new Auth Sessions feature (DEP 4560), which allows Dex to track logged-in users across browser sessions and enables OIDC features likeprompt=none,prompt=login, and SSO, set theDEX_SESSIONS_ENABLEDenvironment variable totrue.