Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ebb0962
Fix Issue and Add Tests
mohityadav766 Jan 26, 2026
011c9b1
Merge branch 'main' into stats-correction
mohityadav766 Jan 26, 2026
22fe6b6
Update generated TypeScript types
github-actions[bot] Jan 26, 2026
5a9fa17
Merge branch 'main' into stats-correction
mohityadav766 Jan 26, 2026
beea25b
Fix CI jest failure
mohityadav766 Jan 26, 2026
0966e5e
Merge branch 'main' into stats-correction
mohityadav766 Jan 26, 2026
2afce70
Add design doc for user identity management simplification
mohityadav766 Jan 26, 2026
f4ed16b
Add implementation plan for user identity simplification
mohityadav766 Jan 26, 2026
472a633
feat(auth): add emailClaim and displayNameClaim config options
mohityadav766 Jan 26, 2026
e806756
feat(auth): add adminEmails, allowedEmailDomains, botDomain config
mohityadav766 Jan 26, 2026
a01bac9
feat(auth): add extractEmailFromClaim utility method
mohityadav766 Jan 26, 2026
fb4894f
feat(auth): add extractDisplayNameFromClaim utility method
mohityadav766 Jan 26, 2026
092fb8f
feat(auth): add generateUsernameFromEmail utility
mohityadav766 Jan 26, 2026
0cd661f
feat(auth): add validateEmailDomain utility
mohityadav766 Jan 26, 2026
291cb32
feat(auth): add isAdminEmail utility
mohityadav766 Jan 26, 2026
589c092
feat(auth): add deprecation warnings for old config options
mohityadav766 Jan 26, 2026
dfc7370
feat(auth): update JwtFilter for email-first resolution
mohityadav766 Jan 26, 2026
4658f4f
feat(auth): update OIDC handler for email-first flow
mohityadav766 Jan 26, 2026
ad9a6c0
feat(auth): update SAML handler for email-first flow
mohityadav766 Jan 26, 2026
962339a
feat(auth): update LDAP authenticator for email-first flow
mohityadav766 Jan 26, 2026
7f96af2
feat(auth): add createBotEmail utility using botDomain config
mohityadav766 Jan 26, 2026
c10f886
feat(auth): update admin user creation to use adminEmails
mohityadav766 Jan 26, 2026
6d49e8b
docs: update example config with new email-first options
mohityadav766 Jan 26, 2026
0eb02a6
Merge branch 'main' into user-auth-improvements
mohityadav766 Jan 26, 2026
8cccdcc
Update generated TypeScript types
github-actions[bot] Jan 26, 2026
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
19 changes: 18 additions & 1 deletion conf/openmetadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,18 @@ migrationConfiguration:
authorizerConfiguration:
className: ${AUTHORIZER_CLASS_NAME:-org.openmetadata.service.security.DefaultAuthorizer}
containerRequestFilter: ${AUTHORIZER_REQUEST_FILTER:-org.openmetadata.service.security.JwtFilter}

# Email-first admin configuration (recommended)
adminEmails: ${AUTHORIZER_ADMIN_EMAILS:-[]}
allowedEmailDomains: ${AUTHORIZER_ALLOWED_EMAIL_DOMAINS:-[]}
botDomain: ${AUTHORIZER_BOT_DOMAIN:-openmetadata.org}

# Deprecated - use adminEmails instead
adminPrincipals: ${AUTHORIZER_ADMIN_PRINCIPALS:-[admin]}
allowedEmailRegistrationDomains: ${AUTHORIZER_ALLOWED_REGISTRATION_DOMAIN:-["all"]}
# Deprecated - use botDomain for bots, allowedEmailDomains for user restrictions
principalDomain: ${AUTHORIZER_PRINCIPAL_DOMAIN:-"open-metadata.org"}

