# Seguridad — SKEEN Derma Experts

**Versión:** 2.0  
**Fecha:** 16 de julio de 2026

---

## 1. Principios de Seguridad

1. **Defensa en profundidad:** Múltiples capas de seguridad.
2. **Principio de menor privilegio:** Acceso mínimo necesario.
3. **Datos en tránsito cifrados:** HTTPS/TLS en producción.
4. **Datos en reposo protegidos:** PostgreSQL con autenticación, backups cifrados.
5. **Secretos fuera del código:** Variables de entorno, nunca hardcoded.
6. **Auditoría:** Logs de acceso y cambios.

---

## 2. Autenticación y Autorización

### 2.1 Frontend React (JWT)

- **Algoritmo:** HMAC-SHA256
- **Expiración:** 24 horas
- **Payload:** `uid`, `login`, `role`, `exp`
- **Roles:** `admin`, `recepcion`, `medico`, `lectura`

**Generación de token:**
```python
def sign_token(env, user):
    payload = {
        'uid': user.id,
        'login': user.login,
        'role': user.role,
        'exp': int(time.time()) + 86400
    }
    secret = env['ir.config_parameter'].sudo().get_param('skeen.frontend.jwt_secret')
    return jwt.encode(payload, secret, algorithm='HS256')
```

### 2.2 Odoo API (API Key)

- Endpoints JSON-RPC/XML-RPC usan `auth='api_key'`.
- API key almacenada en `ir.config_parameter` o header.

### 2.3 WACRM API (Bearer Token)

- API keys creadas en Supabase tabla `api_keys`.
- Scopes granulares: `messages:send`, `contacts:read`, etc.

### 2.4 Supabase (JWT)

- **Anon Key:** Para operaciones públicas.
- **Service Role Key:** Para operaciones administrativas (solo backend).
- **Row-Level Security (RLS):** Habilitado en tablas sensibles.

---

## 3. Webhooks

### 3.1 Meta → WACRM

- **Verify Token:** `skeen_webhook_verify_2026`
- **Validación:** GET con `hub.mode`, `hub.verify_token`, `hub.challenge`.

### 3.2 WACRM → Bridge (HMAC-SHA256)

**Firma:**
```javascript
function verifySignature(payload, signature) {
  const [t, v1] = signature.split(',').map(s => s.split('=')[1]);
  const expected = crypto.createHmac('sha256', WACRM_WEBHOOK_SECRET)
    .update(`${t}.${payload}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
}
```

**Headers:**
- `X-WACRM-Signature: t=<timestamp>,v1=<hmac_sha256>`

**Validación:**
1. Extraer timestamp y firma del header.
2. Calcular HMAC-SHA256 de `timestamp.payload`.
3. Comparar con firma recibida (timing-safe).
4. Rechazar si timestamp es muy antiguo (> 5 min).

---

## 4. Protección de Datos

### 4.1 Datos Sensibles

| Dato | Protección |
|------|-----------|
| Teléfonos | RLS en Supabase, validación en Odoo |
| Emails | RLS, enmascaramiento en logs |
| Historial médico | Acceso restringido por rol |
| Datos de pago | Nunca almacenar tarjetas, usar tokens |
| API keys | Variables de entorno, nunca commiteadas |

### 4.2 Enmascaramiento en Logs

```python
def mask_phone(phone):
    if len(phone) > 4:
        return phone[:3] + '*' * (len(phone) - 7) + phone[-4:]
    return '***'
