Skip to content

feat: expose OpenID id_token to account mapper #17

@linux4life798

Description

@linux4life798

Prerequisites

  • I have searched existing issues and discussions for duplicates
  • I reviewed the README and docs to ensure this isn't already supported
  • I considered alternatives or workarounds and describe them below
  • The scope is minimal and focused on a single feature

Impacted areas (select all that apply)

  • Public API (traits, structs, functions, modules)
  • Authorization model (roles, groups, permissions)
  • Authentication flows (credentials, JWT, cookies, bearer)
  • Storage backends (memory/sea-orm/surrealdb)
  • Configuration/feature flags
  • Error types and error mapping
  • Performance/throughput/latency
  • Documentation/examples

Problem statement

Today the OAuth2 flow erases OpenID Connect extras by constraining to StandardTokenResponse<EmptyExtraTokenFields, BasicTokenType>. The mapper only sees access/refresh tokens, so consumers must issue an extra UserInfo HTTP call to get claims that are already present in the id_token (e.g., sub, email, email_verified, hd, nonce, iss, aud). This adds latency, another failure mode, and blocks the usage of providers that don't provide a userinfo endpoint.

Proposed solution (high-level)

Allow OIDC token responses (with id_token) to reach with_account_mapper, enabling consumers to validate and extract claims without an extra UserInfo request, before minting the first-party JWT.

API design details

* Widen the mapper input to a token response that retains `id_token` or allows generalization to change the expected response type.
* Surface the raw `id_token` and possibly decoded claims to the mapper; handle JWT verification in the library.
* Consider an additive API (`with_oidc_account_mapper`) or a type alias to keep compatibility; avoid breaking existing mappers.

Primary use-cases and examples

As a consumer of Google/Microsoft OIDC, I want to validate id_token nonce/iss/aud and use sub/email_verified/hd to build my Account without calling the UserInfo endpoint.


// Pseudo code
Gate::oauth2::<Role, Group>()
    .add_scope("openid")
    .with_account_mapper(|token| {
        let id_token = token.id_token().ok_or(...)?
        // validate nonce/aud/iss, decode claims, map to Account
        let claims = id_token
                .claims(&id_token_verifier, &nonce)
                .context("Failed to verify ID token")?;
        let provider_subject = claims.subject().as_str().to_string();
        let name = claims
                .name()
                .and_then(|n| n.get(None).map(|n| n.to_string()));
        let email = claims
                .email()
                .ok_or_else(|| anyhow!("Email is required"))?
                .to_string();
        // Add user info elsewhere.

        let user_id = format!("PROVIDER-UUID:{provider_subject}");
        Ok(Account::<Role, Group>::new(&user_id, &[Role::User], &[]))
    })
    .with_jwt_codec("my-app", codec, 86400);

Alternatives considered

Honestly, I'm not a rust wizard, yet.

Prior art and references

No response

Breaking changes

Possibly (soft break, deprecations)

Breaking changes and migration strategy

No response

Feature flag

Unsure

Configuration surface

No response

Security and privacy considerations

  • Encourages/enables validation on id_token claims.
  • Reduces attack surface, since we don't need to make another request to userinfo and the info that we have is verified via a crypto signature.
  • On the flip side, if a service must handle providers like GitHub and other proper OIDC providers (Google, Microsoft, Tailscale OIDC), simultaneously, then we may have increased the complexity, since this account handler would conditionally use the id_token claims for normal providers, but would make a userinfo request for GitHub.

Performance implications

No response

Observability (logging/metrics/tracing)

No response

Documentation and examples

No response

Acceptance criteria

  • Mapper API (or new variant) surfaces id_token JWT to user code

Contribution readiness

  • I am willing to help implement this feature
  • I can contribute API review feedback
  • I will include tests and docs updates in a PR
  • I have not included secrets, tokens, or PII in this request

Contact (optional)

@linux4life798

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions