Skip to content

Auth & Sessions ​

This document covers the authentication flows, session lifecycle, token management, and epoch-based invalidation system that form the core of AuthNexus's business logic.

Authentication Methods ​

AuthNexus supports two primary authentication methods, both handled over the custom binary protocol on the mTLS TCP channel:

Password Login ​

cpp
AuthResult result = client.login("username", "password");
  1. SDK sends username + password over the encrypted channel.
  2. Server validates credentials against HMAC-SHA256 hash in the Runtime DB.
  3. On success, server issues a 32-byte opaque session token and returns user metadata.
  4. Token is bound to the device ID from the SDK config.

Card Key Login ​

cpp
AuthResult result = client.card_key_login("XXXX-YYYY-ZZZZ");
  1. SDK sends the card key string.
  2. Server validates the key: existence, activation status, expiration, device binding.
  3. On first use, the card key is activated and bound to the user/device.
  4. On success, a session token is issued.

Card key login combines authentication and service activation in a single operation.

User Registration ​

cpp
AuthResult result = client.register_user("username", "password", "email", "invite_code");

Registration creates a new user account bound to the application (app_id) determined by the mTLS client certificate. The optional invite code supports referral tracking.

Session Lifecycle ​

Session Creation ​

A session is created on successful login (password, card key, or registration). It consists of:

ComponentDescription
Session token32-byte cryptographically random value
Device bindingThe device_id from the SDK config
Auth epochThe user's epoch at login time
Session expiryAbsolute time when the session becomes invalid
Service expiryThe user's service expiration (subscription end)

Session Validation ​

Every authenticated request validates the session:

  1. Token lookup -- the 32-byte token must exist in the session store.
  2. Epoch check -- the token's epoch must match the user's current auth epoch. If the epoch has been bumped (admin action, password change), the token is rejected.
  3. Session expiry -- the session must not have timed out.
  4. Device match -- the requesting device must match the bound device ID.

Session Termination ​

Sessions end through:

  • Explicit logout -- client.logout() invalidates the token.
  • Epoch bump -- any admin action that advances the user's auth epoch invalidates all sessions for that user.
  • Session timeout -- natural expiration.
  • Force logout push -- the admin can push a ForceLogout notification via the push system.

Heartbeat Mechanism ​

The heartbeat system maintains session liveness and provides the server with client presence information.

Enabling Heartbeats ​

cpp
client.enable_heartbeat(std::chrono::seconds(30));  // Default: 30 seconds

This spawns a dedicated heartbeat thread that periodically sends keepalive messages to the server.

Heartbeat Response ​

cpp
struct HeartbeatResult {
    bool        success;
    ResultCode  code;
    std::string message;
    uint64_t    server_time;
    uint64_t    session_expire_time;
    uint64_t    service_expire_time;
};

The server returns updated expiry times with each heartbeat, allowing the SDK to track session health without additional requests.

Heartbeat Contribution to Presence ​

Heartbeat data is aggregated by server nodes and reported to the Control Plane during checkins. This powers the online user presence system visible in the admin dashboard.

Auth Epoch System ​

The auth epoch is the core mechanism for instant session invalidation across distributed server nodes.

Design ​

  • Each user has a monotonically increasing auth_epoch counter.
  • Tokens embed the epoch at issuance time.
  • Any mismatch between a token's epoch and the user's current epoch causes immediate rejection.

Operations That Bump Epoch ​

OperationTrigger
Password changeUser or admin initiates
Forced logoutAdmin action via dashboard
Security actionAdmin blacklists user or resets credentials
Token revocationDELETE /admin/v1/tokens/user/:user_id

Propagation ​

Admin bumps epoch (Control DB)
    ↓
auth_epoch_changes table updated
    ↓
Channel 2 SSE: epoch.bumped (hint)
    ↓
Channel 3: RuntimeSecurityDeltaPuller pulls delta
    ↓
Server Runtime DB + in-memory cache updated
    ↓
Next token validation rejects stale tokens

Typical propagation latency: under 5 seconds with healthy SSE, under 1 second in most cases.

Card Key Operations ​

Beyond login, card keys support additional operations:

Card Key Recharge ​

cpp
CardKeyRechargeResult result = client.card_key_recharge("XXXX-YYYY-ZZZZ");

Extends the user's service expiration by the card key's duration. Returns the new expiration time and added minutes.

Card Key Rebind ​

cpp
CardKeyRebindResult result = client.card_key_rebind("XXXX-YYYY-ZZZZ", "new_device_id");

Rebinds a card key to a new device, subject to rebind count limits and cooldown periods.

Device Rebind ​

cpp
RebindDeviceResult result = client.rebind_device("rebind_ticket", "new_device_id", "reason");

Changes the device binding for the current session. Returns remaining rebind quota and next available rebind time.

Password Change ​

cpp
AuthResult result = client.change_password("old_password", "new_password");

Password change bumps the user's auth epoch, invalidating all existing sessions. The current session receives a new token.

Query Operations ​

These operations are available within an authenticated session:

cpp
UserInfoResult info = client.get_user_info();
AccountStatusResult status = client.get_account_status();
UserAttributeResult attr = client.get_user_attribute();
CardKeyAttributeResult card = client.query_card_key_attribute("XXXX-YYYY-ZZZZ");

User Info ​

Returns profile data: username, email, balance, expiration, device ID, registration details, login count, and status.

Account Status ​

Returns comprehensive account state: balance, quotas, service plan, features, concurrent connection limits, usage tracking, and subscription details.

Token Utilities ​

The SDK provides helper functions for token serialization:

cpp
std::string hex = auth_nexus::sdk::token_to_hex(token);
std::optional<Token> token = auth_nexus::sdk::token_from_hex("abcdef...");

These enable persistent token storage for session resume across application restarts.

Next Steps ​