Security Model
CORTEX implements defense-in-depth security with multiple layers of protection.
Security Layers
┌─────────────────────────────────────────────────┐
│ Network Layer │
│ • HTTPS/TLS 1.3 • DDoS protection │
│ • Firewall rules • IP allowlisting │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Application Layer │
│ • Helmet headers • CORS policy │
│ • Rate limiting • Input validation │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Authentication Layer │
│ • JWT validation • Token rotation │
│ • Session mgmt • Account lockout │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Authorization Layer │
│ • RBAC • Permission checks │
│ • Scope validation • Resource ownership │
└─────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────┐
│ Data Layer │
│ • Tenant isolation • Row Level Security │
│ • Encryption • Audit logging │
└─────────────────────────────────────────────────┘
Authentication Security
Password Storage
- Algorithm: Argon2id (memory-hard, resistant to GPU attacks)
- Salt: Automatically generated per password
- Parameters: Memory: 64MB, Iterations: 3, Parallelism: 4
Token Security
| Token Type | Lifetime | Storage | Rotation |
|---|---|---|---|
| Access Token | 15 min | Client | On refresh |
| Refresh Token | 7 days | Server + Client | On use |
Session Management
- Sessions stored server-side
- Concurrent session limits
- Automatic session cleanup
- Remote session termination
Authorization Security
RBAC Model
User → RoleAssignment → Role → Permission
│
└── Organization (optional scope)
Permission Checks
// Guard implementation
@Injectable()
export class RbacGuard implements CanActivate {
async canActivate(context: ExecutionContext): Promise<boolean> {
const user = context.switchToHttp().getRequest().user;
const permission = this.reflector.get('permission', context.getHandler());
return this.rbacService.hasPermission(user.id, permission);
}
}
Tenant Isolation
Application Level
Every query includes tenant filter:
async findUsers(tenantId: string) {
return this.prisma.user.findMany({
where: { tenantId },
});
}
Database Level (RLS)
ALTER TABLE "User" ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON "User"
USING (tenant_id = current_setting('app.tenant_id')::uuid);
Input Validation
DTO Validation
export class CreateUserDto {
@IsEmail()
email: string;
@IsString()
@MinLength(8)
@Matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*])/)
password: string;
@IsString()
@MaxLength(100)
firstName: string;
}
Sanitization
- HTML entities escaped
- SQL injection prevented via Prisma
- NoSQL injection not applicable
Security Headers
// Helmet configuration
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
},
},
hsts: {
maxAge: 31536000,
includeSubDomains: true,
},
}));
Headers Set
| Header | Value |
|---|---|
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' |
Rate Limiting
| Endpoint | Limit | Window |
|---|---|---|
/auth/login | 5 | 15 min |
/auth/* | 20 | 1 min |
/* | 100 | 1 min |
Audit Trail
All security-relevant events are logged:
- Authentication attempts
- Authorization failures
- Data modifications
- Admin actions
Secrets Management
| Secret | Storage | Rotation |
|---|---|---|
| JWT Secret | Environment | On deploy |
| Database Password | Azure Key Vault | 90 days |
| API Keys | Environment | Manual |
Compliance
CORTEX security controls support:
- SOC 2 Type II
- GDPR
- HIPAA (with BAA)
- ISO 27001