Skip to main content

Security Features

CORTEX implements multiple layers of security to protect user accounts and prevent unauthorized access.

Account Lockout

How It Works

Login Attempt 1: Failed → Counter: 1
Login Attempt 2: Failed → Counter: 2
Login Attempt 3: Failed → Counter: 3
Login Attempt 4: Failed → Counter: 4
Login Attempt 5: Failed → Counter: 5 → LOCKED

Configuration

SettingDefaultDescription
LOCKOUT_THRESHOLD5Failed attempts before lockout
LOCKOUT_DURATION_MINUTES15How long the account stays locked
Lockout window15 minutesWindow for counting failures

Lockout Response

{
"type": "https://api.cortex.purplelab.ai/errors/account-locked",
"title": "Account Locked",
"status": 403,
"detail": "Account is temporarily locked due to too many failed login attempts. Try again in 15 minutes."
}

Lockout Reset

The lockout counter resets when:

  • The user successfully logs in
  • The lockout duration expires
  • An administrator manually unlocks the account

Rate Limiting

Global Rate Limits

Endpoint PatternLimitWindow
/auth/*20 requests1 minute
/* (all others)100 requests1 minute

Rate Limit Response

{
"type": "https://api.cortex.purplelab.ai/errors/rate-limit",
"title": "Too Many Requests",
"status": 429,
"detail": "Rate limit exceeded. Try again in 45 seconds."
}

Rate Limit Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705312500
Retry-After: 45

Password Security

Hashing Algorithm

Passwords are hashed using Argon2id with these parameters:

  • Memory: 64 MB
  • Iterations: 3
  • Parallelism: 4

Argon2id is the winner of the Password Hashing Competition and is resistant to:

  • Brute-force attacks
  • GPU-based attacks
  • Side-channel attacks

Password Storage

Never stored: plaintext password
Stored: $argon2id$v=19$m=65536,t=3,p=4$salt$hash

Password Comparison

Password verification uses constant-time comparison to prevent timing attacks.

User Enumeration Prevention

CORTEX prevents attackers from discovering valid email addresses:

Login

Invalid email    → "The email or password provided is incorrect"
Invalid password → "The email or password provided is incorrect"

Both cases return the same error message.

Registration

When an email already exists:

  • Returns 409 Conflict only if the request comes from an authenticated admin
  • For public registration, uses timing-safe responses

Token Security

Access Tokens

PropertyImplementation
AlgorithmHS256
Expiry15 minutes
StorageClient memory
RevocationNot supported (by design)

Refresh Tokens

PropertyImplementation
AlgorithmHS256
Expiry7 days
StorageServer-side session
RevocationImmediate
RotationOn every use

Token Rotation

Original tokens:
Access: AT1 (expires T+15m)
Refresh: RT1 (expires T+7d)

After refresh at T+10m:
Access: AT2 (expires T+25m) ← New
Refresh: RT2 (expires T+7d+10m) ← New
RT1: INVALIDATED

Transport Security

HTTPS Requirement

In production:

  • All traffic must use HTTPS
  • HTTP requests are redirected to HTTPS
  • HSTS header is set

Security Headers

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Content-Security-Policy: default-src 'self'

CORS Policy

Configuration

// main.ts
app.enableCors({
origin: process.env.CORS_ORIGINS?.split(','),
credentials: true,
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
allowedHeaders: ['Content-Type', 'Authorization'],
});

Allowed Origins

Only origins listed in CORS_ORIGINS can make cross-origin requests.

Security Checklist

For Developers

  • Use HTTPS in production
  • Store tokens securely (not in localStorage)
  • Implement token refresh before expiration
  • Clear tokens on logout
  • Validate all user input
  • Use parameterized queries

For Administrators

  • Configure appropriate rate limits
  • Set strong JWT secrets (min 32 chars)
  • Review audit logs regularly
  • Keep dependencies updated
  • Monitor for suspicious activity
  • Enable alerts for failed logins

Reporting Security Issues

If you discover a security vulnerability:

  1. Do not open a public issue
  2. Email security@purplelab.ai with details
  3. Include steps to reproduce
  4. Allow time for a fix before disclosure

We take security seriously and appreciate responsible disclosure.