allowedEmailRegistrationDomains: ${AUTHORIZER_ALLOWED_REGISTRATION_DOMAIN:-["all"]}
allowedDomains: ${AUTHORIZER_ALLOWED_DOMAINS:-[]}
enforcePrincipalDomain: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false}
enableSecureSocketConnection : ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false}
Expand All @@ -299,7 +308,15 @@ authenticationConfiguration:
authority: ${AUTHENTICATION_AUTHORITY:-https://accounts.google.com}
clientId: ${AUTHENTICATION_CLIENT_ID:-""}
callbackUrl: ${AUTHENTICATION_CALLBACK_URL:-""}

# Email-first claim configuration (recommended)
# Uses email as primary identifier, defaults vary by provider (OIDC: email, LDAP: mail)
emailClaim: ${AUTHENTICATION_EMAIL_CLAIM:-email}
displayNameClaim: ${AUTHENTICATION_DISPLAY_NAME_CLAIM:-name}

# Deprecated - use emailClaim instead
jwtPrincipalClaims: ${AUTHENTICATION_JWT_PRINCIPAL_CLAIMS:-[email,preferred_username,sub]}
# Deprecated - use emailClaim and displayNameClaim instead
jwtPrincipalClaimsMapping: ${AUTHENTICATION_JWT_PRINCIPAL_CLAIMS_MAPPING:-[]}
enableSelfSignup : ${AUTHENTICATION_ENABLE_SELF_SIGNUP:-true}
enableAutoRedirect: ${AUTHENTICATION_ENABLE_AUTO_REDIRECT:-false}
Expand Down
184 changes: 184 additions & 0 deletions docs/plans/2026-01-26-user-identity-simplification-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# User Identity Management Simplification Design

## Summary

Simplify OpenMetadata's authentication system to use email as the primary user identifier, replacing the complex claim resolution logic with a straightforward email-first approach.

## Goals

- Email as the single source of truth for user identity
- Simplified configuration with sensible defaults
- Backward compatibility with deprecation warnings for old configs
- Support for all authentication providers (OIDC, SAML, LDAP, Basic)

## Configuration Schema

### New Configuration Model

```yaml
authenticationConfiguration:
provider: "oidc" # Required: oidc, saml, ldap, basic
publicKeyUrls: ["https://..."] # Required for SSO providers

# New simplified fields
emailClaim: "email" # Optional, defaults per provider
displayNameClaim: "name" # Optional, defaults per provider

# Deprecated (warn if present, still functional)
jwtPrincipalClaims: [...] # Deprecated
jwtPrincipalClaimsMapping: [...] # Deprecated

authorizerConfiguration:
# New fields
adminEmails: ["admin@company.com", "user1@company.com"]
allowedEmailDomains: ["company.com", "subsidiary.com"] # Optional, if set only these domains can authenticate
botDomain: "bot.company.com" # Domain used for system-created bots

# Deprecated (warn if present, still functional)
adminPrincipals: [...] # Deprecated
principalDomain: "..." # Deprecated
```

### Provider Defaults

| Provider | `emailClaim` | `displayNameClaim` |
|----------|-------------|-------------------|
| OIDC | `"email"` | `"name"` |
| SAML | `"email"` | `"name"` |
| LDAP | `"mail"` | `"displayName"` |
| Basic | N/A | N/A |

## User Identity Model

| Field | Source | Uniqueness |
|-------|--------|------------|
| `email` | From claim (required) | Unique, primary lookup key |
| `name` | Auto-generated (email prefix, collision suffix if needed) | Unique, internal identifier |
| `displayName` | From `displayNameClaim` or email prefix | Not unique, user-friendly |

### Name Generation

1. Extract prefix from email (`john.doe@company.com` → `john.doe`)
2. Check if `john.doe` exists
3. If collision, append random suffix → `john.doe_x7k2`

## Authentication Flow

```
┌─────────────────────────────────────────────────────────┐
│ User Authenticates │
└─────────────────────┬───────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ Extract email from claim/attribute using emailClaim │
│ (OIDC: JWT claim, SAML: assertion, LDAP: attribute) │
└─────────────────────┬───────────────────────────────────┘
┌───────────────┐
│ Email found? │
└───────┬───────┘
┌──────────┴──────────┐
│ No │ Yes
▼ ▼
┌─────────────────────┐ ┌─────────────────────────────────┐
│ Fail authentication │ │ Validate email format │
│ "email claim not │ └─────────────────┬───────────────┘
│ found in token" │ │
└─────────────────────┘ ▼
┌───────────────────────┐
│ allowedEmailDomains │
│ configured? │
└───────────┬───────────┘
┌──────────┴──────────┐
│ Yes │ No
▼ │
┌─────────────────────┐ │
│ Domain in allowed │ │
│ list? │ │
└─────────┬───────────┘ │
│ │
┌──────────┴──────────┐ │
│ No │ Yes │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────────────┐
│ Fail: "domain │ │ Lookup user by email │
│ not allowed" │ └─────────────┬───────────┘
└─────────────────┘ │
┌─────────────────────┐
│ User exists? │
└─────────┬───────────┘
┌──────────┴──────────┐
│ No │ Yes
▼ ▼
┌─────────────────────┐ ┌─────────────────┐
│ enableSelfSignup? │ │ Return existing │
└─────────┬───────────┘ │ user │
│ └─────────────────┘
┌──────────┴──────────┐
│ No │ Yes
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ Fail: "User not │ │ Create new user: │
│ registered. Contact │ │ - Generate name │
│ administrator." │ │ - Set displayName │
└─────────────────────┘ │ - Set email │
└─────────────────────┘
```

## Error Messages

| Scenario | Error Message |
|----------|---------------|
| Missing email claim | `"Authentication failed: email claim '{claimName}' not found in token"` |
| Invalid email format | `"Authentication failed: invalid email format"` |
| Domain not allowed | `"Authentication failed: domain '{domain}' not in allowed list"` |
| User not registered | `"User not registered. Contact administrator."` |

## Deprecation Warnings

Logged at startup if deprecated configs are present:

| Deprecated Config | Warning Message |
|-------------------|-----------------|
| `jwtPrincipalClaims` | "Deprecated: Use 'emailClaim' instead" |
| `jwtPrincipalClaimsMapping` | "Deprecated: Use 'emailClaim' and 'displayNameClaim' instead" |
| `adminPrincipals` | "Deprecated: Use 'adminEmails' instead" |
| `principalDomain` | "Deprecated: Use 'botDomain' for bots, 'allowedEmailDomains' for domain restrictions" |

## Files to Modify

### Configuration Schema
- `openmetadata-spec/src/main/resources/json/schema/configuration/authenticationConfiguration.json` - Add `emailClaim`, `displayNameClaim`
- `openmetadata-spec/src/main/resources/json/schema/configuration/authorizerConfiguration.json` - Add `adminEmails`, `allowedEmailDomains`, `botDomain`

### Core Authentication Logic
- `SecurityUtil.java` - New simplified `findEmailFromClaim()` method, deprecation warnings
- `JwtFilter.java` - Update to use email-first resolution, lookup by email
- `UserRepository.java` - Add/verify email-based lookup method

### Authenticators
- `BasicAuthenticator.java` - Align with email-first approach
- `LdapAuthenticator.java` - Use `emailClaim` for LDAP attribute
- `SamlAuthenticationHandler.java` - Use `emailClaim` for SAML assertion
- `AuthenticationCodeFlowHandler.java` - Update OIDC flow

### User Management
- `UserUtil.java` - Update admin user creation to use `adminEmails`, bot creation to use `botDomain`, name generation with collision handling
- `UserResource.java` - API for username selection (Basic Auth flow)

### Startup/Bootstrap
- Deprecation warning logging when old configs detected

## Migration Strategy

Phase 1 (this implementation): Backward-compatible changes with deprecation warnings. Old configs continue to work.

Phase 2 (future): Migration tooling via OpenMetadataOps to help users transition existing users with artificial emails to real emails.

Phase 3 (future): Remove deprecated configuration options.
Loading