Saltar a contenido

Table of Contents generated with DocToc

05 - Seguridad del Servidor de MedTime

Identificador: TECH-SEC-SERVER-001 Version: 1.0.0 Fecha: 2025-12-07 Ultima Revision: Creacion inicial - IT-02 Autor: SecurityDrone (MTS-DRN-SEC-001) + SpecQueen Refs Funcional: MTS-AUTH-001, MTS-PRI-001, MTS-OFF-001 Refs Tecnico: TECH-SEC-CLIENT-001 (04-seguridad-cliente.md), TECH-CS-001 (02-arquitectura-cliente-servidor.md) Refs Investigacion: INV-005 (HIPAA Security Rule), INV-011 (Auditoria Zero-Knowledge) Estado: Borrador


1. Principios de Seguridad del Servidor

1.1. Zero-Knowledge: El Servidor NO Ve PHI

PRINCIPIO FUNDAMENTAL:
+------------------------------------------------------------------+
|  El servidor MedTime es ZERO-KNOWLEDGE respecto a datos PHI.     |
|                                                                   |
|  - El servidor SOLO almacena blobs cifrados (opacos)              |
|  - NO tiene acceso a claves de descifrado                         |
|  - NO puede leer contenido de datos de salud                      |
|  - En caso de brecha: atacante obtiene datos INUTILES             |
+------------------------------------------------------------------+

1.1.1. Lo que el Servidor VE vs NO VE

Dato Servidor Ve Servidor NO Ve
Blobs cifrados 0x7f8a9b2c... (bytes) Contenido descifrado
User ID UUID del usuario Datos personales
Timestamps Fechas de sync Contenido de operaciones
Blind indexes Hash determinista Valor original
Metadata sync Tamano, version Datos PHI
Firebase tokens Token JWT Password del usuario

1.1.2. Diagrama de Visibilidad

flowchart LR
    subgraph CLIENTE["Cliente (Ve Todo)"]
        C1[Datos PHI en claro]
        C2[Master Key]
        C3[Datos descifrados]
    end

    subgraph SERVIDOR["Servidor (Zero-Knowledge)"]
        S1[Blobs cifrados]
        S2[Metadata operativa]
        S3[Blind indexes]
    end

    C1 -->|Cifrado E2E| S1
    C1 -->|HMAC-SHA256| S3

    style SERVIDOR fill:#f9f,stroke:#333
    style CLIENTE fill:#9f9,stroke:#333

1.2. Defense in Depth

El servidor implementa multiples capas de seguridad:

CAPAS DE SEGURIDAD SERVIDOR:
+------------------------------------------------------------------+

CAPA 6: INFRAESTRUCTURA CLOUD
+----------------------------------+
| - VPC privada                    |
| - WAF (Web Application Firewall) |
| - DDoS protection                |
| - Network segmentation           |
+----------------------------------+

CAPA 5: APLICACION
+----------------------------------+
| - Rate limiting por endpoint     |
| - Input validation               |
| - OWASP API Security             |
| - Error handling seguro          |
+----------------------------------+

CAPA 4: AUTENTICACION/AUTORIZACION
+----------------------------------+
| - Firebase Auth + JWT            |
| - MFA obligatorio (Pro/Perfect)  |
| - RBAC con permisos granulares   |
| - Session management             |
+----------------------------------+

CAPA 3: BASE DE DATOS
+----------------------------------+
| - Row Level Security (RLS)       |
| - Encryption at rest (AES-256)   |
| - Conexiones TLS obligatorias    |
| - Audit logging                  |
+----------------------------------+

CAPA 2: RED
+----------------------------------+
| - TLS 1.3 obligatorio            |
| - Certificate pinning            |
| - Private subnets                |
| - Security groups                |
+----------------------------------+

CAPA 1: FISICA
+----------------------------------+
| - Data centers certificados      |
| - SOC 2 Type II                  |
| - ISO 27001                      |
+----------------------------------+

1.3. Principio de Minimo Privilegio

Principio de Minimo Privilegio:

  aplicacion:
    # La aplicacion backend tiene permisos minimos
    puede:
      - Leer/escribir blobs cifrados del usuario autenticado
      - Leer catalogos publicos
      - Escribir audit logs
    no_puede:
      - Acceder a datos de otros usuarios
      - Descifrar blobs (no tiene claves)
      - Modificar audit logs existentes
      - Acceder a produccion desde desarrollo

  base_de_datos:
    # Roles separados por funcion
    app_user:
      - SELECT, INSERT, UPDATE en tablas de negocio
      - NO DELETE (soft delete via UPDATE)
      - NO acceso a tablas de auditoria directamente

    audit_writer:
      - INSERT ONLY en tablas de auditoria
      - NO SELECT, UPDATE, DELETE

    admin_readonly:
      - SELECT en todas las tablas
      - NO modificaciones
      - Solo para debugging produccion

