Skip to main content

Qontak | Platform | Centralize SSO Token — Centralized Web Session Integration

Product Requirements Document · NEW PRD v1.0


Superseded by centralized-sso-token.md — this early draft (Hub-Chat + Launchpad scope only) was superseded by the broader 4-product PRD, which carries the assigned Epic BIF-7802. Kept for historical reference only.


HEADER BLOCK

FieldValue
PMQontak PM Group
PRD Version1.0
StatusDEPRECATED
PRD TypeNEW
EpicTBD — add once Epic is created
SquadBifrost
RFC LinkRFC: Centralized Web Session Between Product and SSO
Figma MasterN/A — no UI changes required
AnchorNo — standalone, single-squad
Labelsepic:qontak-platform | module:sso | feature:centralized-session
Last Updated2026-06-30

Table of Contents


1. One-liner + Problem

One-liner: Integrate the Mekari Session SDK into Qontak products so that user sessions are synchronized with SSO — logging out or switching accounts on any Mekari product is immediately reflected in Qontak without stale session state.

Problem: Qontak's products (hub-chat and qontak-launchpad) each manage sessions independently. When a user logs out from SSO (account.mekari.com) or switches to a different Mekari account, Qontak products have no mechanism to detect this. As a result:

  1. A user who logs out of SSO remains fully logged in to Qontak — their session persists until it naturally expires, potentially exposing another user's company data.
  2. A user who switches SSO accounts (e.g. from Company A to Company B) can land back on a Qontak page still showing Company A's data, because the product session was never invalidated.
  3. Hub-chat currently maintains three parallel token chains (chat_sso_token, crm_sso_token, global_sso_token) with no centralized validation — token drift leads to inconsistent auth state.
  4. Qontak Launchpad uses LAUNCHPAD_SSO_ID cookies and global_sso_token for session tracking, but has no event-driven mechanism to react to SSO-side session changes.

The Platform team (Account & Launchpad) is building a centralized solution: a mekari-session JS SDK and a Session Manager service (RFC: Centralized Web Session Between Product and SSO). Qontak's responsibility is to integrate this SDK into its frontend products and update its logout flows to propagate session termination through SSO.


2. Target Users + Persona Context

PersonaRoleGoalPainWorkaround
Primary — Qontak End UserAgent or Admin using hub-chat or Qontak LaunchpadLog out from one Mekari product and have all products reflect that immediatelyAfter logging out from SSO or another Mekari product, still has full access to Qontak — session is not revokedNone — unaware the session is stale until a colleague tries to access the same browser
Primary — Multi-account UserUser who manages multiple Mekari company accountsSwitch companies on SSO and immediately work in the correct company context in QontakSwitches SSO account to Company B but Qontak still shows Company A's data — must manually sign out and back inManually sign out from Qontak, then re-sign in after SSO switch
Secondary — Qontak Frontend EngineerDev maintaining hub-chat or qontak-launchpad-feSingle, reliable source of truth for session validityManages three parallel token chains with no cross-product validation; token drift is hard to debugPeriodic token sync via syncSsoCookie() — fires regardless of actual SSO session state

3. Non-Goals

  1. This does not replace Qontak's existing OAuth2/Doorkeeper token management in hub-service — the SDK validates session state; the existing token system continues to handle API authorization.
  2. This does not auto-revoke access & refresh tokens when the user is idle for 2 hours (out of scope per RFC).
  3. This does not cover mobile apps — web only.
  4. This does not implement the Session Manager service or the SDK itself — that is owned by the Account & Launchpad Platform team.
  5. This does not modify Qontak's existing Redis or session storage — Qontak does not write to the centralized SSO Redis.
  6. This does not build a new logout UI — the existing logout screens are preserved; only the destination of the logout redirect changes.
  7. This does not gate access to SSO login/callback flows — the existing OAuth2 authorization code flow is unchanged.
  8. This does not apply to non-Qontak One clients (unified_app = false) — the SDK is only initialized for accounts on the unified platform.

