RFC: Managed Concurrent Sessions & Device Tracking
RFC: Managed Concurrent Sessions & Device Tracking
- Authors: - Prathik Shetty(@pshettydev)
- Date: 2026-01-13
- Status: Accepted
Abstract
This RFC outlines the implementation of a robust device tracking and session management system for the PNow ATS. The system transitions from a potential "Single Active Device" model (which although defined in schema but not in use by the application) to a "Managed Concurrent Sessions" model. This approach allows users to access the platform from multiple devices (e.g., laptop and mobile) simultaneously while strictly tracking device identity, IP addresses, and geographical locations for security auditing and anomaly detection.
Motivation
In modern recruitment workflows, users frequently switch contexts between desktop applications and mobile devices. Enforcing a strict "single active session" policy (where logging in on a new device or browser, logs out the desktop) creates significant friction ("login fatigue") and degrades the user experience.
However, security remains paramount given the sensitive PII (candidate data) handled by the ATS. We needed a solution that:
- Enhances UX: Supports multi-device productivity without constant re-authentication.
- Improves Security: Provides deep visibility into who is accessing the system, from where, and on what device.
- Enables Auditing: Maintains a historical record of access locations and IPs to detect suspicious patterns (e.g., impossible travel, unknown devices).
Approaches
Evaluated three primary strategies for session management:
1. Single Active Device (Strict Session Management)
- Concept: A user can only be logged in on one device at a time. A new login invalidates the previous session token.
- Pros: Minimizes attack surface; prevents account sharing; simplifies backend logic (no sync needed).
- Cons: Poor UX for modern multi-device users; frustrates users switching between contexts.
[!NOTE]
This is considered the end goal for high-security environments. However, implementing this immediately would introduce excessive friction. We chose to start with a more flexible approach (Option 3) to gather usage data and provide a smooth initial experience, while building the infrastructure (device tracking) that could enable this strict mode in the future.
2. Unrestricted Multi-Device Access (Earlier implemented approach)
- Concept: Users can log in from as many devices as they want with no specific tracking.
- Pros: Maximum convenience; zero friction.
- Cons: High security risk; rampant account sharing (revenue leakage); difficult to detect compromised credentials until it's too late.
3. Managed Concurrent Sessions (Auditable Security) - CHOSEN (Initial Implementation)
- Concept: Allow multiple sessions but rigorously track and fingerprint each device. Differentiate between known devices and new ones. Log location history per device.
- Pros: Balances UX and Security. Allows productivity while enabling security features like "Revoke Device," "New Device Alerts," and "Suspicious Location Detection."
- Cons: Higher implementation complexity (requires device fingerprinting and location history schema).
[!IMPORTANT] Strategic Decision: This approach was selected to prioritize user adoption and smooth workflow integration. By implementing robust tracking first, we establish the necessary audit trails and device identity infrastructure. This leaves room to enforce stricter policies (like limiting the number of concurrent sessions or moving to Single Active Device) in the future without architectural rework.
Proposal
We implemented Option 3: Managed Concurrent Sessions. This involves changes across the full stack, from the frontend client to the database schema.
1. Architecture Overview
- Frontend Identity: The client generates a persistent unique identifier (
x-device-id) stored in local storage. This ID, along with the User Agent, is sent with every API request. - API Gateway: Acts as the ingress point. It extracts the
x-device-id,User-Agent, and Client IP (request-ip). It proxies these details to the Authentication Service during Login and Token Refresh events. - Authentication Service: The source of truth. It resolves the IP to a physical location (
geoip-lite) and updates the database. It maintains a registry ofUserDevicesand a history ofUserDeviceLocations.
2. Schema Changes
The database schema (prisma/tenants/schema/users/users.prisma) was updated to support history tracking and removed restrictive unique constraints.
UserDevice:- Removed unique constraint on
user_idto allow multiple devices per user. - Added
current_ip(@db.Inet) for quick access to the last known IP. - Added
device_metadatato store User Agent details.
- Removed unique constraint on
UserDeviceLocation:- Removed unique constraints on
device_idto allow a one-to-many relationship (Device -> Locations). - Added
ip_address(@db.Inet) andcreated_attimestamps to form an immutable location history log.
- Removed unique constraints on
3. Implementation Details
Frontend (axios interceptors)
A shared Axios interceptor (apps/frontend/web/src/utils/api/axiosInstance.ts) manages the device identifier. It checks localStorage for an existing ID or generates a UUID, then injects it into request headers:
The same interceptor handles 401 refresh retries for API gateway calls (and avoids retrying /auth/refresh itself).
Backend (auth-service)
A new trackDevice method was implemented in AuthenticationService:
- Upsert Device: Updates
last_accessed_atandcurrent_ip. - Location Resolution: Uses
geoip-liteto resolve coordinates from the IP. - History Logging: If the IP has changed since the last record, a new
UserDeviceLocationentry is created.
Additional updates:
- Cookie parsing is enabled (
cookie-parser) so refresh-token guards can read cookies. - Device metadata now stores structured user-agent details (object entries) instead of raw strings.
- New endpoints expose device lists and device history for the signed-in user.
API Gateway
The Gateway proxies refresh calls to the Auth Service, forwarding x-device-id, user-agent, and client IP, then extracts set-cookie from the response and re-sets access/refresh cookies for the client. It also exposes device list/history endpoints backed by auth-service. Login proxying remains unchanged.
4. Security Considerations
- IP Spoofing: We utilize
request-ipandx-forwarded-forheaders to correctly identify client IPs behind load balancers. - Trust: While
x-device-idis client-generated, combining it with signed JWTs and IP history creates a strong enough fingerprint for "Authorized Device" tracking.