2. Autenticacion y Autorizacion

2.1. Firebase Authentication

MedTime utiliza Firebase Authentication como proveedor de identidad principal.

FLUJO DE AUTENTICACION:
+------------------------------------------------------------------+

  CLIENTE                    FIREBASE                  SERVIDOR
     |                           |                         |
     |  1. Login (email/pass)    |                         |
     |-------------------------->|                         |
     |                           |                         |
     |  2. ID Token (JWT)        |                         |
     |<--------------------------|                         |
     |                           |                         |
     |  3. Request + ID Token    |                         |
     |-------------------------------------------------->  |
     |                           |                         |
     |                           |  4. Verificar Token     |
     |                           |<------------------------|
     |                           |                         |
     |                           |  5. Token valido + UID  |
     |                           |------------------------>|
     |                           |                         |
     |  6. Response              |                         |
     |<---------------------------------------------------|
     |                           |                         |

+------------------------------------------------------------------+

2.1.1. Configuracion de Firebase Auth

Firebase Auth Configuration:

  providers_habilitados:
    - email_password: true
    - google: true  # Social login
    - apple: true   # Requerido para iOS
    - phone: false  # No soportado inicialmente

  password_policy:
    min_length: 12
    require_uppercase: true
    require_lowercase: true
    require_number: true
    require_special: false  # Opcional para usabilidad

  session:
    token_expiry: 3600  # 1 hora
    refresh_token_expiry: 2592000  # 30 dias

  mfa:
    enforcement:
      free: optional
      pro: required
      perfect: required
    methods:
      - totp  # Google Authenticator, Authy
      - sms   # Backup (menos seguro)

2.2. JWT y Tokens Personalizados

2.2.1. Estructura del ID Token

{
  "header": {
    "alg": "RS256",
    "typ": "JWT",
    "kid": "firebase-key-id"
  },
  "payload": {
    "iss": "https://securetoken.google.com/medtime-prod",
    "aud": "medtime-prod",
    "auth_time": 1733580000,
    "user_id": "firebase-uid",
    "sub": "firebase-uid",
    "iat": 1733580000,
    "exp": 1733583600,
    "email": "user@example.com",
    "email_verified": true,
    "firebase": {
      "identities": {
        "email": ["user@example.com"]
      },
      "sign_in_provider": "password"
    },
    "medtime_tier": "pro",
    "medtime_role": "patient"
  }
}

2.2.2. Custom Claims de MedTime

Custom Claims:
  # Agregados via Firebase Admin SDK

  medtime_tier:
    type: string
    values: [free, pro, perfect]
    description: Nivel de suscripcion del usuario

  medtime_role:
    type: string
    values: [patient, caregiver, professional, admin]
    description: Rol principal del usuario

  medtime_permissions:
    type: array
    values: [read_own, write_own, read_dependents, manage_dependents]
    description: Permisos granulares

  medtime_device_id:
    type: string
    description: ID del dispositivo actual (para device binding)

2.2.3. Verificacion de Token en Backend

# Pseudocodigo - Verificacion de JWT
async def verify_firebase_token(token: str) -> TokenPayload:
    """Verifica token de Firebase y extrae claims."""

    try:
        # 1. Verificar firma con clave publica de Firebase
        decoded = firebase_admin.auth.verify_id_token(
            token,
            check_revoked=True  # Verificar si token fue revocado
        )

        # 2. Validar claims requeridos
        if not decoded.get('email_verified'):
            raise AuthError("Email no verificado")

        # 3. Extraer custom claims de MedTime
        tier = decoded.get('medtime_tier', 'free')
        role = decoded.get('medtime_role', 'patient')

        # 4. Verificar MFA para Pro/Perfect
        if tier in ['pro', 'perfect']:
            if not decoded.get('firebase', {}).get('sign_in_second_factor'):
                raise AuthError("MFA requerido para tier Pro/Perfect")

        return TokenPayload(
            uid=decoded['uid'],
            email=decoded['email'],
            tier=tier,
            role=role,
            permissions=decoded.get('medtime_permissions', [])
        )

    except firebase_admin.auth.ExpiredIdTokenError:
        raise AuthError("Token expirado")
    except firebase_admin.auth.RevokedIdTokenError:
        raise AuthError("Token revocado")
    except firebase_admin.auth.InvalidIdTokenError:
        raise AuthError("Token invalido")