Scope Changes

  • Frontend (hub-chat) — Install @mekari/sdk; initialize Session with user_sso_id on every page via global middleware; handle logged_in, logged_out, switch_user, server_down events; gate full behavior behind centralized_session feature toggle.
  • Frontend (qontak-launchpad-fe) — Same SDK integration as hub-chat; update unified logout to call SSO sign-out endpoint.
  • Backend (hub-service) — Update product logout flow to redirect to account.mekari.com/sign_out after destroying the local session; sync current company from SSO after session creation.
  • Backend (qontak-launchpad) — Update logout routing to propagate to SSO sign-out endpoint; align update_last_session webhook with Session Manager's session tracking.

4. Constraints

  1. Platform dependency gate: This PRD cannot be released until the Platform/Account & Launchpad team delivers: (a) Session Manager service at account.mekari.com/sm/*, (b) @mekari/sdk published and stable, (c) Qontak domains added to the SDK CSP frame-ancestors or referrer whitelist.
  2. Feature toggle required: All behavioral changes must be gated behind a centralized_session feature flag to allow safe rollback if Session Manager is degraded.
  3. SDK SLA dependency: Hub-chat pages are high-traffic (up to 2.9k RPS at clock-in/out). Session Manager's published SLA is 50ms p95 at 6k RPS. Qontak FE must implement the server_down fallback correctly to avoid user disruption if that SLA is breached.
  4. No domain-crossing: Session validation relies on the _mekari_account cookie. Qontak's domains (qontak.com, qontak.net) must be declared as allowed origins in the SDK CSP policy before integration goes live.
  5. Backward compatibility: When centralized_session toggle is OFF, existing auth behavior (current cookie/localStorage token chains) must continue working without any regression.
  6. Qontak One only: The SDK must only be initialized for accounts where unified_app = true. Non-unified accounts (unified_app = false) must continue using the existing auth flow with no changes.

5. Background & Current State

Current Session Architecture Per Product

ProductSession StorageToken KeysLogout Flow
hub-chat (FE)Cookies + localStorageqontak._token.hub, qontak._refresh_token.hub, chat_sso_token, crm_sso_token, global_sso_tokenClears cookies + localStorage; does NOT call SSO sign-out
hub-service (BE)Doorkeeper OAuth2 + cookieschat_sso_token, chat_sso_refresh_token, crm_sso_token, global_sso_tokenRevokes OAuth2 tokens; does NOT call SSO sign-out
qontak-launchpad-fe (FE)Cookiesglobal_sso_token, global_sso_refresh_token, global_sso_valid_until, LAUNCHPAD_SSO_IDCalls ChatPanel /logout with is_unified_logout=true; does NOT call SSO sign-out directly
qontak-launchpad (BE)Header-based (X-Authenticated-Userid + Bearer) + Redis cache (24h TTL)N/A (stateless)No dedicated logout endpoint — token invalidation delegated upstream

Key Gap: None of the four products currently validate session state against SSO at page load or on an interval. They rely entirely on their own token TTL and refresh logic, which operates independently of the SSO session's actual state.

What the Platform Team Delivers (from RFC)

ComponentDescription
Session Manager ServiceGo service hosted at account.mekari.com/sm/* via Kong/MAG. Maintains session state in a dedicated Redis. Validates _mekari_account cookie and returns user_sso_id
@mekari/sdkJS SDK (CJS + ESM). Injects an invisible iframe pointing to account.mekari.com/sm/current. Emits events: logged_in, logged_out, switch_user, server_down. Uses postMessage to return session state to the parent page
Centralized RedisSeparate from SSO's existing Redis. Stores msi:session:{sessionID} (1 day TTL) and msi:sessionmapping:{user_sso_id}. Accessible only by SSO and Session Manager
Session Eventslogged_in — session valid, user_sso_id matches; logged_out — session gone (idle 2h or explicit logout); switch_user — session exists but different user_sso_id; server_down — Session Manager unreachable
Fallback mechanismSDK reads msli (Mekari Session Logged In) localStorage key + _mekari_account cookie as fallback when Session Manager is down

6. New Features

F1: Mekari Session SDK Integration (hub-chat)

Initialize @mekari/sdk on every page of hub-chat, passing the current user's user_sso_id. React to session events to enforce session state consistency:

  • logged_in → continue normally; update msli timestamp
  • logged_out → trigger sign-out flow (clear tokens, redirect to SSO sign-in)
  • switch_user → destroy local session, redirect to SSO autologin, rebuild session for the new account
  • server_down → use msli + _mekari_account cookie as fallback; sign out if fallback also fails

F2: Mekari Session SDK Integration (qontak-launchpad-fe)

Same as F1 but implemented in qontak-launchpad-fe (Nuxt), leveraging the existing authenticated.global.ts middleware hook for SDK initialization.

F3: Centralized Logout Flow — Hub-Service

After destroying the local Qontak session, redirect the user to account.mekari.com/sign_out instead of terminating the flow at the product. This ensures the SSO session is also terminated, which in turn causes Session Manager to invalidate all product sessions for that user.

F4: Centralized Logout Flow — Qontak Launchpad

Update Qontak Launchpad to route logout through account.mekari.com/sign_out to propagate session termination to SSO. Align update_last_session webhook behavior with Session Manager's last_request_at TTL logic.

F5: Current Company Sync After Session Event

After logged_in or switch_user results in a new session being created in Qontak, call https://api.mekari.com/v1.1/users/{user_sso_id}/current_company via Qontak BE (using client_credentials) to ensure the correct company context is set. This guards against the multi-account scenario where session switches leave stale company data.


7. System Flow + User Stories + ACs

7.1 System Flow

F1/F2: SDK Event Flow (FE)

User accesses Qontak page
→ Middleware loads SDK: new Session({ current_user: user_sso_id })
→ SDK injects hidden iframe → account.mekari.com/sm/current (sends _mekari_account cookie)
→ Session Manager validates session in Redis
→ If session exists: update last_request_at, return user_sso_id via postMessage
→ If session absent: return null
→ SDK compares user_sso_id
→ Match → emit logged_in → update msli timestamp
→ Mismatch → emit switch_user → destroy session, redirect to SSO autologin
→ Null (no session) → emit logged_out → sign-out flow
→ Timeout/unreachable→ emit server_down → fallback: check msli + _mekari_account cookie

F3/F4: Centralized Logout Flow (BE)

User clicks logout on Qontak
→ Qontak FE calls Qontak BE logout endpoint
→ Qontak BE: destroy local session + revoke OAuth tokens
→ Qontak BE / FE: redirect user to account.mekari.com/sign_out
→ SSO: destroy _mekari_account session in Redis Session
→ SSO: clear session mapping (msi:sessionmapping:<user_sso_id>)
→ SSO: redirect user to account.mekari.com/users/sign_in

F5: Current Company Sync

SDK emits logged_in or switch_user
→ Qontak FE → Qontak BE: GET /current_company
→ Qontak BE → SSO: GET /v1.1/users/{user_sso_id}/current_company (client_credentials)
→ Qontak BE: set company context
→ Qontak FE: render correct company data

7.2 User Stories

User StoryImportanceTechnical NotesAcceptance Criteria
[SSO-S01] — Hub-Chat SDK Integration

As a hub-chat user, I want my Qontak session to automatically expire when I log out of SSO or any Mekari product, so that my company data cannot be accessed by another person using the same browser.
Must HaveInstall @mekari/sdk. Initialize Session in authenticated.global.ts middleware after user is loaded. Gate entire SDK behavior behind centralized_session feature toggle. Store SDK instance in AuthStore or a dedicated composable.— Happy Path —
• AC-1: Given centralized_session toggle is ON, when a hub-chat page loads and the user is authenticated, then the SDK is initialized with the correct user_sso_id before the user can interact with the page.
• AC-2: Given the SDK emits logged_in, then msli localStorage key is updated with the current timestamp and the user sees the page normally.
• AC-3: Given the SDK emits logged_out (SSO session ended), then all local tokens and cookies are cleared and the user is redirected to the Qontak sign-in page.
• AC-4: Given the SDK emits switch_user (user switched SSO account), then the Qontak FE destroys the local session, redirects to SSO /auth for autologin, and after redirect back, creates a new Qontak session for the new account with correct company data.
— Error / Unhappy Path —
• ERR-1: Given the SDK emits server_down, when msli exists and the diff with current time is < 2 hours AND _mekari_account cookie is valid, then the SDK returns logged_in as a fallback and normal page access continues.
• ERR-2: Given the SDK emits server_down, when msli is absent OR diff > 2 hours OR _mekari_account cookie is invalid, then the user is signed out.
• NEG-1: Given centralized_session toggle is OFF, then SDK is not loaded and existing hub-chat token flow behaves exactly as before.
• NEG-2: Given the authenticated user's account has unified_app = false, then the SDK is not initialized and the existing hub-chat auth flow is used unchanged.
[SSO-S02] — Qontak Launchpad FE SDK Integration

As a Qontak Launchpad user, I want my Launchpad session to automatically expire when I log out of SSO or any Mekari product, so that stale sessions from a previous company setup flow cannot persist.
Must HaveSame SDK integration pattern as SSO-S01. Launchpad's authenticated.global.ts is the integration point. Replace current LAUNCHPAD_SSO_ID cookie check with SDK event. Remove or retain LAUNCHPAD_SSO_ID as secondary fallback during migration.— Happy Path —
• AC-1: Given centralized_session toggle is ON and a Launchpad page loads, then SDK is initialized with the user's user_sso_id.
• AC-2: Given SDK emits logged_out, then the Launchpad session is destroyed and user is redirected to sign-in.
• AC-3: Given SDK emits switch_user, then Launchpad destroys session, redirects to SSO for autologin, and rebuilds session with the new account's company context.
— Error / Unhappy Path —
• ERR-1: Given SDK emits server_down, then fallback behavior (msli + cookie check) applies identically to SSO-S01.
• NEG-1: Given centralized_session toggle is OFF, then existing Launchpad session flow (LAUNCHPAD_SSO_ID + global_sso_token) is unchanged.
• NEG-2: Given the authenticated user's account has unified_app = false, then the SDK is not initialized and existing Launchpad auth flow is used unchanged.
[SSO-S03] — Hub-Service Centralized Logout

As a Qontak system, when a user logs out from Qontak, I want the SSO session to also be terminated so all other Mekari products detect the logout via the SDK.
Must HaveModify the logout endpoint in hub-service to redirect to account.mekari.com/sign_out after local session destruction and OAuth token revocation. This propagates the logout through SSO Redis, which invalidates the _mekari_account session.— Happy Path —
• AC-1: Given a user clicks logout on hub-chat, then hub-service destroys the local Qontak session and revokes OAuth tokens, then redirects the user to account.mekari.com/sign_out.
• AC-2: Given the user is redirected to SSO sign-out, then the _mekari_account session is destroyed in SSO Redis and the user lands on account.mekari.com/users/sign_in.
• AC-3: Given another browser tab has hub-chat open after the logout, when the SDK polling interval fires, then the SDK emits logged_out and that tab is also signed out.
— Error / Unhappy Path —
• ERR-1: Given the redirect to account.mekari.com/sign_out fails (SSO unreachable), then the user is still signed out of Qontak locally and shown the Qontak sign-in page.
• NEG-1: Given centralized_session toggle is OFF, then the existing logout behavior (no SSO redirect) is preserved.
[SSO-S04] — Qontak Launchpad BE Centralized Logout

As a Qontak system, when a user logs out from Qontak Launchpad, I want the SSO session to also be terminated so all products detect the logout.
Must HaveCurrently, qontak-launchpad has no dedicated logout endpoint — termination is delegated upstream to hub-service via unified logout. Confirm that the unified logout path already propagates to SSO sign-out after SSO-S03 is done, OR add an explicit SSO sign-out redirect in qontak-launchpad's logout handler if one exists.— Happy Path —
• AC-1: Given a user initiates logout from Qontak Launchpad FE, when the unified logout chain completes (ChatPanel /logout → hub-service → SSO sign-out), then the _mekari_account session is destroyed.
• AC-2: Given SSO-S03 is implemented, then the existing unified logout chain in qontak-launchpad-fe already achieves SSO sign-out without additional changes to qontak-launchpad BE. (If not, a direct SSO redirect must be added.)
— Error / Unhappy Path —
• ERR-1: Given hub-service (ChatPanel) is unreachable during logout, then qontak-launchpad destroys local cache (Redis user/company lookup) and redirects user to SSO sign-out directly as fallback.
[SSO-S05] — Current Company Sync After Session Event

As a Qontak user who switches SSO accounts, I want the correct company to be displayed immediately after switching, so I don't see data from my previous company.
Must HaveAfter logged_in or a successful switch_user → autologin cycle, Qontak FE calls Qontak BE to fetch current company from SSO API (GET /v1.1/users/{user_sso_id}/current_company via client_credentials). This is per RFC recommendation.— Happy Path —
• AC-1: Given SDK emits logged_in and Qontak BE creates a session, then Qontak BE calls SSO GET /v1.1/users/{user_sso_id}/current_company (client_credentials) and stores the result as the user's active company context.
• AC-2: Given SDK emits switch_user and the autologin cycle completes with a new Qontak session, then the new company context from SSO is fetched and rendered before the user interacts with any company-specific data.
— Error / Unhappy Path —
• ERR-1: Given the SSO /current_company call fails, then the user is shown an error state and prompted to refresh; Qontak does not silently use the previous company context.

8. Rollout

This PRD is a SUPPORT initiative from Qontak's perspective — Qontak integrates what the Platform team builds, following the rollout sequence defined in the RFC.

PhaseDescriptionOwnerDependency
Phase 0 — PrerequisiteConfirm Platform team has deployed Session Manager, published @mekari/sdk, and whitelisted Qontak domains (qontak.com, qontak.net) in SDK CSPPlatform / Account & LaunchpadSession Manager deployed at account.mekari.com/sm/*
Phase 1 — SDK SpikeInstall @mekari/sdk in hub-chat and qontak-launchpad-fe on staging; validate iframe + postMessage flow against Session Manager; confirm all four events fire correctlyBifrost FEPhase 0 complete
Phase 2 — BE Logout UpdateUpdate hub-service logout to redirect to SSO sign-out; validate qontak-launchpad unified logout chain propagates to SSO correctlyBifrost BEPhase 0 complete
Phase 3 — Internal RolloutEnable centralized_session flag for internal Mekari company CIDs only; monitor SDK event rates and server_down frequency; validate company sync accuracyBifrostPhase 1 + 2 complete
Phase 4 — Gradual GAEnable centralized_session flag progressively by user percentage (10% → 50% → 100%); monitor p95 SDK latency and server_down event rate; back off if anomalies detectedBifrostPhase 3 stable for 1 week

Rollback: Disable centralized_session feature flag → reverts to pre-integration token behavior with no code changes required.


9. Observability

SignalToolAlert Threshold
server_down event rate from SDKDatadog / custom metric> 1% of SDK initializations in 5-minute window
SDK initialization failure (sdk.js load error)Sentry / browser error trackingAny error on sdk.js load
Hub-service logout redirect failure rateDatadog> 0.1% of logout requests fail to reach SSO sign-out
/current_company call failure rate after session eventDatadog> 1% failure rate
switch_user event rate (anomaly detection)DatadogSpike > 5× baseline in 5-minute window

10. Success Metrics

Primary KPI: % of Qontak sessions that are correctly terminated within 30 seconds of SSO sign-out

  • Baseline: 0% (no detection today)
  • Target: ≥ 95% within 30 seconds post-GA

Session Consistency:

  • switch_user events resulting in correct company context after autologin: ≥ 99%

Stability:

  • server_down event rate: < 0.5% of SDK initializations
  • Zero regression in existing auth flows when centralized_session toggle is OFF

11. Dependencies

DependencyOwnerBlocker?Notes
Session Manager service deployed at account.mekari.com/sm/*Account & Launchpad PlatformYesSDK will not function without this
@mekari/sdk package published to npm/internal registryAccount & Launchpad PlatformYesFE integration blocked until SDK is stable
Qontak domains added to SDK's CSP frame-ancestors whitelistAccount & Launchpad PlatformYesIframe security policy blocks cross-origin postMessage without this
centralized_session feature flag created in LaunchDarklyBifrostYesAll behavior is gated; must exist before any code ships
SSO GET /v1.1/users/{user_sso_id}/current_company endpoint available (client_credentials)Account & Launchpad / SSOYesRequired for company sync (SSO-S05)
Confirmation of unified logout chain (qontak-launchpad → hub-service → SSO)Bifrost BENo — investigation itemDetermines whether SSO-S04 needs additional BE work

12. Key Decisions + Alternatives Rejected

DecisionRationale
Integrate Platform SDK rather than build custom session validationThe RFC's Session Manager service + SDK provides a shared, scalable solution. Building per-product custom validation would require each product to individually hit SSO Redis, defeating centralization.
Gate all changes behind centralized_session feature toggleSession management is critical path. Any regression could lock out users. A toggle allows instant rollback without a code deploy.
Route logout through account.mekari.com/sign_out (BE-initiated redirect)SSO sign-out is the authoritative termination point. Qontak-only logout leaves the _mekari_account cookie alive, meaning other products (and the SDK) see the user as still logged in.
Keep existing OAuth2/Doorkeeper token system unchangedThe SDK handles session validation; OAuth2 handles API authorization. These are complementary, not competing, concerns. Replacing the token system is out of scope.
Use switch_user → autologin flow rather than silent session swapRFC design: product cannot silently assume the new user's identity. A fresh OAuth2 authorization code flow via SSO ensures the new account's tokens are properly issued.

13. Open Questions

#QuestionOwnerStatus
1What is the concrete timeline for Platform team to deliver @mekari/sdk and Session Manager to staging? Bifrost cannot start Phase 1 without it.Account & Launchpad PMOpen
2Which SDK security model will Platform use: CSP frame-ancestors whitelist OR referrer/origin validation? This determines how Qontak domains are registered and whether a deploy is needed each time a new subdomain is added.Platform / InfosecOpen
3Does the existing unified logout chain (qontak-launchpad-fe → ChatPanel /logout → hub-service) already propagate to account.mekari.com/sign_out after SSO-S03 is implemented, or does qontak-launchpad BE need its own redirect?Bifrost BEOpen — investigation needed
4Should hub-chat's syncSsoCookie() and is_sync_auth seamless auth pattern be deprecated once centralized_session is at 100%? Or are they serving a different purpose (token propagation between hub-chat and CRM)?Bifrost FEOpen
5What is the session.refresh() call throttle interval (TBD in RFC)? Hub-chat makes high-frequency user interactions — this interval affects how often last_request_at is extended in Session Manager Redis.PlatformOpen
6Does the centralized_session toggle live in LaunchDarkly, in hub-service's feature flag system, or somewhere else? Who controls it?Bifrost / PlatformOpen

PRD CHANGELOG

VersionDateAuthorChanges
1.02026-06-30Qontak PM GroupInitial draft based on RFC: Centralized Web Session Between Product and SSO