Skip to main content

Authentication

FieldValue
Document IDASCEND-SEC-003
Version1.0.0
Last UpdatedDecember 19, 2025
AuthorAscend Engineering Team
PublisherOW-KAI Technologies Inc.
ClassificationEnterprise Client Documentation
ComplianceSOC 2 CC6.1/CC6.2, PCI-DSS 7.1/8.3, HIPAA 164.312, NIST 800-53 AC-2/SI-4

Reading Time: 10 minutes | Skill Level: Intermediate

Overview

ASCEND provides dual authentication supporting both JWT (admin UI) and API keys (SDK). The system implements banking-level security controls including token blacklisting, session management, and MFA enforcement.

Authentication Methods

MethodUse CaseToken TypeMFA
JWT CookieAdmin UISession tokenRequired
Bearer TokenCognito/SSOJWTDelegated
API KeySDKHashed keyOptional

Dual Authentication Flow

+---------------------------------------------------------------------------------+
| DUAL AUTHENTICATION FLOW |
+---------------------------------------------------------------------------------+
| |
| REQUEST ARRIVES |
| | |
| v |
| +------------------------+ |
| | CHECK JWT COOKIE | 1. Session cookie from admin UI |
| +------------------------+ |
| | (not found) |
| v |
| +------------------------+ |
| | CHECK BEARER TOKEN | 2. Authorization: Bearer <token> |
| +------------------------+ |
| | |
| +-- JWT (3 parts)? ---> Validate with Cognito JWKS |
| | |
| +-- API Key? ---------> Verify hash, check rate limit |
| | |
| v (not found) |
| +------------------------+ |
| | CHECK X-API-KEY | 3. X-API-Key: <api_key> |
| +------------------------+ |
| | (not found) |
| v |
| +------------------------+ |
| | 401 UNAUTHORIZED | |
| +------------------------+ |
| |
+---------------------------------------------------------------------------------+

JWT Session Management

Login

curl -X POST "https://pilot.owkai.app/api/auth/login" \
-H "Content-Type: application/json" \
-d '{
"email": "user@company.com",
"password": "securePassword123!"
}'

Response:

{
"success": true,
"user": {
"id": 123,
"email": "user@company.com",
"role": "admin",
"organization_id": 1
},
"requires_mfa": true,
"mfa_session_token": "<temporary_token>"
}

MFA Verification

curl -X POST "https://pilot.owkai.app/api/auth/mfa/verify" \
-H "Content-Type: application/json" \
-d '{
"mfa_session_token": "<temporary_token>",
"totp_code": "123456"
}'

Response (sets session cookie):

{
"success": true,
"message": "Authentication successful",
"user": {
"id": 123,
"email": "user@company.com",
"role": "admin"
}
}

Logout

curl -X POST "https://pilot.owkai.app/api/auth/logout" \
-H "Cookie: owai_session=<session_token>"

Response:

{
"success": true,
"message": "Logged out successfully",
"tokens_revoked": 1
}

Token Security Features

Token Blacklist (AUTH-001)

# Source: security/enterprise_security.py:59
class TokenBlacklist:
"""
Thread-safe token blacklist for immediate revocation.
Banking-level security requires tokens to be revokable instantly.
"""

def revoke(self, token_jti: str, expires_at: datetime) -> None:
"""Revoke a token by its JTI (JWT ID)."""
with self._lock:
self._blacklist.add(token_jti)
self._expiry[token_jti] = expires_at

def is_revoked(self, token_jti: str) -> bool:
"""Check if a token has been revoked."""
return token_jti in self._blacklist

def revoke_all_user_tokens(self, user_id: int, db: Session) -> int:
"""Revoke ALL tokens for a user (logout from all devices)."""
pass

Refresh Token Rotation (AUTH-003)

# Source: security/enterprise_security.py:231
class RefreshTokenManager:
"""
Manages refresh token rotation for banking-level security.
Each time a refresh token is used, a new one is issued
and the old one is invalidated.
"""

def validate_and_rotate(self, token_jti: str) -> bool:
"""
Validate refresh token hasn't been used and mark it as used.
Returns True if token is valid (first use), False if reused.
"""
if self.is_used(token_jti):
return False
self.mark_used(token_jti)
return True

Session Fixation Prevention (AUTH-005)

# Source: security/enterprise_security.py:341
def regenerate_session(response: Response, old_session_id: Optional[str] = None) -> str:
"""
Regenerate session ID after authentication (prevents session fixation).
Returns new 256-bit cryptographically secure session ID.
"""
new_session_id = secrets.token_hex(32)
return new_session_id

Account Lockout

Lockout Policy (AUTH-004)