2.3. Multi-Factor Authentication (MFA)

MFA Configuration:

  enforcement_by_tier:
    free:
      required: false
      encouraged: true
      prompt_interval: 7_days  # Recordar cada 7 dias

    pro:
      required: true
      grace_period: 7_days  # Dias para configurar despues de upgrade
      methods: [totp, sms]

    perfect:
      required: true
      grace_period: 3_days
      methods: [totp]  # Solo TOTP (mas seguro)

  totp_config:
    algorithm: SHA1
    digits: 6
    period: 30
    issuer: "MedTime"

  sms_config:
    code_length: 6
    expiry: 300  # 5 minutos
    max_attempts: 3
    cooldown: 60  # 1 minuto entre reenvios

2.4. Session Management

Session Management:

  server_side:
    # El servidor NO mantiene estado de sesion
    # Toda la autenticacion es via JWT stateless
    session_storage: none
    validation: jwt_per_request

  client_side:
    # El cliente mantiene tokens
    access_token_storage: secure_storage  # Keychain/Keystore
    refresh_token_storage: secure_storage

  token_lifecycle:
    access_token:
      expiry: 3600  # 1 hora
      refresh: automatic  # Via refresh token

    refresh_token:
      expiry: 2592000  # 30 dias
      rotation: true  # Nuevo refresh token en cada uso
      revocation: on_logout

  security_controls:
    concurrent_sessions:
      free: 2
      pro: 5
      perfect: 10

    device_binding:
      enabled: true
      max_devices:
        free: 1
        pro: 3
        perfect: 5

    session_termination:
      on_password_change: all_sessions
      on_mfa_change: all_sessions
      on_security_alert: affected_sessions

3. Row Level Security (RLS) en PostgreSQL

3.1. Principios de RLS

ROW LEVEL SECURITY:
+------------------------------------------------------------------+
|  RLS garantiza que cada usuario SOLO puede acceder a SUS datos.  |
|                                                                   |
|  - Politicas aplicadas a nivel de fila                            |
|  - Transparente para la aplicacion                                |
|  - Imposible de bypassear via SQL injection                       |
|  - Auditoria automatica de accesos                                |
+------------------------------------------------------------------+

3.1.1. Habilitacion de RLS

-- Habilitar RLS en tablas con datos de usuario
ALTER TABLE user_sync_data ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_devices ENABLE ROW LEVEL SECURITY;
ALTER TABLE user_preferences ENABLE ROW LEVEL SECURITY;
ALTER TABLE audit_logs ENABLE ROW LEVEL SECURITY;

-- IMPORTANTE: Forzar RLS incluso para owner de tabla
ALTER TABLE user_sync_data FORCE ROW LEVEL SECURITY;

3.2. Politicas por Tabla

3.2.1. Tabla: user_sync_data (Blobs Cifrados)

-- Contexto: user_id se pasa via current_setting desde la aplicacion

-- Politica SELECT: Usuario solo ve sus propios blobs
CREATE POLICY user_select_own_data ON user_sync_data
    FOR SELECT
    USING (user_id = current_setting('app.current_user_id')::uuid);

-- Politica INSERT: Usuario solo puede insertar para si mismo
CREATE POLICY user_insert_own_data ON user_sync_data
    FOR INSERT
    WITH CHECK (user_id = current_setting('app.current_user_id')::uuid);

-- Politica UPDATE: Usuario solo puede actualizar sus datos
CREATE POLICY user_update_own_data ON user_sync_data
    FOR UPDATE
    USING (user_id = current_setting('app.current_user_id')::uuid)
    WITH CHECK (user_id = current_setting('app.current_user_id')::uuid);

-- Politica DELETE: Soft delete via UPDATE (no permitir DELETE real)
-- No se crea politica DELETE - operacion prohibida

3.2.2. Tabla: user_devices

-- Usuario ve sus dispositivos registrados
CREATE POLICY user_select_own_devices ON user_devices
    FOR SELECT
    USING (user_id = current_setting('app.current_user_id')::uuid);

-- Maximo dispositivos por tier (verificado en aplicacion + trigger)
CREATE POLICY user_insert_own_devices ON user_devices
    FOR INSERT
    WITH CHECK (
        user_id = current_setting('app.current_user_id')::uuid
        AND (
            SELECT COUNT(*) FROM user_devices
            WHERE user_id = current_setting('app.current_user_id')::uuid
        ) < current_setting('app.max_devices')::int
    );

3.2.3. Tabla: audit_logs

-- Logs de auditoria: solo INSERT, nunca SELECT/UPDATE/DELETE
-- La aplicacion usa un rol especial para escribir

CREATE POLICY audit_insert_only ON audit_logs
    FOR INSERT
    WITH CHECK (true);  -- Cualquier insert es valido

-- No hay politicas SELECT/UPDATE/DELETE para la aplicacion
-- Solo admins con rol especial pueden leer logs

3.3. Roles de Base de Datos

-- Crear roles con permisos minimos
CREATE ROLE medtime_app_user NOLOGIN;
CREATE ROLE medtime_audit_writer NOLOGIN;
CREATE ROLE medtime_admin_readonly NOLOGIN;

-- Permisos para app_user
GRANT SELECT, INSERT, UPDATE ON user_sync_data TO medtime_app_user;
GRANT SELECT, INSERT, UPDATE ON user_devices TO medtime_app_user;
GRANT SELECT ON public_catalogs TO medtime_app_user;
-- NO GRANT DELETE en ninguna tabla

-- Permisos para audit_writer
GRANT INSERT ON audit_logs TO medtime_audit_writer;
-- NO SELECT, UPDATE, DELETE

-- Permisos para admin_readonly
GRANT SELECT ON ALL TABLES IN SCHEMA public TO medtime_admin_readonly;
-- NO INSERT, UPDATE, DELETE

-- Usuario de conexion de la aplicacion
CREATE USER medtime_backend WITH PASSWORD 'secure_password';
GRANT medtime_app_user TO medtime_backend;
GRANT medtime_audit_writer TO medtime_backend;

3.3.1. Configuracion de Contexto de Usuario

# Pseudocodigo - Configurar contexto RLS por request
async def set_rls_context(db_conn, user: TokenPayload):
    """Configura el contexto RLS para la conexion."""

    await db_conn.execute(
        "SET LOCAL app.current_user_id = $1",
        str(user.uid)
    )

    # Configurar limite de dispositivos segun tier
    max_devices = {
        'free': 1,
        'pro': 3,
        'perfect': 5
    }
    await db_conn.execute(
        "SET LOCAL app.max_devices = $1",
        max_devices.get(user.tier, 1)
    )

    # Configurar rol segun tier
    await db_conn.execute(
        "SET LOCAL app.user_tier = $1",
        user.tier
    )

4. Proteccion de APIs

4.1. Rate Limiting

