Issue: Missing sub Claim in User Interface
Summary
The User interface does not expose the sub (subject) claim, which is mandatory according to the OpenID Connect specification. This creates an OIDC compliance issue and limits interoperability with standard OIDC providers.
OIDC Specification Requirements
According to the OpenID Connect Core 1.0 specification:
- ID Token (Section 2):
sub is a REQUIRED claim
- UserInfo Response (Section 5.1):
sub is a REQUIRED claim
The sub claim is the unique identifier for the end-user at the issuer and serves as the primary key for user identity.
Current Implementation
File: packages/react-native-oidc-auth-core/src/oidc-auth/interface/user.ts
export interface User {
id?: string;
username?: string;
email?: string;
firstName?: string;
lastName?: string;
enabled?: boolean;
emailVerified?: boolean;
totp?: boolean;
createdTimestamp?: number;
}
Issues:
- ❌ No
sub field (OIDC required claim)
- ✅ Has
id field (appears to be Keycloak-specific)
- ✅ Has Keycloak-specific fields (
enabled, totp, createdTimestamp)
Root Cause Analysis
The library appears to have been originally designed for Keycloak, which:
- Provides a non-standard
/account endpoint (used in oidc-auth-bare.ts line 78)
- Uses
id as the user identifier in its admin/account APIs rather than the standard OIDC sub
- Includes additional user properties not in standard OIDC UserInfo
Evidence:
JwtToken interface does include sub (used for tokens) - see packages/react-native-oidc-auth-core/src/oidc-auth/interface/jwt-token.ts
- But
User interface doesn't expose it when calling /userinfo endpoint
- The
getUserInfo implementations don't map the sub claim from the response
Impact
Compatibility Issues:
- ❌ Not compliant with OIDC specification
- ❌ Cannot reliably identify users across OIDC providers (some use
id, some don't)
- ❌
sub is the only guaranteed unique identifier in OIDC
- ❌
email can change, username may not exist, but sub is immutable
Real-world scenarios where this matters:
- Multi-tenant applications
- User migration between identity providers
- Auditing and compliance (need stable user identifier)
- Integration with standard OIDC providers (Auth0, Okta, Azure AD, etc.)
Proposed Solution
Option 1: Add sub to User interface (Recommended)
export interface User {
sub: string; // ✅ OIDC required - unique subject identifier
id?: string; // Keep for Keycloak compatibility
username?: string;
email?: string;
firstName?: string;
lastName?: string;
enabled?: boolean;
emailVerified?: boolean;
totp?: boolean;
createdTimestamp?: number;
}
Update getUserInfo implementations to include sub:
In oidc-auth-expo.ts:
return {
sub: result.sub, // ✅ Add this
email: result.email,
// ... rest of fields
};
In oidc-auth-bare.ts:
return {
sub: result.sub, // ✅ Add this
email: result.email,
// ... rest of fields
};
Option 2: Use standard OIDC UserInfo claims
Alternatively, align the entire User interface with the standard OIDC UserInfo claims:
export interface User {
// Standard OIDC claims
sub: string; // Required
name?: string;
given_name?: string;
family_name?: string;
middle_name?: string;
nickname?: string;
preferred_username?: string;
profile?: string;
picture?: string;
website?: string;
email?: string;
email_verified?: boolean;
gender?: string;
birthdate?: string;
zoneinfo?: string;
locale?: string;
phone_number?: string;
phone_number_verified?: boolean;
address?: Address;
updated_at?: number;
// Keycloak-specific (keep as optional for backward compatibility)
id?: string;
enabled?: boolean;
totp?: boolean;
createdTimestamp?: number;
}
Affected Files
packages/react-native-oidc-auth-core/src/oidc-auth/interface/user.ts (interface definition)
packages/react-native-oidc-auth-expo/src/oidc-auth-expo.ts (getUserInfo implementation)
packages/react-native-oidc-auth/src/oidc-auth-bare.ts (getUserInfo implementation)
Testing Considerations
- Verify
sub is correctly mapped from UserInfo endpoint response
- Test with multiple OIDC providers (not just Keycloak)
- Ensure backward compatibility with existing Keycloak integrations
- Update TypeScript types and examples
References
Would you be open to a PR implementing Option 1? This would maintain backward compatibility while adding OIDC compliance.
Issue: Missing
subClaim in User InterfaceSummary
The
Userinterface does not expose thesub(subject) claim, which is mandatory according to the OpenID Connect specification. This creates an OIDC compliance issue and limits interoperability with standard OIDC providers.OIDC Specification Requirements
According to the OpenID Connect Core 1.0 specification:
subis a REQUIRED claimsubis a REQUIRED claimThe
subclaim is the unique identifier for the end-user at the issuer and serves as the primary key for user identity.Current Implementation
File:
packages/react-native-oidc-auth-core/src/oidc-auth/interface/user.tsIssues:
subfield (OIDC required claim)idfield (appears to be Keycloak-specific)enabled,totp,createdTimestamp)Root Cause Analysis
The library appears to have been originally designed for Keycloak, which:
/accountendpoint (used inoidc-auth-bare.tsline 78)idas the user identifier in its admin/account APIs rather than the standard OIDCsubEvidence:
JwtTokeninterface does includesub(used for tokens) - seepackages/react-native-oidc-auth-core/src/oidc-auth/interface/jwt-token.tsUserinterface doesn't expose it when calling/userinfoendpointgetUserInfoimplementations don't map thesubclaim from the responseImpact
Compatibility Issues:
id, some don't)subis the only guaranteed unique identifier in OIDCemailcan change,usernamemay not exist, butsubis immutableReal-world scenarios where this matters:
Proposed Solution
Option 1: Add
subto User interface (Recommended)Update
getUserInfoimplementations to includesub:In
oidc-auth-expo.ts:In
oidc-auth-bare.ts:Option 2: Use standard OIDC UserInfo claims
Alternatively, align the entire
Userinterface with the standard OIDC UserInfo claims:Affected Files
packages/react-native-oidc-auth-core/src/oidc-auth/interface/user.ts(interface definition)packages/react-native-oidc-auth-expo/src/oidc-auth-expo.ts(getUserInfo implementation)packages/react-native-oidc-auth/src/oidc-auth-bare.ts(getUserInfo implementation)Testing Considerations
subis correctly mapped from UserInfo endpoint responseReferences
Would you be open to a PR implementing Option 1? This would maintain backward compatibility while adding OIDC compliance.