Skip to content

feat: Identify client at login/refresh (M2-10999) - #2097

Open
sricharan-varanasi wants to merge 4 commits into
developfrom
session-token-client-type
Open

feat: Identify client at login/refresh (M2-10999)#2097
sricharan-varanasi wants to merge 4 commits into
developfrom
session-token-client-type

Conversation

@sricharan-varanasi

Copy link
Copy Markdown
Contributor
  • Tests for the changes have been added
  • Related documentation has been added / updated
  • For new features, QA automation engineers have been tagged
  • OSS packages added to
    Curious open source credit page

📝 Description

🔗 Jira Ticket M2-10999

Part of the session-timeout project: mobile will keep long-lived tokens while web/admin move to short-lived ones (follow-up ticket). Before we can vary token lifetime by client, the backend needs to reliably know - and remember for the life of a session - which client (web / admin / mobile) each token belongs to. This PR only adds that identification; it makes no change to token lifetimes or any other behavior.

All three clients already send a Mindlogger-Content-Source header on every request. This PR reads it at token-issuance time and embeds it as a new optional client JWT claim, propagated through refresh so it survives for the whole session, and surfaced in audit events for observability.

Changes include:

  • New strict header dependency get_optional_mindlogger_content_source: valid header → the client name; missing or invalid header → None ("unknown"), never a guess. (The existing get_mindlogger_content_source, which defaults unknown to web, is left untouched since another endpoint still depends on that behavior.) Guessing "unknown → web" would have been dangerous here: mobile app versions released earlier might not send the header, and misclassifying them as web would eventually give them a short-lived token in the follow-up ticket.
  • New optional client claim on TokenPayload, so tokens issued before this deploys keep parsing with client = None - no forced re-login on rollout.
  • client is embedded in both the access and refresh token at all three token-issuance points: plain login, MFA-TOTP verification, and MFA-recovery-code verification.
  • The refresh endpoint copies the client claim from the incoming refresh token onto the newly minted access token (and onto the reprinted refresh token in the rare signing-key-transition path), so the claim persists across renewals instead of being lost after the first refresh.
  • Login/refresh audit events now record the raw header value as client.source, for visibility into rollout (e.g. spotting mobile clients still not sending the header).

✏️ Notes

  • Zero behavior change: token lifetimes are identical in every case (asserted directly in tests).
  • No feature flag: this change is additive and backward compatible.

return access_payload, refresh_payload

@staticmethod
def _assert_lifetimes_unchanged(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: Just a thought, do you feel the name of this function truly represents what it does?

@adeiji adeiji left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me, just made one comment that is non-blocking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants