Security Model
Optare is built with security-first principles. This document explains our security architecture.
Defense in Depth
┌─────────────────────────────────────────────────────────────┐
│ Network Layer │
│ • TLS 1.3 encryption • DDoS protection • WAF │
├─────────────────────────────────────────────────────────────┤
│ Application Layer │
│ • Input validation • CSRF protection • Rate limiting │
├─────────────────────────────────────────────────────────────┤
│ Authentication Layer │
│ • PKCE • MFA • Secure password hashing • Token rotation │
├─────────────────────────────────────────────────────────────┤
│ Authorization Layer │
│ • RBAC • Org isolation • Scope-based access │
├─────────────────────────────────────────────────────────────┤
│ Data Layer │
│ • Encryption at rest • Audit logs • Backup encryption │
└─────────────────────────────────────────────────────────────┘Authentication Security
Password Security
| Measure | Implementation |
|---|---|
| Hashing | Argon2id with unique salts |
| Minimum Length | 12 characters (configurable) |
| Breach Detection | Check against HaveIBeenPwned |
| Rate Limiting | 5 failed attempts = 15 min lockout |
Token Security
| Token | Security Measures |
|---|---|
| Access Token | Short-lived (1hr), signed with RS256 |
| Refresh Token | Rotated on use, revocable |
| ID Token | Signed, audience-restricted |
PKCE (Proof Key for Code Exchange)
All Authorization Code flows use PKCE to prevent code interception:
1. Client generates random code_verifier
2. Client creates code_challenge = SHA256(code_verifier)
3. Authorization request includes code_challenge
4. Token request includes code_verifier
5. Server verifies SHA256(code_verifier) == code_challengeAuthorization Security
Role-Based Access Control (RBAC)
Permission = Organization + Role + Action
Can user delete members?
├── User belongs to Org A? ✓
├── User role is Admin? ✓
├── Admin can delete members? ✓
└── Result: ALLOWEDTenant Isolation
Every data access is scoped by organization:
// All queries include organizationId
const data = await db.query({
where: {
organizationId: req.user.organizationId, // REQUIRED
...otherFilters
}
});API Security
| Measure | Description |
|---|---|
| Token Validation | Verify signature, issuer, audience, expiration |
| Scope Checking | Ensure token has required scopes |
| Rate Limiting | Per-user and per-org limits |
| Input Validation | Zod schemas for all inputs |
Data Security
Encryption
| Type | Implementation |
|---|---|
| In Transit | TLS 1.3 (minimum TLS 1.2) |
| At Rest | AES-256 for sensitive fields |
| Backups | Encrypted with separate keys |
Sensitive Data Handling
// Passwords never logged or returned
const user = await getUser(id);
delete user.passwordHash; // Never expose
// Tokens masked in logs
logger.info('Token issued', {
token: `${token.slice(0, 8)}...`
});Audit Logging
All security-relevant events are logged:
| Event | Logged Data |
|---|---|
| Login Success | User, IP, timestamp, method |
| Login Failure | Email attempt, IP, timestamp |
| Permission Denied | User, resource, action |
| Token Revoked | Token ID, reason, admin |
| Settings Changed | Before/after, admin, timestamp |
Infrastructure Security
Hosting
| Aspect | Implementation |
|---|---|
| Provider | Cloudflare / Vercel / Fly.io |
| Regions | User-selectable |
| Isolation | Container-based isolation |
| Secrets | Environment variables, encrypted |
Network
- DDoS Protection - Cloudflare at edge
- WAF - OWASP rule sets
- IP Allowlisting - Enterprise feature
Secrets Management
Environment Variables (encrypted)
├── DATABASE_URL
├── JWT_SECRET
├── ENCRYPTION_KEY
└── THIRD_PARTY_SECRETSCompliance
Standards
| Standard | Status |
|---|---|
| GDPR | Compliant |
| SOC 2 | In progress |
| HIPAA | Available on request |
| ISO 27001 | Planned |
Data Residency
Choose where your data is stored:
- US - us-east-1
- EU - eu-west-1
- APAC - ap-southeast-1
Data Retention
| Data Type | Retention |
|---|---|
| Active user data | Until deletion |
| Audit logs | 90 days (1 year enterprise) |
| Deleted accounts | 30 days (recovery period) |
| Backups | 30 days |
Security Checklist for Your App
- Validate tokens on every API request
- Check
iss,aud, andexpclaims - Scope all database queries by
organizationId - Use RBAC for sensitive operations
- Enable MFA for admin users
- Log security events
- Set up monitoring/alerting
Next Steps
- RBAC - Role-based access control
- Security Best Practices - Security guidelines and logging
- Best Practices - Implementation guide