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
| Setting | Default | Description |
|---|---|---|
LOCKOUT_THRESHOLD | 5 | Failed attempts before lockout |
LOCKOUT_DURATION_MINUTES | 15 | How long the account stays locked |
| Lockout window | 15 minutes | Window 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 Pattern | Limit | Window |
|---|---|---|
/auth/* | 20 requests | 1 minute |
/* (all others) | 100 requests | 1 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
| Property | Implementation |
|---|---|
| Algorithm | HS256 |
| Expiry | 15 minutes |
| Storage | Client memory |
| Revocation | Not supported (by design) |
Refresh Tokens
| Property | Implementation |
|---|---|
| Algorithm | HS256 |
| Expiry | 7 days |
| Storage | Server-side session |
| Revocation | Immediate |
| Rotation | On 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:
- Do not open a public issue
- Email security@purplelab.ai with details
- Include steps to reproduce
- Allow time for a fix before disclosure
We take security seriously and appreciate responsible disclosure.