```

---

## 5. Seguridad en Red

### 5.1 Firewall

```bash
# Solo puertos necesarios
sudo ufw allow 22/tcp    # SSH
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS
sudo ufw enable
```

### 5.2 nginx

```nginx
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://localhost:8069;
    }
}
```

### 5.3 HTTPS

Configurar SSL en producción:

```bash
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d skeen.consultoria-as.com
```

---

## 6. Gestión de Secretos

### 6.1 Variables de Entorno

**Nunca commitear:**
- `.env`
- `.env.local`
- `*.key`
- `*.pem`
- Tokens de Meta
- Keys de Stripe/MercadoPago

### 6.2 .gitignore

```gitignore
# Secretos
.env
.env.local
.env.*.local
*.key
*.pem
*.crt
*.pfx
*.p12
*.keystore
*.jks
```

### 6.3 Rotación de Secretos

| Secreto | Frecuencia | Método |
|---------|-----------|--------|
| Meta Access Token | 60 días | Meta Developers |
| WACRM API Key | 90 días | Dashboard WACRM |
| Supabase JWT | 180 días | Regenerar |
| Odoo admin password | 90 días | Cambiar manual |
| ENCRYPTION_KEY | 365 días | Regenerar (requiere re-encrypt) |

---

## 7. Auditoría y Logs

### 7.1 Logs de Odoo

```bash
tail -f /tmp/odoo.log | grep "audit"
```

### 7.2 Logs de WACRM

```bash
tail -f /tmp/wacrm.log
```

### 7.3 Logs del Bridge

```bash
tail -f /tmp/hermes-bridge.log
```

### 7.4 Auditoría de Base de Datos

```sql
-- Cambios en pacientes
SELECT * FROM audit_log WHERE model = 'res.partner' ORDER BY create_date DESC LIMIT 100;

-- Accesos a datos sensibles
SELECT * FROM audit_log WHERE model = 'skeen.cita' AND method = 'read' ORDER BY create_date DESC;
```

---

## 8. Backups

### 8.1 Estrategia

| Tipo | Frecuencia | Retención | Ubicación |
|------|-----------|-----------|-----------|
| PostgreSQL Odoo | Diario | 30 días | Local + remoto |
| PostgreSQL Supabase | Diario | 30 días | Local + remoto |
| Archivos | Semanal | 12 semanas | Local + remoto |
| Configuración | Mensual | 12 meses | Git |

### 8.2 Scripts

```bash
#!/bin/bash
# backup-daily.sh

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=/root/backups

# PostgreSQL Odoo
pg_dump -U skeen -h localhost skeen_odoo | gzip > $BACKUP_DIR/odoo_$DATE.sql.gz

# PostgreSQL Supabase
docker exec supabase-db pg_dump -U postgres postgres | gzip > $BACKUP_DIR/supabase_$DATE.sql.gz

# Archivos
tar -czf $BACKUP_DIR/files_$DATE.tar.gz \
  /root/skeen-frontend \
  /root/skeen-wacrm \
  /root/skeen-odoo/addons/skeen_* \
  /root/skeen-roadmap-hermes \
  /root/migracion

# Limpiar backups antiguos
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
```

---

## 9. Respuesta a Incidentes

### 9.1 Detección

- Monitoreo Uptime Kuma.
- Alertas de errores en logs.
- Alertas de uso anormal de API.

### 9.2 Contención

1. Identificar componente afectado.
2. Aislar componente (stop service, block IP).
3. Evaluar impacto (datos expuestos, usuarios afectados).

### 9.3 Erradicación

1. Cerrar vulnerabilidad.
2. Cambiar secretos comprometidos.
3. Restaurar desde backup limpio si es necesario.

### 9.4 Recuperación

1. Restaurar servicios.
2. Verificar integridad de datos.
3. Monitorear post-incidente.

### 9.5 Lecciones Aprendidas

1. Documentar incidente.
2. Actualizar procedimientos.
3. Mejorar controles.

---

## 10. Checklist de Seguridad

### Pre-Producción

- [ ] HTTPS configurado
- [ ] Firewall configurado
- [ ] Secretos rotados
- [ ] API keys con scopes mínimos
- [ ] RLS habilitado en Supabase
- [ ] Rate limiting configurado
- [ ] Logs de auditoría activos
- [ ] Backups automatizados
- [ ] Monitoreo configurado

### Producción

- [ ] Revisión mensual de logs
- [ ] Rotación trimestral de secretos
- [ ] Pruebas de penetración anuales
- [ ] Actualizaciones de seguridad mensuales
- [ ] Verificación de backups mensual
- [ ] Revisión de accesos trimestral

---

## 11. Contacto de Seguridad

Para reportar vulnerabilidades:
- **Email:** ialcarazsalazar@consultoria-as.com
- **PGP:** (a configurar)

**No divulgar públicamente** hasta que se haya resuelto.
