145 lines
3.8 KiB
Markdown
145 lines
3.8 KiB
Markdown
# Authentication & Authorization Guide
|
|
|
|
## Before Starting
|
|
1. Check assigned issue: `~/.mosaic/rails/git/issue-list.sh -a @me`
|
|
2. Review existing auth implementation in codebase
|
|
3. Review Vault secrets structure: `docs/vault-secrets-structure.md`
|
|
|
|
## Authentication Patterns
|
|
|
|
### JWT (JSON Web Tokens)
|
|
```
|
|
Vault Path: secret-{env}/backend-api/jwt/signing-key
|
|
Fields: key, algorithm, expiry_seconds
|
|
```
|
|
|
|
**Best Practices:**
|
|
- Use RS256 or ES256 (asymmetric) for distributed systems
|
|
- Use HS256 (symmetric) only for single-service auth
|
|
- Set reasonable expiry (15min-1hr for access tokens)
|
|
- Include minimal claims (sub, exp, iat, roles)
|
|
- Never store sensitive data in JWT payload
|
|
|
|
### Session-Based
|
|
```
|
|
Vault Path: secret-{env}/{service}/session/secret
|
|
Fields: secret, cookie_name, max_age
|
|
```
|
|
|
|
**Best Practices:**
|
|
- Use secure, httpOnly, sameSite cookies
|
|
- Regenerate session ID on privilege change
|
|
- Implement session timeout
|
|
- Store sessions server-side (Redis/database)
|
|
|
|
### OAuth2/OIDC
|
|
```
|
|
Vault Paths:
|
|
- secret-{env}/{service}/oauth/{provider}/client_id
|
|
- secret-{env}/{service}/oauth/{provider}/client_secret
|
|
```
|
|
|
|
**Best Practices:**
|
|
- Use PKCE for public clients
|
|
- Validate state parameter
|
|
- Verify token signatures
|
|
- Check issuer and audience claims
|
|
|
|
## Authorization Patterns
|
|
|
|
### Role-Based Access Control (RBAC)
|
|
```python
|
|
# Example middleware
|
|
def require_role(roles: list):
|
|
def decorator(handler):
|
|
def wrapper(request):
|
|
user_roles = get_user_roles(request.user_id)
|
|
if not any(role in user_roles for role in roles):
|
|
raise ForbiddenError()
|
|
return handler(request)
|
|
return wrapper
|
|
return decorator
|
|
|
|
@require_role(['admin', 'moderator'])
|
|
def delete_user(request):
|
|
pass
|
|
```
|
|
|
|
### Permission-Based
|
|
```python
|
|
# Check specific permissions
|
|
def check_permission(user_id, resource, action):
|
|
permissions = get_user_permissions(user_id)
|
|
return f"{resource}:{action}" in permissions
|
|
```
|
|
|
|
## Security Requirements
|
|
|
|
### Password Handling
|
|
- Use bcrypt, scrypt, or Argon2 for hashing
|
|
- Minimum 12 character passwords
|
|
- Check against breached password lists
|
|
- Implement account lockout after failed attempts
|
|
|
|
### Token Security
|
|
- Rotate secrets regularly
|
|
- Implement token revocation
|
|
- Use short-lived access tokens with refresh tokens
|
|
- Store refresh tokens securely (httpOnly cookies or encrypted storage)
|
|
|
|
### Multi-Factor Authentication
|
|
- Support TOTP (Google Authenticator compatible)
|
|
- Consider WebAuthn for passwordless
|
|
- Require MFA for sensitive operations
|
|
|
|
## Testing Authentication
|
|
|
|
### Test Cases Required
|
|
```python
|
|
class TestAuthentication:
|
|
def test_login_success_returns_token(self):
|
|
pass
|
|
def test_login_failure_returns_401(self):
|
|
pass
|
|
def test_invalid_token_returns_401(self):
|
|
pass
|
|
def test_expired_token_returns_401(self):
|
|
pass
|
|
def test_missing_token_returns_401(self):
|
|
pass
|
|
def test_insufficient_permissions_returns_403(self):
|
|
pass
|
|
def test_token_refresh_works(self):
|
|
pass
|
|
def test_logout_invalidates_token(self):
|
|
pass
|
|
```
|
|
|
|
## Common Vulnerabilities to Avoid
|
|
|
|
1. **Broken Authentication**
|
|
- Weak password requirements
|
|
- Missing brute-force protection
|
|
- Session fixation
|
|
|
|
2. **Broken Access Control**
|
|
- Missing authorization checks
|
|
- IDOR (Insecure Direct Object Reference)
|
|
- Privilege escalation
|
|
|
|
3. **Security Misconfiguration**
|
|
- Default credentials
|
|
- Verbose error messages
|
|
- Missing security headers
|
|
|
|
## Commit Format
|
|
```
|
|
feat(#89): Implement JWT authentication
|
|
|
|
- Add /auth/login and /auth/refresh endpoints
|
|
- Implement token validation middleware
|
|
- Configure 15min access token expiry
|
|
|
|
Fixes #89
|
|
```
|