# ORIGIN_SECURITY_FRAMEWORK.md

## 📋 RÉSUMÉ EXÉCUTIF

Ce document définit le framework de sécurité complet et définitif de la plateforme Veza. Il couvre tous les aspects de la sécurité applicative, infrastructure, et conformité réglementaire (GDPR, CCPA, SOC2). Le framework suit les meilleures pratiques OWASP, NIST, et CIS Benchmarks pour garantir la protection des données utilisateurs, la résilience aux attaques, et la conformité légale pendant 24 mois.

## 🎯 OBJECTIFS

### Objectif Principal
Construire une plateforme sécurisée par conception (Security by Design) qui protège les données utilisateurs, résiste aux menaces courantes (OWASP Top 10), et maintient la conformité GDPR/CCPA/SOC2 en permanence.

### Objectifs Secondaires
- Prévenir les vulnérabilités critiques (injection, XSS, CSRF)
- Chiffrer toutes les données sensibles (at rest, in transit)
- Implémenter une authentification robuste (MFA, JWT, OAuth)
- Auditer toutes les actions critiques (audit logs immuables)
- Détecter et répondre aux incidents rapidement (SIEM, alerting)

## 📖 TABLE DES MATIÈRES

1. [Security Philosophy](#1-security-philosophy)
2. [Threat Model](#2-threat-model)
3. [Authentication Systems](#3-authentication-systems)
4. [Authorization & RBAC](#4-authorization--rbac)
5. [Data Protection](#5-data-protection)
6. [Network Security](#6-network-security)
7. [Application Security](#7-application-security)
8. [Infrastructure Security](#8-infrastructure-security)
9. [Compliance (GDPR, CCPA, SOC2)](#9-compliance-gdpr-ccpa-soc2)
10. [Incident Response](#10-incident-response)
11. [Security Testing](#11-security-testing)

## 🔒 RÈGLES IMMUABLES

1. **Toutes les passwords DOIVENT être hashées** avec Argon2id ou bcrypt (cost ≥ 12)
2. **Toutes les communications DOIVENT être chiffrées** (TLS 1.3 minimum)
3. **Toutes les données sensibles au repos DOIVENT être chiffrées** (AES-256)
4. **JWT tokens DOIVENT expirer** (access: 15 min, refresh: 7 jours)
5. **MFA OBLIGATOIRE** pour admin et moderator
6. **Rate limiting OBLIGATOIRE** sur tous les endpoints publics
7. **Input validation OBLIGATOIRE** côté serveur (never trust client)
8. **Audit logs OBLIGATOIRES** pour actions sensibles (immuables)
9. **Security headers OBLIGATOIRES** (CSP, HSTS, X-Frame-Options, etc.)
10. **Secrets JAMAIS dans le code** (environment variables ou Vault)

## 1. SECURITY PHILOSOPHY

### 1.1 Principes Fondamentaux

**Defense in Depth** (multiple layers):
```
Layer 1: Network (Firewall, WAF, DDoS protection)
Layer 2: Application (Input validation, output encoding)
Layer 3: Authentication (JWT, MFA, session management)
Layer 4: Authorization (RBAC, resource-level permissions)
Layer 5: Data (Encryption at rest, in transit)
Layer 6: Monitoring (SIEM, anomaly detection, alerting)
```

**Least Privilege Principle**:
- Users get minimum permissions needed
- Service accounts have scoped permissions
- Database users have role-specific privileges

**Fail Securely**:
- Default deny (whitelist, not blacklist)
- Errors don't leak sensitive info
- Graceful degradation

**Zero Trust Architecture**:
- Never trust, always verify
- Verify every request (even internal)
- Assume breach mentality

### 1.2 Security by Design

**Secure Defaults**:
```go
// Good: Secure by default
user := User{
    Role: "user",           // Not admin
    IsActive: false,        // Requires activation
    EmailVerified: false,   // Requires verification
    MFAEnabled: false,      // User opts in
}

// Bad: Insecure defaults
user := User{
    Role: "admin",          // DANGER
    IsActive: true,
    EmailVerified: true,
}
```

**Minimise Attack Surface**:
- Disable unused features
- Remove debug endpoints in production
- Restrict CORS origins
- Limit exposed ports

## 2. THREAT MODEL

### 2.1 OWASP Top 10 (2021)

| # | Threat | Mitigation | Status |
|---|--------|------------|--------|
| **A01** | Broken Access Control | RBAC, resource ownership checks | ✅ Implemented |
| **A02** | Cryptographic Failures | TLS 1.3, AES-256, proper key management | ✅ Implemented |
| **A03** | Injection | Parameterized queries, input validation | ✅ Implemented |
| **A04** | Insecure Design | Security requirements, threat modeling | ✅ Implemented |
| **A05** | Security Misconfiguration | Hardened configs, automated scanning | ✅ Implemented |
| **A06** | Vulnerable Components | Dependency scanning, automated updates | ✅ Implemented |
| **A07** | Authentication Failures | JWT + MFA, rate limiting, session management | ✅ Implemented |
| **A08** | Software & Data Integrity | Signed packages, CI/CD security | ✅ Implemented |
| **A09** | Security Logging Failures | Comprehensive audit logs, SIEM | ✅ Implemented |
| **A10** | Server-Side Request Forgery | URL validation, allowlist | ✅ Implemented |

### 2.2 Threat Actors

| Actor | Motivation | Capability | Targets |
|-------|------------|------------|---------|
| **Script Kiddies** | Fun, recognition | Low | Public endpoints, known vulnerabilities |
| **Competitors** | Business advantage | Medium | API, data scraping |
| **Cybercriminals** | Financial gain | High | User data, payment info, accounts |
| **Nation States** | Espionage, disruption | Very High | Infrastructure, sensitive data |
| **Malicious Insiders** | Revenge, financial | High | Database, internal systems |

### 2.3 Attack Scenarios

**Scenario 1: Credential Stuffing Attack**
- **Attack**: Automated login attempts with leaked credentials
- **Mitigation**: Rate limiting (10 attempts/min), CAPTCHA after 3 failures, account lockout, MFA
- **Detection**: Anomalous login patterns, multiple failed attempts

**Scenario 2: SQL Injection**
- **Attack**: Malicious SQL in user input
- **Mitigation**: Parameterized queries (GORM, SQLx), input validation, WAF rules
- **Detection**: SQLMap signatures, unusual query patterns

**Scenario 3: XSS Attack**
- **Attack**: Inject malicious JavaScript
- **Mitigation**: Output encoding, CSP headers, sanitize HTML
- **Detection**: WAF rules, CSP violation reports

**Scenario 4: Data Breach**
- **Attack**: Unauthorized access to database
- **Mitigation**: Encryption at rest, minimal privileges, audit logs, network segmentation
- **Detection**: Unusual query volumes, access from unknown IPs

**Scenario 5: DDoS Attack**
- **Attack**: Overwhelm servers with traffic
- **Mitigation**: Cloudflare DDoS protection, rate limiting, auto-scaling
- **Detection**: Traffic spikes, latency increases

## 3. AUTHENTICATION SYSTEMS

### 3.1 Password Authentication

**Password Requirements**:
```
- Minimum length: 12 characters
- Maximum length: 128 characters
- Must contain:
  - At least 1 uppercase letter
  - At least 1 lowercase letter
  - At least 1 digit
  - At least 1 special character
- Cannot contain:
  - Email or username
  - Common passwords (check against Have I Been Pwned)
  - Sequential characters (abc, 123)
```

**Password Hashing** (Go backend):
```go
import "golang.org/x/crypto/bcrypt"

// Hash password with bcrypt (cost 12)
func HashPassword(password string) (string, error) {
    hash, err := bcrypt.GenerateFromPassword([]byte(password), 12)
    if err != nil {
        return "", err
    }
    return string(hash), nil
}

// Verify password
func VerifyPassword(hash, password string) bool {
    err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
    return err == nil
}
```

**Password Hashing** (Rust services):
```rust
use argon2::{Argon2, PasswordHasher, PasswordVerifier};
use argon2::password_hash::{SaltString, rand_core::OsRng};

// Hash password with Argon2id
pub fn hash_password(password: &str) -> Result<String> {
    let salt = SaltString::generate(&mut OsRng);
    let argon2 = Argon2::default();
    let hash = argon2.hash_password(password.as_bytes(), &salt)
        .map_err(|e| anyhow!("Hash error: {}", e))?;
    Ok(hash.to_string())
}

// Verify password
pub fn verify_password(hash: &str, password: &str) -> bool {
    let parsed_hash = PasswordHash::new(hash).ok()?;
    Argon2::default()
        .verify_password(password.as_bytes(), &parsed_hash)
        .is_ok()
}
```

**Password History**:
```sql
-- Prevent password reuse (last 5 passwords)
SELECT COUNT(*) FROM password_history
WHERE user_id = $1
AND password_hash = $2
AND created_at > NOW() - INTERVAL '90 days'
```

### 3.2 JWT Tokens

**Token Structure**:
```json
{
  "header": {
    "alg": "HS256",
    "typ": "JWT"
  },
  "payload": {
    "sub": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "role": "user",
    "token_version": 0,
    "iat": 1730556000,
    "exp": 1730556900
  },
  "signature": "..."
}
```

**Token Lifecycle**:
- **Access Token**: 15 minutes (short-lived)
- **Refresh Token**: 7 days (long-lived, stored in DB)

**Token Generation** (Go):
```go
import "github.com/golang-jwt/jwt/v5"

type Claims struct {
    UserID       uuid.UUID `json:"sub"`
    Email        string    `json:"email"`
    Role         string    `json:"role"`
    TokenVersion int       `json:"token_version"`
    jwt.RegisteredClaims
}

func GenerateAccessToken(user *models.User) (string, error) {
    claims := Claims{
        UserID:       user.ID,
        Email:        user.Email,
        Role:         user.Role,
        TokenVersion: user.TokenVersion,
        RegisteredClaims: jwt.RegisteredClaims{
            ExpiresAt: jwt.NewNumericDate(time.Now().Add(15 * time.Minute)),
            IssuedAt:  jwt.NewNumericDate(time.Now()),
        },
    }
    
    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    return token.SignedString([]byte(os.Getenv("JWT_SECRET")))
}
```

**Token Invalidation**:
```go
// Invalidate all tokens for user (logout all devices)
func InvalidateAllTokens(userID uuid.UUID) error {
    return db.Model(&models.User{}).
        Where("id = ?", userID).
        Update("token_version", gorm.Expr("token_version + 1")).
        Error
}
```

**Token Verification Middleware**:
```go
func AuthMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        authHeader := c.GetHeader("Authorization")
        if !strings.HasPrefix(authHeader, "Bearer ") {
            c.JSON(401, ErrorResponse{Code: 1002, Message: "Invalid token"})
            c.Abort()
            return
        }
        
        tokenString := strings.TrimPrefix(authHeader, "Bearer ")
        claims, err := VerifyToken(tokenString)
        if err != nil {
            c.JSON(401, ErrorResponse{Code: 1001, Message: "Token expired"})
            c.Abort()
            return
        }
        
        // Check token version (for revocation)
        user := GetUser(claims.UserID)
        if user.TokenVersion != claims.TokenVersion {
            c.JSON(401, ErrorResponse{Code: 1002, Message: "Token revoked"})
            c.Abort()
            return
        }
        
        c.Set("user", user)
        c.Next()
    }
}
```

### 3.3 Multi-Factor Authentication (MFA)

**TOTP (Time-Based One-Time Password)**:
```go
import "github.com/pquerna/otp/totp"

// Generate TOTP secret
func GenerateTOTPSecret(email string) (*otp.Key, error) {
    return totp.Generate(totp.GenerateOpts{
        Issuer:      "Veza",
        AccountName: email,
    })
}

// Verify TOTP code
func VerifyTOTPCode(secret, code string) bool {
    return totp.Validate(code, secret)
}
```

**Backup Codes**:
```go
// Generate 10 backup codes (8 characters each)
func GenerateBackupCodes() []string {
    codes := make([]string, 10)
    for i := range codes {
        codes[i] = generateRandomString(8)
    }
    return codes
}

// Store hashed backup codes
func StoreBackupCodes(userID uuid.UUID, codes []string) error {
    hashed := make([]string, len(codes))
    for i, code := range codes {
        hash, _ := bcrypt.GenerateFromPassword([]byte(code), 12)
        hashed[i] = string(hash)
    }
    
    return db.Model(&models.TwoFactorConfig{}).
        Where("user_id = ?", userID).
        Update("backup_codes", hashed).
        Error
}
```

**MFA Login Flow**:
```
1. User enters email/password
2. Backend verifies credentials
3. IF MFA enabled:
   a. Return "mfa_required" response
   b. User enters TOTP code
   c. Backend verifies TOTP
   d. Return JWT tokens
4. ELSE:
   Return JWT tokens directly
```

### 3.4 OAuth 2.0 (Social Login)

**Supported Providers**:
- Google OAuth 2.0
- GitHub OAuth
- Discord OAuth
- Spotify OAuth

**OAuth Flow** (Authorization Code):
```go
// Step 1: Redirect to provider
func InitiateOAuth(c *gin.Context) {
    provider := c.Param("provider") // google, github, discord, spotify
    
    config := getOAuthConfig(provider)
    state := generateRandomString(32)
    
    // Store state in Redis (expires in 10 min)
    redis.Set("oauth_state:"+state, c.ClientIP(), 10*time.Minute)
    
    url := config.AuthCodeURL(state, oauth2.AccessTypeOffline)
    c.Redirect(302, url)
}

// Step 2: Handle callback
func OAuthCallback(c *gin.Context) {
    code := c.Query("code")
    state := c.Query("state")
    
    // Verify state
    if !redis.Exists("oauth_state:" + state) {
        c.JSON(400, ErrorResponse{Code: 1009, Message: "Invalid state"})
        return
    }
    
    // Exchange code for token
    token, err := config.Exchange(ctx, code)
    if err != nil {
        c.JSON(400, ErrorResponse{Code: 1009, Message: "OAuth error"})
        return
    }
    
    // Get user info from provider
    userInfo := fetchUserInfo(token)
    
    // Find or create user
    user := findOrCreateUserByOAuth(userInfo)
    
    // Generate JWT
    accessToken := GenerateAccessToken(user)
    refreshToken := GenerateRefreshToken(user)
    
    c.JSON(200, LoginResponse{
        AccessToken:  accessToken,
        RefreshToken: refreshToken,
        User:         user,
    })
}
```

### 3.5 Session Management

**Refresh Token Storage**:
```sql
CREATE TABLE refresh_tokens (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    token_hash VARCHAR(255) NOT NULL UNIQUE,  -- SHA-256 hash
    device_name VARCHAR(255),
    user_agent TEXT,
    ip_address INET,
    expires_at TIMESTAMPTZ NOT NULL,
    last_used_at TIMESTAMPTZ,
    is_revoked BOOLEAN NOT NULL DEFAULT false,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```

**Session Security**:
- Store only hashed refresh tokens (SHA-256)
- Track device, IP, user agent
- Invalidate on password change
- Revoke on logout
- Auto-expire after 7 days of inactivity

## 4. AUTHORIZATION & RBAC

### 4.1 Role Hierarchy

```
admin (highest privileges)
  └── moderator (content moderation)
        └── premium (paid features)
              └── creator (content creation)
                    └── user (base role)
```

### 4.2 Permission Matrix

| Resource | Action | user | creator | premium | moderator | admin |
|----------|--------|------|---------|---------|-----------|-------|
| **Track** | View | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Track** | Upload | ❌ | ✅ | ✅ | ✅ | ✅ |
| **Track** | Edit Own | ❌ | ✅ | ✅ | ✅ | ✅ |
| **Track** | Delete Own | ❌ | ✅ | ✅ | ✅ | ✅ |
| **Track** | Delete Any | ❌ | ❌ | ❌ | ✅ | ✅ |
| **User** | View Profile | ✅ | ✅ | ✅ | ✅ | ✅ |
| **User** | Edit Own | ✅ | ✅ | ✅ | ✅ | ✅ |
| **User** | Ban | ❌ | ❌ | ❌ | ✅ | ✅ |
| **User** | Change Role | ❌ | ❌ | ❌ | ❌ | ✅ |
| **Product** | Buy | ✅ | ✅ | ✅ | ✅ | ✅ |
| **Product** | Sell | ❌ | ✅ | ✅ | ✅ | ✅ |
| **Config** | View | ❌ | ❌ | ❌ | ❌ | ✅ |
| **Config** | Edit | ❌ | ❌ | ❌ | ❌ | ✅ |

### 4.3 Resource-Level Authorization

**Check Ownership**:
```go
func RequireOwnership() gin.HandlerFunc {
    return func(c *gin.Context) {
        user := GetCurrentUser(c)
        resourceID := c.Param("id")
        
        resource := GetResource(resourceID)
        if resource.UserID != user.ID && user.Role != "admin" {
            c.JSON(403, ErrorResponse{Code: 1003, Message: "Forbidden"})
            c.Abort()
            return
        }
        
        c.Next()
    }
}

// Usage
r.PATCH("/tracks/:id", AuthMiddleware(), RequireOwnership(), handlers.UpdateTrack)
```

**Permission Policies** (Casbin):
```ini
# policy.csv
p, admin, *, *
p, moderator, track, delete
p, moderator, user, ban
p, creator, track, create
p, creator, track, update_own
p, user, track, view
```

### 4.4 API Key Authentication (for external integrations)

**API Key Structure**:
```
Format: vz_live_1234567890abcdef1234567890abcdef
Prefix: vz_live_ (production) or vz_test_ (sandbox)
```

**API Key Storage**:
```sql
CREATE TABLE api_keys (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    key_prefix VARCHAR(20) NOT NULL,  -- vz_live_1234
    key_hash VARCHAR(255) NOT NULL UNIQUE,  -- SHA-256 of full key
    name VARCHAR(255),
    scopes VARCHAR(50)[],  -- ['read:tracks', 'write:playlists']
    last_used_at TIMESTAMPTZ,
    expires_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```

## 5. DATA PROTECTION

### 5.1 Encryption at Rest

**Database Encryption** (PostgreSQL):
```sql
-- Enable pgcrypto extension
CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- Encrypt sensitive columns
CREATE TABLE users (
    id UUID PRIMARY KEY,
    email VARCHAR(255) NOT NULL,
    ssn BYTEA,  -- Encrypted with pgcrypto
    phone_encrypted BYTEA
);

-- Insert encrypted data
INSERT INTO users (id, email, ssn)
VALUES (
    gen_random_uuid(),
    'user@example.com',
    pgp_sym_encrypt('123-45-6789', 'encryption_key')
);

-- Decrypt data
SELECT 
    id,
    email,
    pgp_sym_decrypt(ssn, 'encryption_key') AS ssn_decrypted
FROM users;
```

**File Encryption** (S3/MinIO):
```go
// Client-side encryption before upload
func EncryptFile(data []byte, key []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    
    gcm, err := cipher.NewGCM(block)
    if err != nil {
        return nil, err
    }
    
    nonce := make([]byte, gcm.NonceSize())
    if _, err := rand.Read(nonce); err != nil {
        return nil, err
    }
    
    ciphertext := gcm.Seal(nonce, nonce, data, nil)
    return ciphertext, nil
}

// Or server-side encryption (S3)
s3Client.PutObject(&s3.PutObjectInput{
    Bucket:               aws.String("veza-files"),
    Key:                  aws.String("file.txt"),
    Body:                 bytes.NewReader(data),
    ServerSideEncryption: aws.String("AES256"),
})
```

**Encryption Key Management**:
```
Production: HashiCorp Vault
Development: Environment variables
Rotation: Every 90 days
Algorithm: AES-256-GCM
Key derivation: PBKDF2 or Argon2
```

### 5.2 Encryption in Transit

**TLS Configuration** (Nginx):
```nginx
server {
    listen 443 ssl http2;
    server_name api.veza.io;
    
    # TLS 1.3 only
    ssl_protocols TLSv1.3;
    
    # Modern cipher suite
    ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256';
    ssl_prefer_server_ciphers off;
    
    # Certificates (Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/api.veza.io/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.veza.io/privkey.pem;
    
    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    
    # HSTS header
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
}
```

**Database TLS** (PostgreSQL):
```go
// Require SSL for database connections
db, err := gorm.Open(postgres.Open(
    "host=db.veza.io user=veza password=xxx dbname=veza_db sslmode=require",
), &gorm.Config{})
```

**Redis TLS**:
```go
redisClient := redis.NewClient(&redis.Options{
    Addr:      "redis.veza.io:6380",
    Password:  os.Getenv("REDIS_PASSWORD"),
    TLSConfig: &tls.Config{
        MinVersion: tls.VersionTLS13,
    },
})
```

### 5.3 Data Masking & Anonymization

**PII Masking** (logs):
```go
func MaskEmail(email string) string {
    parts := strings.Split(email, "@")
    if len(parts) != 2 {
        return "***"
    }
    
    username := parts[0]
    if len(username) > 3 {
        username = username[:3] + "***"
    } else {
        username = "***"
    }
    
    return username + "@" + parts[1]
}

// Log: user@example.com → use***@example.com
logger.Info("User logged in", zap.String("email", MaskEmail(user.Email)))
```

**Data Anonymization** (for analytics):
```sql
-- Anonymize user data for analytics
CREATE MATERIALIZED VIEW analytics_users AS
SELECT
    MD5(id::text)::uuid AS anonymous_id,  -- One-way hash
    DATE_TRUNC('month', created_at) AS signup_month,
    role,
    country  -- Aggregated, not precise location
FROM users;
```

### 5.4 Data Retention & Deletion

**Soft Delete** (default):
```sql
-- Soft delete (set deleted_at timestamp)
UPDATE users SET deleted_at = NOW() WHERE id = $1;

-- Queries exclude soft-deleted
SELECT * FROM users WHERE deleted_at IS NULL;
```

**Hard Delete** (GDPR right to be forgotten):
```go
func DeleteUserData(userID uuid.UUID) error {
    // 1. Delete user data
    db.Unscoped().Where("id = ?", userID).Delete(&models.User{})
    
    // 2. Anonymize related data (preserve analytics)
    db.Model(&models.Track{}).
        Where("creator_id = ?", userID).
        Update("creator_id", uuid.Nil)  // Null user reference
    
    // 3. Delete personal files (S3)
    deleteUserFiles(userID)
    
    // 4. Log deletion (audit)
    auditLog("user_deleted", userID)
    
    return nil
}
```

**Retention Policy**:
```
Account data: Until account deletion
Audit logs: 7 years (legal requirement)
Analytics: 24 months (aggregated, anonymized)
Backups: 30 days
```

## 6. NETWORK SECURITY

### 6.1 Firewall Rules

**VPC Security Groups** (AWS):
```hcl
# Allow HTTPS from anywhere
resource "aws_security_group_rule" "allow_https" {
  type              = "ingress"
  from_port         = 443
  to_port           = 443
  protocol          = "tcp"
  cidr_blocks       = ["0.0.0.0/0"]
  security_group_id = aws_security_group.web.id
}

# Allow PostgreSQL only from backend
resource "aws_security_group_rule" "allow_postgres" {
  type                     = "ingress"
  from_port                = 5432
  to_port                  = 5432
  protocol                 = "tcp"
  source_security_group_id = aws_security_group.backend.id
  security_group_id        = aws_security_group.database.id
}

# Deny all other inbound traffic (implicit)
```

### 6.2 WAF (Web Application Firewall)

**Cloudflare WAF Rules**:
```
Rule 1: Block known bad IPs (threat intelligence)
Rule 2: Rate limit login attempts (10/min per IP)
Rule 3: Block SQL injection patterns (UNION SELECT, etc.)
Rule 4: Block XSS patterns (<script>, onerror=, etc.)
Rule 5: Block common attack tools (Nikto, SQLMap)
Rule 6: Challenge suspicious traffic (high request rate, unusual headers)
Rule 7: Block traffic from high-risk countries (optional)
```

**ModSecurity Rules** (if self-hosted):
```apache
# Enable OWASP Core Rule Set
Include /etc/modsecurity/crs-setup.conf
Include /etc/modsecurity/rules/*.conf

# Custom rules
SecRule REQUEST_URI "@rx (\bunion\b.{1,100}\bselect\b)" \
    "id:1001,phase:2,deny,status:403,msg:'SQL Injection Attempt'"

SecRule ARGS "@rx (<script|onerror=|onload=)" \
    "id:1002,phase:2,deny,status:403,msg:'XSS Attempt'"
```

### 6.3 DDoS Protection

**Cloudflare DDoS Protection** (Layer 3/4/7):
- Automatic mitigation (up to 100 Tbps capacity)
- Rate limiting (configurable thresholds)
- Challenge page for suspicious traffic

**Application-Level Rate Limiting**:
```go
// Redis-based rate limiter
func RateLimitMiddleware(limit int, window time.Duration) gin.HandlerFunc {
    return func(c *gin.Context) {
        key := "ratelimit:" + c.ClientIP() + ":" + c.Request.URL.Path
        
        count, _ := redis.Incr(key)
        if count == 1 {
            redis.Expire(key, window)
        }
        
        if count > int64(limit) {
            c.Header("X-RateLimit-Limit", strconv.Itoa(limit))
            c.Header("X-RateLimit-Remaining", "0")
            c.JSON(429, ErrorResponse{
                Code:    5000,
                Message: "Rate limit exceeded",
            })
            c.Abort()
            return
        }
        
        c.Header("X-RateLimit-Limit", strconv.Itoa(limit))
        c.Header("X-RateLimit-Remaining", strconv.Itoa(limit-int(count)))
        c.Next()
    }
}
```

### 6.4 Network Segmentation

**VPC Architecture**:
```
Public Subnet (DMZ):
  - Load Balancers (ALB)
  - Bastion hosts

Private Subnet (Application):
  - Backend API servers
  - Rust services (chat, stream)
  - Worker nodes

Private Subnet (Data):
  - PostgreSQL (RDS)
  - Redis (ElastiCache)
  - Elasticsearch

Isolated Subnet (Management):
  - Monitoring (Prometheus, Grafana)
  - CI/CD runners
```

## 7. APPLICATION SECURITY

### 7.1 Input Validation

**Validate ALL Inputs**:
```go
type CreateTrackRequest struct {
    Title       string `json:"title" binding:"required,min=1,max=255"`
    Artist      string `json:"artist" binding:"max=255"`
    Genre       string `json:"genre" binding:"oneof=electronic house techno"`
    BPM         int    `json:"bpm" binding:"min=60,max=200"`
    Duration    int    `json:"duration" binding:"required,min=1"`
    Visibility  string `json:"visibility" binding:"required,oneof=public unlisted private"`
}

func CreateTrack(c *gin.Context) {
    var req CreateTrackRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(400, ErrorResponse{
            Code:    2000,
            Message: "Validation failed",
            Details: parseValidationErrors(err),
        })
        return
    }
    
    // Additional business logic validation
    if req.BPM > 0 && (req.BPM < 60 || req.BPM > 200) {
        c.JSON(400, ErrorResponse{Code: 2003, Message: "BPM out of range"})
        return
    }
    
    // Process request...
}
```

**Sanitize HTML** (frontend):
```typescript
import DOMPurify from 'dompurify';

function sanitizeHTML(dirty: string): string {
  return DOMPurify.sanitize(dirty, {
    ALLOWED_TAGS: ['b', 'i', 'em', 'strong', 'a'],
    ALLOWED_ATTR: ['href'],
  });
}

// Usage
const userBio = sanitizeHTML(inputBio);
```

### 7.2 SQL Injection Prevention

**Use Parameterized Queries** (GORM):
```go
// ✅ Safe: Parameterized query
db.Where("email = ?", userInput).First(&user)

// ❌ DANGER: String concatenation
db.Where("email = '" + userInput + "'").First(&user)  // NEVER DO THIS
```

**Use Parameterized Queries** (SQLx Rust):
```rust
// ✅ Safe: Parameterized query
let user = sqlx::query_as!(
    User,
    "SELECT * FROM users WHERE email = $1",
    email
)
.fetch_one(&pool)
.await?;

// ❌ DANGER: Format string
let query = format!("SELECT * FROM users WHERE email = '{}'", email);  // NEVER
```

### 7.3 XSS Prevention

**Output Encoding** (React automatically escapes):
```tsx
// ✅ Safe: React escapes by default
<div>{userInput}</div>

// ⚠️ Danger: dangerouslySetInnerHTML
<div dangerouslySetInnerHTML={{ __html: userInput }} />  // Only if sanitized

// ✅ Safe with sanitization
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
```

**CSP Header**:
```go
c.Header("Content-Security-Policy", 
    "default-src 'self'; " +
    "script-src 'self' 'unsafe-inline' https://cdn.veza.io; " +
    "style-src 'self' 'unsafe-inline'; " +
    "img-src 'self' data: https:; " +
    "font-src 'self' data:; " +
    "connect-src 'self' wss://api.veza.io; " +
    "frame-ancestors 'none';")
```

### 7.4 CSRF Protection

**CSRF Token** (for forms):
```go
// Generate CSRF token
func GenerateCSRFToken() string {
    b := make([]byte, 32)
    rand.Read(b)
    return base64.URLEncoding.EncodeToString(b)
}

// Store in session
session.Set("csrf_token", GenerateCSRFToken())

// Validate on POST
func ValidateCSRFToken(c *gin.Context) {
    sessionToken := session.Get("csrf_token")
    requestToken := c.PostForm("csrf_token")
    
    if sessionToken != requestToken {
        c.JSON(403, ErrorResponse{Code: 1003, Message: "CSRF token invalid"})
        c.Abort()
        return
    }
}
```

**SameSite Cookie** (for API):
```go
c.SetSameSite(http.SameSiteStrictMode)
c.SetCookie(
    "refresh_token",
    token,
    3600*24*7,  // 7 days
    "/",
    "veza.io",
    true,  // Secure (HTTPS only)
    true,  // HttpOnly (no JavaScript access)
)
```

### 7.5 File Upload Security

**Validation**:
```go
func ValidateFileUpload(file *multipart.FileHeader) error {
    // 1. Check file size (max 100 MB)
    if file.Size > 100*1024*1024 {
        return errors.New("file too large")
    }
    
    // 2. Check file extension (whitelist)
    allowedExtensions := []string{".mp3", ".wav", ".flac", ".m4a"}
    ext := filepath.Ext(file.Filename)
    if !contains(allowedExtensions, ext) {
        return errors.New("invalid file type")
    }
    
    // 3. Check MIME type (from content, not just extension)
    f, _ := file.Open()
    defer f.Close()
    
    buffer := make([]byte, 512)
    f.Read(buffer)
    mimeType := http.DetectContentType(buffer)
    
    if !strings.HasPrefix(mimeType, "audio/") {
        return errors.New("invalid file content")
    }
    
    // 4. Virus scan (ClamAV)
    if !virusScan(file) {
        return errors.New("virus detected")
    }
    
    return nil
}
```

**Safe Storage**:
```go
// Generate random filename (prevent path traversal)
func GenerateFilename(originalName string) string {
    ext := filepath.Ext(originalName)
    randomName := uuid.New().String()
    return randomName + ext
}

// Store outside webroot with restricted permissions
func SaveFile(file *multipart.FileHeader) error {
    filename := GenerateFilename(file.Filename)
    path := filepath.Join("/var/uploads", filename)  // Outside webroot
    
    if err := c.SaveUploadedFile(file, path); err != nil {
        return err
    }
    
    // Set permissions (owner read/write only)
    os.Chmod(path, 0600)
    
    return nil
}
```

### 7.6 Security Headers

**All Responses Include**:
```go
func SecurityHeadersMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        // Prevent clickjacking
        c.Header("X-Frame-Options", "DENY")
        
        // Prevent MIME sniffing
        c.Header("X-Content-Type-Options", "nosniff")
        
        // Enable XSS filter
        c.Header("X-XSS-Protection", "1; mode=block")
        
        // HSTS (force HTTPS)
        c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
        
        // Referrer policy
        c.Header("Referrer-Policy", "strict-origin-when-cross-origin")
        
        // Permissions policy
        c.Header("Permissions-Policy", "geolocation=(), microphone=(), camera=()")
        
        // CSP (see above)
        c.Header("Content-Security-Policy", "default-src 'self'; ...")
        
        c.Next()
    }
}
```

## 8. INFRASTRUCTURE SECURITY

### 8.1 Container Security

**Dockerfile Best Practices**:
```dockerfile
# Use specific version (not latest)
FROM golang:1.22-alpine AS builder

# Run as non-root user
RUN adduser -D -u 10001 appuser

# Copy only necessary files
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go build -o main .

# Multi-stage build (smaller image)
FROM alpine:3.19
RUN adduser -D -u 10001 appuser
COPY --from=builder /app/main /app/main

# Run as non-root
USER appuser
EXPOSE 8080
CMD ["/app/main"]
```

**Image Scanning**:
```bash
# Trivy scan
trivy image veza-backend:latest

# Fail CI if critical vulnerabilities
trivy image --severity CRITICAL,HIGH --exit-code 1 veza-backend:latest
```

### 8.2 Secrets Management

**HashiCorp Vault**:
```go
import "github.com/hashicorp/vault/api"

func GetSecret(key string) (string, error) {
    client, _ := api.NewClient(api.DefaultConfig())
    client.SetAddress("https://vault.veza.io")
    client.SetToken(os.Getenv("VAULT_TOKEN"))
    
    secret, err := client.Logical().Read("secret/data/veza/" + key)
    if err != nil {
        return "", err
    }
    
    return secret.Data["value"].(string), nil
}

// Usage
jwtSecret := GetSecret("jwt_secret")
dbPassword := GetSecret("db_password")
```

**Environment Variables** (development):
```bash
# .env (NEVER commit to Git)
JWT_SECRET=your-super-secret-jwt-key-min-32-chars
DATABASE_URL=postgresql://veza:password@localhost:5432/veza_db
REDIS_URL=redis://localhost:6379
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

### 8.3 Logging & Monitoring

**Audit Logs** (all sensitive actions):
```go
func AuditLog(action string, userID uuid.UUID, resourceType string, resourceID uuid.UUID, metadata map[string]interface{}) {
    log := models.AuditLog{
        ID:           uuid.New(),
        UserID:       userID,
        Action:       action,
        ResourceType: resourceType,
        ResourceID:   resourceID,
        Metadata:     metadata,
        IPAddress:    c.ClientIP(),
        UserAgent:    c.Request.UserAgent(),
        CreatedAt:    time.Now(),
    }
    
    db.Create(&log)
}

// Usage
AuditLog("user.login", user.ID, "user", user.ID, map[string]interface{}{
    "mfa_used": true,
})

AuditLog("track.deleted", user.ID, "track", track.ID, map[string]interface{}{
    "track_title": track.Title,
})
```

**Security Monitoring** (Prometheus metrics):
```go
var (
    loginAttempts = prometheus.NewCounterVec(
        prometheus.CounterOpts{
            Name: "veza_login_attempts_total",
            Help: "Total login attempts",
        },
        []string{"status", "method"},
    )
    
    unauthorizedRequests = prometheus.NewCounter(
        prometheus.CounterOpts{
            Name: "veza_unauthorized_requests_total",
            Help: "Total unauthorized requests (401/403)",
        },
    )
)

// Track failed logins
loginAttempts.WithLabelValues("failed", "password").Inc()

// Alert if > 100 failed logins/min from same IP
```

## 9. COMPLIANCE (GDPR, CCPA, SOC2)

### 9.1 GDPR Compliance

**Lawful Basis**: Consent (for marketing), Contract (for service), Legitimate Interest (for security)

**Data Subject Rights**:

**Right to Access** (Article 15):
```go
func ExportUserData(userID uuid.UUID) (map[string]interface{}, error) {
    data := make(map[string]interface{})
    
    // Personal data
    var user models.User
    db.First(&user, userID)
    data["user"] = user
    
    // Tracks
    var tracks []models.Track
    db.Where("creator_id = ?", userID).Find(&tracks)
    data["tracks"] = tracks
    
    // Orders
    var orders []models.Order
    db.Where("user_id = ?", userID).Find(&orders)
    data["orders"] = orders
    
    // Messages (recent 90 days)
    var messages []models.Message
    db.Where("sender_id = ? AND created_at > ?", userID, time.Now().AddDate(0, -3, 0)).Find(&messages)
    data["messages"] = messages
    
    return data, nil
}
```

**Right to Erasure** (Article 17):
```go
func DeleteUserDataGDPR(userID uuid.UUID) error {
    // 1. Hard delete user
    db.Unscoped().Delete(&models.User{}, userID)
    
    // 2. Anonymize tracks (keep for platform, anonymize creator)
    db.Model(&models.Track{}).
        Where("creator_id = ?", userID).
        Update("creator_id", nil)
    
    // 3. Delete messages
    db.Delete(&models.Message{}, "sender_id = ?", userID)
    
    // 4. Delete files (S3)
    deleteUserFiles(userID)
    
    // 5. Blacklist email (prevent re-registration)
    db.Create(&models.DeletedUser{
        Email:     user.Email,
        DeletedAt: time.Now(),
    })
    
    return nil
}
```

**Right to Data Portability** (Article 20):
```go
// Export as JSON
func ExportUserDataJSON(userID uuid.UUID) ([]byte, error) {
    data, err := ExportUserData(userID)
    if err != nil {
        return nil, err
    }
    
    return json.MarshalIndent(data, "", "  ")
}
```

**Consent Management**:
```sql
CREATE TABLE user_consents (
    id UUID PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    consent_type VARCHAR(50) NOT NULL,  -- marketing, analytics, cookies
    granted BOOLEAN NOT NULL,
    ip_address INET,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
```

### 9.2 CCPA Compliance

**Do Not Sell My Personal Information**:
```go
func OptOutOfDataSale(userID uuid.UUID) error {
    return db.Model(&models.UserSettings{}).
        Where("user_id = ?", userID).
        Update("ccpa_opt_out", true).
        Error
}
```

**Disclosure**: Privacy policy lists all data collected and shared

### 9.3 SOC 2 Type II

**Security Controls**:
- [ ] Access control (RBAC)
- [ ] Encryption (TLS, AES-256)
- [ ] Logging & monitoring
- [ ] Incident response plan
- [ ] Disaster recovery plan
- [ ] Vendor risk management
- [ ] Security awareness training

**Audit Trail**: All access to production systems logged

## 10. INCIDENT RESPONSE

### 10.1 Incident Response Plan

**Phase 1: Detection** (< 15 minutes)
- SIEM alerts (unusual patterns)
- User reports (security@veza.io)
- Bug bounty reports

**Phase 2: Containment** (< 1 hour)
- Isolate affected systems
- Block malicious IPs
- Disable compromised accounts
- Preserve evidence

**Phase 3: Eradication** (< 4 hours)
- Identify root cause
- Remove malware/backdoors
- Patch vulnerabilities
- Reset credentials

**Phase 4: Recovery** (< 8 hours)
- Restore from clean backups
- Re-enable services
- Monitor for re-infection

**Phase 5: Post-Incident** (< 1 week)
- Post-mortem report
- Update security controls
- User notification (if required)
- Regulatory notification (GDPR 72h)

### 10.2 Security Incident Categories

| Severity | Examples | Response Time | Escalation |
|----------|----------|---------------|------------|
| **Critical** | Data breach, RCE, complete outage | < 15 min | CTO, CEO |
| **High** | SQL injection, XSS, privilege escalation | < 1 hour | Security Lead |
| **Medium** | DDoS, brute-force, CSRF | < 4 hours | DevOps Team |
| **Low** | Informational leaks, outdated software | < 24 hours | Developer |

### 10.3 Communication Plan

**Internal**:
- Slack #security-incidents channel
- On-call rotation (PagerDuty)

**External**:
- Status page (status.veza.io)
- Email notifications (affected users)
- Press release (if public breach)

## 11. SECURITY TESTING

### 11.1 Static Application Security Testing (SAST)

**Go** (Gosec):
```bash
# Install
go install github.com/securego/gosec/v2/cmd/gosec@latest

# Run
gosec ./...

# CI/CD integration
gosec -fmt=json -out=report.json ./...
```

**Rust** (Cargo Audit):
```bash
# Install
cargo install cargo-audit

# Run
cargo audit

# CI/CD integration
cargo audit --deny warnings
```

**TypeScript** (ESLint security plugin):
```bash
npm install --save-dev eslint-plugin-security

# .eslintrc.js
plugins: ['security'],
extends: ['plugin:security/recommended'],
```

### 11.2 Dynamic Application Security Testing (DAST)

**OWASP ZAP**:
```bash
# Docker scan
docker run -t owasp/zap2docker-stable zap-baseline.py \
    -t https://staging.veza.io \
    -r zap_report.html
```

**Burp Suite** (manual testing):
- Proxy all requests
- Identify injection points
- Test authentication flows
- Test session management

### 11.3 Dependency Scanning

**Go** (Dependabot + govulncheck):
```bash
# Install
go install golang.org/x/vuln/cmd/govulncheck@latest

# Run
govulncheck ./...
```

**Rust** (Cargo Audit):
```bash
cargo audit --deny warnings
```

**JavaScript** (npm audit):
```bash
npm audit --audit-level=high
```

### 11.4 Penetration Testing

**Schedule**: Quarterly + after major releases

**Scope**:
- Web application (frontend + backend)
- API endpoints
- WebSocket connections
- File upload functionality
- Payment integration
- Authentication flows

**Methodology**: OWASP Testing Guide

**Deliverables**:
- Executive summary
- Vulnerability list (CVSS scores)
- Proof of concept exploits
- Remediation recommendations

### 11.5 Bug Bounty Program

**Platform**: HackerOne or Bugcrowd

**Scope**:
- *.veza.io domains
- API (api.veza.io)
- Mobile apps (iOS, Android)

**Out of Scope**:
- Social engineering
- Physical attacks
- DDoS
- Third-party services

**Rewards**:
| Severity | Reward |
|----------|--------|
| Critical | $1,000 - $5,000 |
| High | $500 - $1,000 |
| Medium | $250 - $500 |
| Low | $50 - $250 |

## ✅ CHECKLIST DE VALIDATION

### Authentication
- [ ] Password hashing (bcrypt/Argon2, cost ≥ 12)
- [ ] JWT tokens (HS256, expiration: 15 min)
- [ ] Refresh tokens (secure storage, revocation)
- [ ] MFA (TOTP + backup codes)
- [ ] OAuth 2.0 (Google, GitHub, Discord, Spotify)
- [ ] Session management (device tracking, revocation)

### Authorization
- [ ] RBAC (roles: user, creator, premium, moderator, admin)
- [ ] Resource-level permissions
- [ ] API key authentication (for integrations)

### Data Protection
- [ ] Encryption at rest (AES-256)
- [ ] Encryption in transit (TLS 1.3)
- [ ] Key management (Vault)
- [ ] Data masking (logs)
- [ ] Data retention policies
- [ ] GDPR right to be forgotten

### Application Security
- [ ] Input validation (all endpoints)
- [ ] Parameterized queries (SQL injection prevention)
- [ ] Output encoding (XSS prevention)
- [ ] CSRF protection
- [ ] File upload validation
- [ ] Security headers (CSP, HSTS, X-Frame-Options)

### Infrastructure
- [ ] Firewall rules (VPC security groups)
- [ ] WAF (Cloudflare or ModSecurity)
- [ ] DDoS protection
- [ ] Network segmentation
- [ ] Container security (non-root, image scanning)
- [ ] Secrets management (Vault or env vars)

### Compliance
- [ ] GDPR (consent, data export, right to erasure)
- [ ] CCPA (opt-out of data sale)
- [ ] SOC 2 (controls, audit trail)

### Incident Response
- [ ] Incident response plan
- [ ] On-call rotation
- [ ] Communication plan

### Security Testing
- [ ] SAST (Gosec, cargo audit, ESLint)
- [ ] DAST (OWASP ZAP, Burp Suite)
- [ ] Dependency scanning (Dependabot)
- [ ] Penetration testing (quarterly)
- [ ] Bug bounty program

## 📊 MÉTRIQUES DE SUCCÈS

### Security KPIs
- **Vulnerability Response Time**: < 24 hours (critical), < 7 days (high)
- **Incident Detection Time**: < 15 minutes
- **Incident Response Time**: < 1 hour (containment)
- **Password Strength**: 100% compliant (min 12 chars, complexity)
- **MFA Adoption**: > 90% (admin/moderator), > 50% (all users)
- **Failed Login Rate**: < 1%
- **Unauthorized Access Attempts**: 0 successful
- **Security Scan Coverage**: 100% codebase
- **Critical Vulnerabilities**: 0 in production

## 🔄 HISTORIQUE DES VERSIONS

| Version | Date | Changements |
|---------|------|-------------|
| 1.0.0 | 2025-11-02 | Version initiale - Framework sécurité complet |

---

## ⚠️ AVERTISSEMENT

**CE FRAMEWORK EST IMMUABLE**

Les contrôles de sécurité définis ici sont **OBLIGATOIRES**. Toute modification nécessite:

1. **RFC Security Change** avec threat analysis
2. **Approbation CISO** (ou CTO si pas de CISO)
3. **Penetration testing** après modification
4. **Update documentation**

**Contournement des contrôles de sécurité est STRICTEMENT INTERDIT.**

---

**Document créé par**: Security Team + Architecture  
**Date de création**: 2025-11-02  
**Prochaine révision**: Trimestrielle  
**Propriétaire**: CISO / Lead Security Engineer

**Statut**: ✅ **APPROUVÉ ET VERROUILLÉ**