Rate Limiting Configuration:

  global:
    # Limite global por IP
    requests_per_minute: 1000
    burst: 100

  per_user:
    # Limite por usuario autenticado
    free:
      requests_per_minute: 60
      burst: 10
    pro:
      requests_per_minute: 300
      burst: 50
    perfect:
      requests_per_minute: 600
      burst: 100

  per_endpoint:
    # Limites especificos por endpoint

    POST /auth/login:
      requests_per_minute: 5
      burst: 3
      per: ip
      note: "Prevenir brute force"

    POST /auth/mfa/verify:
      requests_per_minute: 3
      burst: 1
      per: ip
      note: "Prevenir brute force MFA"

    POST /sync/push:
      requests_per_minute: 30
      burst: 5
      per: user
      note: "Prevenir abuso de sync"

    GET /catalogs/*:
      requests_per_minute: 120
      burst: 20
      per: user
      note: "Catalogos son cache-friendly"

  response_headers:
    X-RateLimit-Limit: "{limit}"
    X-RateLimit-Remaining: "{remaining}"
    X-RateLimit-Reset: "{reset_timestamp}"

  exceeded_response:
    status: 429
    body:
      error: "rate_limit_exceeded"
      message: "Demasiadas solicitudes. Intenta de nuevo en {retry_after} segundos."
      retry_after: "{seconds}"

4.1.1. Implementacion de Rate Limiting

# Pseudocodigo - Rate limiter con Redis
class RateLimiter:
    def __init__(self, redis_client):
        self.redis = redis_client

    async def check_rate_limit(
        self,
        key: str,
        limit: int,
        window_seconds: int
    ) -> RateLimitResult:
        """Verifica rate limit usando sliding window."""

        now = time.time()
        window_start = now - window_seconds

        pipe = self.redis.pipeline()

        # Remover requests fuera de la ventana
        pipe.zremrangebyscore(key, 0, window_start)

        # Contar requests en ventana actual
        pipe.zcard(key)

        # Agregar request actual
        pipe.zadd(key, {str(uuid.uuid4()): now})

        # Establecer TTL
        pipe.expire(key, window_seconds)

        _, count, _, _ = await pipe.execute()

        return RateLimitResult(
            allowed=count < limit,
            remaining=max(0, limit - count - 1),
            reset_at=now + window_seconds
        )

4.2. Validacion de Entrada

Input Validation:

  general:
    # Todos los endpoints
    max_request_size: 10MB
    max_header_size: 8KB
    allowed_content_types:
      - application/json
      - application/octet-stream  # Para blobs

  string_fields:
    # Sanitizacion de strings
    max_length: 10000  # Por campo
    strip_null_bytes: true
    normalize_unicode: true

  uuid_fields:
    # Validacion estricta de UUIDs
    format: uuid_v4
    reject_invalid: true

  blob_fields:
    # Blobs cifrados
    max_size: 5MB
    required_prefix: null  # Sin validacion de contenido (cifrado)

  pagination:
    max_limit: 100
    default_limit: 20
    max_offset: 10000

4.2.1. Schema Validation con Pydantic

from pydantic import BaseModel, Field, validator
from uuid import UUID
from datetime import datetime
import re

class SyncPushRequest(BaseModel):
    """Request para push de datos sincronizados."""

    device_id: UUID
    operations: list[SyncOperation] = Field(max_items=100)
    client_timestamp: datetime

    @validator('operations')
    def validate_operations(cls, v):
        for op in v:
            # Validar que blob es base64 valido
            if op.encrypted_blob:
                try:
                    base64.b64decode(op.encrypted_blob)
                except Exception:
                    raise ValueError("Blob invalido")
            # Validar tamano
            if len(op.encrypted_blob) > 5 * 1024 * 1024:
                raise ValueError("Blob excede 5MB")
        return v

class SyncOperation(BaseModel):
    """Operacion de sincronizacion individual."""

    operation_id: UUID
    operation_type: str = Field(regex='^(create|update|delete)$')
    entity_type: str = Field(max_length=50)
    entity_id: UUID
    encrypted_blob: str | None = None  # Base64
    blind_indexes: dict[str, str] = {}
    client_timestamp: datetime

4.3. OWASP API Security Top 10

OWASP API Security Top 10 - Mitigaciones:

  API1 - Broken Object Level Authorization:
    riesgo: Alto
    mitigacion:
      - RLS en PostgreSQL (ver seccion 3)
      - Verificar user_id en cada request
      - No exponer IDs secuenciales (usar UUID)
    verificacion: "Cada query filtra por user_id autenticado"

  API2 - Broken Authentication:
    riesgo: Alto
    mitigacion:
      - Firebase Auth (proveedor probado)
      - MFA obligatorio para Pro/Perfect
      - Rate limiting en endpoints de auth
      - Tokens con expiracion corta (1h)
    verificacion: "Penetration testing anual"

  API3 - Broken Object Property Level Authorization:
    riesgo: Medio
    mitigacion:
      - Response schemas estrictos
      - No incluir campos sensibles en responses
      - Datos PHI siempre cifrados (no hay campos sensibles en servidor)
    verificacion: "Schema validation en responses"

  API4 - Unrestricted Resource Consumption:
    riesgo: Medio
    mitigacion:
      - Rate limiting por tier
      - Limites de tamano en requests
      - Paginacion obligatoria
      - Timeout en operaciones largas
    verificacion: "Load testing trimestral"

  API5 - Broken Function Level Authorization:
    riesgo: Alto
    mitigacion:
      - RBAC con permisos granulares
      - Decoradores de autorizacion en cada endpoint
      - Endpoints admin en path separado
    verificacion: "Matriz de permisos documentada"

  API6 - Unrestricted Access to Sensitive Business Flows:
    riesgo: Bajo
    mitigacion:
      - Rate limiting en flujos criticos
      - CAPTCHA para registro (si abuso detectado)
      - Monitoreo de patrones anomalos
    verificacion: "Alertas de comportamiento anomalo"

  API7 - Server Side Request Forgery:
    riesgo: Bajo
    mitigacion:
      - No hay endpoints que hagan requests a URLs externas
      - OCR service en sandbox aislado
      - Whitelist de servicios internos
    verificacion: "Revision de arquitectura"

  API8 - Security Misconfiguration:
    riesgo: Medio
    mitigacion:
      - Headers de seguridad (ver seccion 6)
      - CORS estricto
      - Error messages genericos
      - Hardening de infraestructura
    verificacion: "Security headers scan semanal"

  API9 - Improper Inventory Management:
    riesgo: Bajo
    mitigacion:
      - OpenAPI spec versionada
      - Endpoints deprecated marcados
      - No hay endpoints ocultos/debug en produccion
    verificacion: "API inventory automatizado"

  API10 - Unsafe Consumption of APIs:
    riesgo: Bajo
    mitigacion:
      - Firebase es unica dependencia externa de auth
      - Validar responses de Firebase
      - Timeout y retry con backoff
    verificacion: "Dependencias auditadas"

5. Audit Logging

5.1. Eventos a Registrar

Eventos de Auditoria:

  autenticacion:
    - login_success
    - login_failure
    - logout
    - mfa_enabled
    - mfa_disabled
    - mfa_challenge_success
    - mfa_challenge_failure
    - password_change
    - password_reset_request
    - token_refresh
    - token_revoked

  autorizacion:
    - access_granted
    - access_denied
    - permission_change
    - role_change

  datos:
    - sync_push
    - sync_pull
    - device_registered
    - device_removed
    - account_deleted

  seguridad:
    - rate_limit_exceeded
    - invalid_token
    - suspicious_activity
    - brute_force_detected
    - device_binding_violation

  administracion:
    - config_change
    - user_suspended
    - user_restored
    - tier_change

5.2. Estructura del Audit Log

{
  "log_id": "uuid-v4",
  "timestamp": "2025-12-07T15:30:00.000Z",
  "event_type": "SYNC_PUSH",
  "event_subtype": "SUCCESS",

  "actor": {
    "user_id": "uuid-usuario",
    "device_id": "uuid-dispositivo",
    "ip_address": "192.168.1.100",
    "user_agent": "MedTime/1.0 iOS/17.0",
    "tier": "pro"
  },

  "resource": {
    "type": "sync_data",
    "id": "uuid-operacion",
    "action": "create"
  },

  "context": {
    "request_id": "uuid-request",
    "session_id": "uuid-session",
    "endpoint": "POST /api/v1/sync/push",
    "response_status": 200,
    "response_time_ms": 150
  },

  "metadata": {
    "operations_count": 5,
    "total_size_bytes": 15000,
    "client_timestamp": "2025-12-07T15:29:58.000Z"
  },

  "security": {
    "risk_score": 0,
    "anomalies": []
  }
}

5.3. Retencion y Almacenamiento

Retencion de Audit Logs:

  por_categoria:
    autenticacion: 6_years  # HIPAA requirement
    acceso_phi: 6_years     # HIPAA requirement
    errores_seguridad: 6_years
    operaciones_normales: 2_years
    metricas: 1_year

  almacenamiento:
    hot_storage:
      duracion: 30_days
      tipo: PostgreSQL
      indices: [timestamp, user_id, event_type]

    warm_storage:
      duracion: 1_year
      tipo: S3 Standard
      formato: Parquet (comprimido)

    cold_storage:
      duracion: 6_years
      tipo: S3 Glacier
      formato: Parquet (comprimido)

  seguridad_logs:
    encryption: AES-256
    integrity: SHA-256 hash chain
    immutability: Write-once policy
    access: Admin readonly role only

6. Seguridad de Red

6.1. TLS 1.3

TLS Configuration:

  version:
    minimum: TLS_1_3
    fallback: none  # No TLS 1.2

  cipher_suites:
    # Solo cipher suites modernos
    - TLS_AES_256_GCM_SHA384
    - TLS_CHACHA20_POLY1305_SHA256
    - TLS_AES_128_GCM_SHA256

  certificate:
    type: EV SSL
    key_size: 4096
    algorithm: RSA
    renewal: automatic (Let's Encrypt o similar)

  hsts:
    enabled: true
    max_age: 31536000  # 1 year
    include_subdomains: true
    preload: true

6.2. Firewall y Network Policies

Network Security:

  vpc:
    cidr: 10.0.0.0/16

  subnets:
    public:
      # Solo load balancer
      cidr: 10.0.1.0/24
      nat_gateway: true

    private_app:
      # Servidores de aplicacion
      cidr: 10.0.2.0/24
      nat_gateway: false (egress via NAT)

    private_db:
      # Base de datos
      cidr: 10.0.3.0/24
      nat_gateway: false (no egress)

  security_groups:

    load_balancer:
      inbound:
        - port: 443, source: 0.0.0.0/0  # HTTPS publico
      outbound:
        - port: 8080, dest: private_app

    app_servers:
      inbound:
        - port: 8080, source: load_balancer
      outbound:
        - port: 5432, dest: private_db
        - port: 443, dest: 0.0.0.0/0  # Firebase Auth

    database:
      inbound:
        - port: 5432, source: app_servers
      outbound: none

6.3. DDoS Protection

DDoS Protection:

  layers:

    layer_3_4:
      provider: AWS Shield Standard
      protection:
        - SYN floods
        - UDP floods
        - Reflection attacks

    layer_7:
      provider: AWS WAF
      rules:
        - Rate-based (>2000 req/5min por IP)
        - Geographic (bloquear paises no soportados)
        - SQL injection patterns
        - XSS patterns
        - Bad bot signatures

  auto_scaling:
    enabled: true
    min_instances: 2
    max_instances: 20
    scale_up_threshold: 70% CPU
    scale_down_threshold: 30% CPU

7. Gestion de Secretos

7.1. Vault/Secret Manager

Secret Management:

  provider: AWS Secrets Manager  # o HashiCorp Vault

  secrets_almacenados:
    database_credentials:
      rotation: 30_days
      format: json

    firebase_service_account:
      rotation: 90_days
      format: json

    api_keys_externos:
      rotation: manual

    encryption_keys:
      rotation: 365_days

  acceso:
    aplicacion:
      # Via IAM Role, no credenciales hardcoded
      role: medtime-app-role
      secrets: [database_credentials, firebase_service_account]

    ci_cd:
      role: medtime-deploy-role
      secrets: [deployment_keys]

    admin:
      # Via MFA + approval
      role: medtime-admin-role
      secrets: all
      requires: mfa + manager_approval

7.2. Rotacion de Credenciales

Credential Rotation:

  database:
    strategy: dual_user
    steps:
      1: Crear usuario nuevo con nuevo password
      2: Actualizar aplicacion para usar nuevo usuario
      3: Verificar que conexiones usan nuevo usuario
      4: Eliminar usuario viejo
    frequency: 30_days

  api_keys:
    strategy: versioned
    steps:
      1: Crear nueva version del secret
      2: Actualizar aplicacion para usar nueva version
      3: Deprecar version vieja (7 dias gracia)
      4: Eliminar version vieja
    frequency: 90_days

  firebase_service_account:
    strategy: manual
    requires: security_team_approval
    frequency: 90_days

8. Monitoreo de Seguridad

8.1. Alertas de Seguridad

Security Alerts:

  critical:
    # Respuesta inmediata (<5 min)
    - brute_force_attack
    - sql_injection_attempt
    - unauthorized_admin_access
    - data_exfiltration_pattern
    notification: pagerduty + sms

  high:
    # Respuesta rapida (<1 hora)
    - multiple_failed_logins (>10 en 5 min)
    - rate_limit_sustained (>100 en 1 min)
    - unusual_geographic_access
    - device_binding_violation
    notification: slack + email

  medium:
    # Revision diaria
    - new_device_registration
    - password_change
    - mfa_disabled
    - permission_change
    notification: email (digest diario)

  low:
    # Metricas semanales
    - failed_login (individual)
    - token_expired
    notification: dashboard only

8.2. Intrusion Detection

Intrusion Detection:

  network_based:
    tool: AWS GuardDuty
    detects:
      - Port scanning
      - Cryptocurrency mining
      - Unusual API calls
      - Compromised credentials

  application_based:
    tool: Custom + WAF logs
    detects:
      - SQL injection patterns
      - XSS attempts
      - Path traversal
      - Command injection

  behavioral:
    tool: Custom anomaly detection
    detects:
      - Unusual login times
      - Unusual sync patterns
      - Geographic anomalies
      - Volume anomalies

  response:
    automatic:
      - Block IP after 10 failed logins
      - Rate limit after sustained abuse
      - Alert on any SQL injection pattern

    manual:
      - Review by security team
      - Escalation procedure defined

9. Cumplimiento Regulatorio

9.1. HIPAA Security Rule

HIPAA Compliance - Server:

  administrative_safeguards:
    security_officer: defined
    workforce_security: background_checks
    security_awareness: annual_training
    security_incidents: documented_procedure
    contingency_plan: disaster_recovery

  physical_safeguards:
    # Via cloud provider (AWS/GCP)
    facility_access: soc2_certified
    workstation_security: n/a (serverless)
    device_controls: n/a (no physical devices)

  technical_safeguards:
    access_control:
      unique_user_id: yes (UUID)
      emergency_access: documented
      automatic_logoff: 1_hour_token_expiry
      encryption: aes_256

    audit_controls:
      audit_logs: yes
      retention: 6_years
      integrity: hash_chain

    integrity_controls:
      data_integrity: checksums
      transmission_integrity: tls_1_3

    transmission_security:
      encryption: tls_1_3
      integrity: certificate_pinning

9.2. LGPD

LGPD Compliance - Server:

  principios:
    finalidade: defined_purposes_only
    adequacao: minimal_data_collection
    necessidade: essential_data_only
    livre_acesso: user_data_export
    qualidade: accuracy_maintained
    transparencia: privacy_policy
    seguranca: encryption_rls_audit
    prevencao: proactive_security
    nao_discriminacao: no_sensitive_processing
    responsabilizacao: compliance_documented

  derechos_titular:
    confirmacion: GET /api/v1/user/data
    acceso: GET /api/v1/user/data/export
    correccion: PUT /api/v1/user/data
    anonimizacion: POST /api/v1/user/anonymize
    eliminacion: DELETE /api/v1/user
    portabilidad: GET /api/v1/user/data/export
    revocacion: POST /api/v1/user/consent/revoke

9.3. FDA 21 CFR Part 11

FDA 21 CFR Part 11 - Server:

  electronic_records:
    validation:
      system_validation: documented
      accuracy: checksums
      retrievability: 6_year_retention

    audit_trail:
      creation: timestamp + user_id
      modification: full_history
      deletion: soft_delete_only

    record_retention:
      duration: 6_years
      format: original + accessible

  electronic_signatures:
    uniqueness: uuid_per_user
    verification: firebase_auth + mfa
    linking: signature_to_record_binding

  signature_components:
    printed_name: user_email
    date_time: server_timestamp
    meaning: action_type (create/update/approve)

10. Respuesta a Incidentes

Incident Response:

  clasificacion:
    p1_critical:
      definicion: "Brecha confirmada de datos PHI"
      tiempo_respuesta: 15_minutes
      notificacion: [security_team, cto, legal]

    p2_high:
      definicion: "Ataque activo detectado"
      tiempo_respuesta: 1_hour
      notificacion: [security_team, on_call]

    p3_medium:
      definicion: "Vulnerabilidad explotable encontrada"
      tiempo_respuesta: 24_hours
      notificacion: [security_team]

    p4_low:
      definicion: "Anomalia de seguridad"
      tiempo_respuesta: 72_hours
      notificacion: [security_team]

  procedimiento:
    1_deteccion:
      - Alerta automatica o reporte manual
      - Clasificar severidad

    2_contencion:
      - Aislar sistemas afectados
      - Preservar evidencia
      - Bloquear vector de ataque

    3_erradicacion:
      - Identificar causa raiz
      - Eliminar acceso no autorizado
      - Parchear vulnerabilidad

    4_recuperacion:
      - Restaurar servicios
      - Verificar integridad
      - Monitoreo intensivo

    5_post_mortem:
      - Documentar timeline
      - Identificar mejoras
      - Actualizar procedimientos

  notificacion_brecha:
    hipaa: 60_days_max
    lgpd: 72_hours
    usuarios: "sin demora indebida"

11. Referencias

11.1. Documentos Internos

ID Documento Relacion
TECH-SEC-CLIENT-001 04-seguridad-cliente.md Seguridad del lado cliente
TECH-CS-001 02-arquitectura-cliente-servidor.md Arquitectura general
MTS-AUTH-001 Autenticacion (functional-spec) Requisitos funcionales
MTS-PRI-001 Privacidad (functional-spec) Requisitos de privacidad
INV-005 HIPAA Security Rule Controles tecnicos
INV-011 Auditoria Zero-Knowledge Estrategia de auditoria

11.2. Referencias Externas


12. Historial de Cambios

Version Fecha Autor Cambios
1.0.0 2025-12-07 SecurityDrone + SpecQueen Creacion inicial - IT-02

Documento generado por SecurityDrone (MTS-DRN-SEC-001) "La seguridad del servidor complementa la del cliente. Zero-Knowledge garantiza que incluso una brecha total del servidor no compromete datos PHI."