# Source: security/enterprise_security.py:285
class AccountLockoutManager:
"""
Manages account lockouts with exponential backoff.

Banking security requires:
- Lock after 5 failed attempts
- Exponential backoff: 5min, 15min, 1hr, 24hr
- Automatic unlock after cooldown period
"""

MAX_ATTEMPTS = 5
BACKOFF_MULTIPLIER = 3
INITIAL_LOCKOUT_MINUTES = 5
MAX_LOCKOUT_HOURS = 24

def calculate_lockout_duration(self, consecutive_lockouts: int) -> timedelta:
"""Calculate lockout duration with exponential backoff."""
minutes = self.INITIAL_LOCKOUT_MINUTES * (self.BACKOFF_MULTIPLIER ** consecutive_lockouts)
max_minutes = self.MAX_LOCKOUT_HOURS * 60
return timedelta(minutes=min(minutes, max_minutes))

Lockout Schedule

Lockout #DurationTotal Wait
15 minutes5 minutes
215 minutes20 minutes
345 minutes65 minutes
4+24 hours24+ hours

Concurrent Session Control

Session Limits (AUTH-011)

# Source: security/enterprise_security.py:530
class ConcurrentSessionManager:
"""
Manages concurrent session limits per user.
Banking security typically limits to 3-5 concurrent sessions.
When limit exceeded, oldest session is terminated.
"""

DEFAULT_MAX_SESSIONS = 5

def register_session(self, user_id, session_id, max_sessions=5):
"""
Register a new session, potentially removing oldest if limit exceeded.
Returns session ID that was removed (if any).
"""
pass

CSRF Protection

# Source: security/enterprise_security.py:419
class CSRFValidator:
"""CSRF protection using double-submit cookie pattern."""

CSRF_COOKIE_NAME = "owai_csrf"
CSRF_HEADER_NAME = "X-CSRF-Token"

@staticmethod
def validate(request: Request) -> bool:
"""
Validate CSRF token using double-submit cookie pattern.
Uses constant-time comparison to prevent timing attacks.
"""
cookie_token = request.cookies.get(CSRFValidator.CSRF_COOKIE_NAME)
header_token = request.headers.get(CSRFValidator.CSRF_HEADER_NAME)

return secrets.compare_digest(cookie_token, header_token)

Rate Limiting

Authentication Rate Limits

# Source: security/rate_limiter.py:33
RATE_LIMITS = {
# Authentication - STRICT limits
"auth_login": "5/minute",
"auth_refresh": "10/minute",
"auth_csrf": "20/minute",

# Password operations - VERY STRICT
"auth_password_change": "3/minute",
"auth_password_reset": "3/minute",

# MFA operations - STRICT
"auth_mfa_setup": "5/minute",
"auth_mfa_verify": "10/minute",

# Account operations
"auth_register": "3/minute",
"auth_logout": "30/minute"
}

Cognito Integration

Token Validation

# Source: dependencies_api_keys.py:421
# Cognito JWT verification using JWKS public keys
user_context = validate_cognito_token(token, db)

# Returns:
{
"user_id": 123,
"email": "user@company.com",
"role": "admin",
"organization_id": 1,
"cognito_user_id": "abc-123-xyz"
}

Session Creation

curl -X POST "https://pilot.owkai.app/api/auth/cognito-session" \
-H "Authorization: Bearer <cognito_token>"

Response (sets session cookie):

{
"success": true,
"user": {
"id": 123,
"email": "user@company.com",
"organization_id": 1
},
"session_expires_at": "2025-12-15T18:30:00Z"
}

Security Headers

Response Headers (AUTH-012)

# Source: security/enterprise_security.py:606
SECURITY_HEADERS = {
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"X-XSS-Protection": "1; mode=block",
"Strict-Transport-Security": "max-age=31536000; includeSubDomains",
"Content-Security-Policy": "default-src 'self'; frame-ancestors 'none';",
"Referrer-Policy": "strict-origin-when-cross-origin",
"Permissions-Policy": "geolocation=(), microphone=(), camera=()"
}

Best Practices

1. Use Secure Cookies

# Session cookies should be:
{
"httponly": True, # Prevent XSS access
"secure": True, # HTTPS only
"samesite": "strict" # CSRF protection
}

2. Implement Token Expiration

# Short-lived access tokens
{
"access_token_expires": "15 minutes",
"refresh_token_expires": "7 days"
}

3. Monitor Failed Logins

# Alert on suspicious activity
if failed_attempts > 3:
alert_security_team(user_email, ip_address)

4. Rotate Secrets Regularly

# JWT secrets should be rotated
{
"rotation_period": "90 days",
"minimum_entropy": "256 bits"
}

Next Steps

  • API Keys — SDK authentication
  • SSO — Enterprise SSO integration
  • RBAC — Role-based access control

Document Version: 1.0.0 | Last Updated: December 2025