Skip to main content
QMSQMS
QMS
  • Welcome to your QMS
  • Quality Manual
  • Procedures
    • GP-001 Control of documents
    • GP-002 Quality planning
    • GP-003 Audits
    • GP-004 Vigilance system
    • GP-005 Human Resources and Training
    • GP-006 Non-conformity, Corrective and Preventive actions
    • GP-007 Post-market surveillance
    • GP-008 Product requirements
    • GP-009 Sales
    • GP-010 Purchases and suppliers evaluation
    • GP-011 Provision of service
    • GP-012 Design, redesign and development
    • GP-013 Risk management
    • GP-014 Feedback and complaints
    • GP-015 Clinical evaluation
    • GP-016 Traceability and identification
    • GP-017 Technical assistance service
    • GP-018 Infrastructure and facilities
    • GP-019 Software validation plan
    • GP-020 QMS Data analysis
    • GP-021 Communications
    • GP-022 Document translation
    • GP-023 Change control management
    • GP-024 Predetermined Change Control Plan
    • GP-025 Usability and Human Factors Engineering
    • GP-027 Corporate Governance
    • GP-028 AI Development
    • GP-029 Software Delivery And Comissioning
    • GP-050 Data Protection
    • GP-051 Security violations
    • GP-052 Data Privacy Impact Assessment (DPIA)
    • GP-100 Business Continuity (BCP) and Disaster Recovery plans (DRP)
    • GP-101 Information security
    • GP-200 Remote Data Acquisition in Clinical Investigations
    • GP-026 Market-specific product requirements
    • GP-110 Esquema Nacional de Seguridad
      • ORG Marco organizativo
      • OP Marco operacional
        • OP.PL Planificación
        • OP.ACC Control de acceso
        • OP.EXP Explotación
        • OP.EXT Servicios externos
        • OP.NUB Servicios en la nube
          • OP.NUB.1 Servicios en la nube
        • OP.CONT Continuidad del servicio
        • OP.MON Monitorización del sistema
      • MP Medidas de protección
      • Sin asignar
      • Real Decreto 311/2022, de 3 de mayo, por el que se regula el Esquema Nacional de Seguridad.
  • Records
  • Legit.Health Plus Version 1.1.0.0
  • Legit.Health Plus Version 1.1.0.1
  • Licenses and accreditations
  • Applicable Standards and Regulations
  • Public tenders
  • Procedures
  • GP-110 Esquema Nacional de Seguridad
  • OP Marco operacional
  • OP.NUB Servicios en la nube
  • OP.NUB.1 Servicios en la nube

OP.NUB.1 Servicios en la nube

☑️Aplicación de la medida

De acuerdo al ANEXO II, 2 Selección de medidas de seguridad, la medida de seguridad OP.NUB.1 Servicios en la nube sí aplica dada la categoría de seguridad del sistema.

OP.NUB.1 Protección de servicios en la nube​

Documentos de referencia​

  • ENS (Esquema Nacional de Seguridad):

    • Real Decreto 311/2022 - Requisitos de seguridad para servicios cloud
    • CCN-STIC 823 - Utilización de servicios en la nube
    • CCN-STIC 884 - Guía de configuración segura para AWS
    • CCN-STIC 885 - Guía de configuración segura para Azure
  • Normativa Internacional:

    • ISO/IEC 27017:2015 - Code of practice for cloud services
    • ISO/IEC 27018:2019 - Protection of PII in public clouds
    • NIST SP 800-53 rev5 - Security and Privacy Controls
    • CSA Cloud Controls Matrix v4.0
  • Regulación Sector Salud:

    • EU MDR 2017/745 - Medical Device Regulation
    • FDA Guidance - Cybersecurity in Medical Devices (2023)
    • NIS2 Directive - Critical infrastructure protection
    • HIPAA/HITECH - Healthcare data protection
  • AWS Specific Compliance:

    • AWS Well-Architected Framework - Security Pillar
    • AWS Security Best Practices
    • AWS Shared Responsibility Model
    • AWS Compliance Programs (SOC 2, ISO 27001, HIPAA)

Guía de implantación​

  1. La protección de servicios en la nube para sistemas de categoría MEDIA con criticidad ALTA en Integridad, Autenticidad y Trazabilidad requiere:
  • Modelo de responsabilidad compartida claramente definido
  • Controles de seguridad específicos para entorno cloud
  • Gestión de identidades y accesos robusta
  • Cifrado de datos en tránsito y reposo
  • Monitorización y auditoría continua
  • Gestión de incidentes coordinada con el proveedor
  • Cumplimiento regulatorio verificado

Implementación en Legit Health Plus​

1. Arquitectura Cloud de Legit Health Plus​

1.1 Visión General de la Infraestructura AWS​

Legit Health Plus opera como un dispositivo médico SaaS Clase IIa desplegado completamente en AWS, con la siguiente arquitectura:

AWS_Infrastructure:
Primary_Region: eu-west-1 (Ireland)
DR_Region: eu-central-1 (Frankfurt)

Account_Structure:
Production:
account_id: "PROD-ACCOUNT-ID"
criticality: "Critical"
compliance: ["HIPAA", "GDPR", "MDR", "ENS"]

Staging:
account_id: "STAGE-ACCOUNT-ID"
criticality: "High"
purpose: "Pre-production validation"

Development:
account_id: "DEV-ACCOUNT-ID"
criticality: "Medium"
purpose: "Development and testing"

Network_Architecture:
VPC_Design:
- Production_VPC: "10.0.0.0/16"
- Staging_VPC: "10.1.0.0/16"
- Development_VPC: "10.2.0.0/16"

Segmentation:
- Public_Subnets: "Load balancers, NAT gateways"
- Private_Subnets: "Application servers, databases"
- Isolated_Subnets: "Critical data processing"

1.2 Servicios AWS Críticos Utilizados​

Servicio AWSFunciónCriticidadControles ENS Aplicados
ECS FargateContenedores de aplicaciónCRÍTICAmp.sw.1, op.exp.2
RDS PostgreSQLBase de datos clínicaCRÍTICAmp.info.3, op.exp.11
S3Almacenamiento de imágenes médicasCRÍTICAmp.info.4, mp.si.2
CloudFrontCDN y protección DDoSALTAmp.com.1, op.mon.1
CognitoGestión de identidadesCRÍTICAop.acc.1, op.acc.5
KMSGestión de claves de cifradoCRÍTICAmp.cryp.1, op.exp.11
CloudWatchMonitorización y logsALTAop.mon.2, op.exp.8
LambdaProcesamiento serverlessMEDIAop.exp.2, mp.sw.2
API GatewayGestión de APIsALTAmp.com.2, op.acc.7
Secrets ManagerGestión de secretosCRÍTICAmp.cryp.2, op.exp.11

2. Modelo de Responsabilidad Compartida​

2.1 Matriz de Responsabilidades AWS vs Legit Health​

Shared_Responsibility_Matrix:
AWS_Responsibilities:
Infrastructure:
- Physical security of data centers
- Hardware and network maintenance
- Hypervisor security
- Global infrastructure availability

Managed_Services:
- RDS patching and backups
- S3 durability and availability
- KMS key management infrastructure
- CloudFront edge locations

Legit_Health_Responsibilities:
Data_Protection:
- Data classification and handling
- Encryption key management
- Access control policies
- Data retention and deletion

Application_Security:
- Application code security
- Container image security
- API security
- Identity and access management

Compliance:
- Medical device regulations (MDR, FDA)
- Data privacy (GDPR, HIPAA)
- Security standards (ENS, ISO 27001)
- Audit and monitoring

2.2 Controles Específicos por Capa​

CapaResponsableControles Implementados
DatosLegit HealthCifrado AES-256, clasificación, DLP
AplicaciónLegit HealthSAST, DAST, dependency scanning
Sistema OperativoCompartidoHardening, patching automático
RedCompartidoSecurity groups, NACLs, WAF
VirtualizaciónAWSAislamiento, hypervisor security
HardwareAWSHSM, secure disposal, physical security
InstalacionesAWSBiometrics, CCTV, 24/7 security

3. Gestión de Identidades y Accesos Cloud (IAM)​

3.1 Estrategia IAM Multinivel​

class AWSIAMStrategy:
def __init__(self):
self.identity_providers = {
'primary': 'Azure AD B2C', # For healthcare professionals
'secondary': 'AWS Cognito', # For patients
'administrative': 'AWS SSO' # For internal staff
}

self.permission_boundaries = {
'production': 'arn:aws:iam::PROD:policy/ProductionBoundary',
'staging': 'arn:aws:iam::STAGE:policy/StagingBoundary',
'development': 'arn:aws:iam::DEV:policy/DevelopmentBoundary'
}

def enforce_least_privilege(self, role_name, permissions_needed):
"""Implementa principio de menor privilegio"""
policy = {
'Version': '2012-10-17',
'Statement': []
}

for permission in permissions_needed:
policy['Statement'].append({
'Effect': 'Allow',
'Action': permission['actions'],
'Resource': permission['resources'],
'Condition': self.add_security_conditions(permission)
})

return policy

def add_security_conditions(self, permission):
"""Añade condiciones de seguridad obligatorias"""
return {
'IpAddress': {
'aws:SourceIp': ['10.0.0.0/8'] # Solo desde VPC
},
'Bool': {
'aws:SecureTransport': 'true' # Solo HTTPS
},
'StringEquals': {
'aws:PrincipalTag/Environment': permission.get('environment', 'production'),
'aws:PrincipalTag/DataClassification': permission.get('data_class', 'sensitive')
}
}

3.2 Roles y Políticas Críticas​

RolPermisosCondicionesMFA Requerido
MedicalDataProcessorS3:GetObject (medical images)IP whitelist, time windowSí
ClinicalAdminRDS:DescribeDBInstancesVPC only, tagged resourcesSí
SecurityAuditorRead-only all servicesCloudTrail enabledSí
IncidentResponderFull access (emergency)Break-glass procedureSí
DataScientistSageMaker, S3 (anonymized)Dev environment onlySí

4. Cifrado y Protección de Datos​

4.1 Estrategia de Cifrado Multicapa​

Encryption_Strategy:
Data_at_Rest:
S3_Medical_Images:
algorithm: "AES-256"
key_management: "AWS KMS CMK"
key_rotation: "Annual"
bucket_policy: "Deny unencrypted uploads"

RDS_Clinical_Data:
algorithm: "AES-256"
encryption_type: "AWS RDS encryption"
key_management: "AWS KMS CMK"
backup_encryption: "Enabled"

EBS_Volumes:
algorithm: "AES-256"
encryption_type: "EBS encryption"
default_encryption: "Enabled account-wide"

Data_in_Transit:
API_Communications:
protocol: "TLS 1.3"
cipher_suites: "ECDHE-RSA-AES256-GCM-SHA384"
certificate: "AWS Certificate Manager"
hsts: "Enabled (max-age=31536000)"

Internal_Communications:
vpc_encryption: "AWS PrivateLink"
service_mesh: "AWS App Mesh with mTLS"
database_connections: "SSL/TLS required"

Key_Management:
Master_Keys:
type: "Customer Managed CMK"
rotation: "Automatic annual"
multi_region: "Replicated to DR region"

Data_Keys:
generation: "On-demand from CMK"
caching: "5 minutes max"
audit: "CloudTrail logging all operations"

4.2 Data Loss Prevention (DLP)​

class CloudDLPControls:
def __init__(self):
self.sensitive_patterns = [
r'\d{9}', # Spanish DNI
r'\d{16}', # Credit card
r'[A-Z]{1,2}\d{6}', # NHS number
r'\b\d{3}-\d{2}-\d{4}\b' # SSN
]

self.classification_levels = {
'public': 0,
'internal': 1,
'confidential': 2,
'medical': 3,
'critical': 4
}

def scan_s3_upload(self, bucket, key, content):
"""Escanea contenido antes de subir a S3"""
classification = self.classify_content(content)

if classification >= self.classification_levels['medical']:
# Requiere cifrado adicional
return self.encrypt_medical_data(content)

if self.contains_sensitive_data(content):
# Bloquea o redacta información sensible
return self.redact_sensitive_info(content)

return content

def enforce_bucket_policies(self, bucket_name):
"""Aplica políticas de bucket según clasificación"""
return {
'Version': '2012-10-17',
'Statement': [{
'Sid': 'DenyUnencryptedObjectUploads',
'Effect': 'Deny',
'Principal': '*',
'Action': 's3:PutObject',
'Resource': f'arn:aws:s3:::{bucket_name}/*',
'Condition': {
'StringNotEquals': {
's3:x-amz-server-side-encryption': 'aws:kms'
}
}
}]
}

5. Seguridad de Red y Perímetro​

5.1 Arquitectura de Seguridad en Profundidad​

Network_Security_Layers:
Edge_Protection:
CloudFront:
- AWS Shield Standard (DDoS protection)
- AWS WAF (Application firewall)
- Origin Access Identity (S3 protection)
- Geo-restriction (EU only)

Route53:
- DNSSEC enabled
- DDoS protection
- Health checks with failover

Perimeter_Security:
Internet_Gateway:
- Restricted security groups
- Network ACLs (stateless rules)
- Flow logs enabled

NAT_Gateway:
- Outbound only for private subnets
- Fixed Elastic IPs
- CloudWatch monitoring

Internal_Segmentation:
Security_Groups:
medical_app_sg:
inbound:
- port: 443
source: "alb_sg"
- port: 5432
source: "app_sg"
outbound:
- port: 443
destination: "0.0.0.0/0"

Network_ACLs:
private_subnet_nacl:
inbound:
- rule: 100
protocol: tcp
port: 443
source: "10.0.0.0/16"
action: ALLOW
- rule: 200
protocol: tcp
port: 5432
source: "10.0.1.0/24"
action: ALLOW
- rule: 32767
protocol: all
port: all
source: "0.0.0.0/0"
action: DENY

5.2 AWS WAF Rules para Dispositivo Médico​

{
"WebACL": {
"Name": "LegitHealthMedicalDeviceWAF",
"DefaultAction": "BLOCK",
"Rules": [
{
"Name": "RateLimitAPI",
"Priority": 1,
"Statement": {
"RateBasedStatement": {
"Limit": 2000,
"AggregateKeyType": "IP"
}
},
"Action": "BLOCK"
},
{
"Name": "SQLInjectionProtection",
"Priority": 2,
"Statement": {
"SqliMatchStatement": {
"FieldToMatch": { "AllQueryArguments": {} },
"TextTransformations": [{ "Priority": 0, "Type": "URL_DECODE" }]
}
},
"Action": "BLOCK"
},
{
"Name": "MedicalAPIAccess",
"Priority": 3,
"Statement": {
"ByteMatchStatement": {
"SearchString": "/api/v1/medical/",
"FieldToMatch": { "UriPath": {} },
"TextTransformations": [{ "Priority": 0, "Type": "LOWERCASE" }],
"PositionalConstraint": "STARTS_WITH"
}
},
"Action": "ALLOW"
},
{
"Name": "GeoBlockingNonEU",
"Priority": 4,
"Statement": {
"NotStatement": {
"Statement": {
"GeoMatchStatement": {
"CountryCodes": ["ES", "FR", "DE", "IT", "PT", "NL", "BE"]
}
}
}
},
"Action": "BLOCK"
}
]
}
}

6. Monitorización y Auditoría Cloud​

6.1 Stack de Observabilidad Cloud-Native​

Observability_Stack:
CloudTrail:
configuration:
- multi_region_trail: true
- log_file_validation: true
- event_selectors:
- read_write_type: "All"
- include_management_events: true
- data_resources:
- type: "AWS::S3::Object"
values: ["arn:aws:s3:::medical-images/*"]
- type: "AWS::RDS::DBCluster"
values: ["arn:aws:rds:*:*:cluster:*"]

integration:
- cloudwatch_logs: true
- s3_bucket: "audit-trail-medical-device"
- sns_notification: true
- encryption: "KMS CMK"

CloudWatch:
Metrics:
custom_namespaces:
- "LegitHealth/Medical"
- "LegitHealth/Security"
- "LegitHealth/Compliance"

critical_metrics:
- api_latency_p99
- error_rate
- authentication_failures
- data_access_anomalies

Logs:
log_groups:
- "/aws/ecs/medical-app"
- "/aws/rds/clinical-db"
- "/aws/lambda/image-processor"

retention: 2555 # 7 years for medical device
encryption: "KMS CMK"

Alarms:
high_priority:
- unauthorized_api_calls
- root_account_usage
- config_changes
- security_group_changes

AWS_Config:
rules:
- s3-bucket-public-read-prohibited
- rds-encryption-enabled
- iam-password-policy
- mfa-enabled-for-iam-console-access
- cloudtrail-enabled

remediation:
automatic: true
notification: "security-team@legithealth.com"

6.2 Security Information and Event Management (SIEM)​

class CloudSIEMIntegration:
def __init__(self):
self.event_sources = [
'CloudTrail',
'VPC Flow Logs',
'CloudWatch Logs',
'GuardDuty',
'Security Hub',
'Access Analyzer'
]

self.correlation_rules = self.load_correlation_rules()
self.threat_intelligence = self.load_threat_feeds()

def process_security_event(self, event):
"""Procesa eventos de seguridad del cloud"""
enriched_event = self.enrich_event(event)
risk_score = self.calculate_risk_score(enriched_event)

if risk_score > 80:
self.trigger_incident_response(enriched_event)
elif risk_score > 60:
self.create_security_alert(enriched_event)

# Almacenar para análisis forense
self.store_security_event(enriched_event)

return {
'event_id': enriched_event['id'],
'risk_score': risk_score,
'actions_taken': self.get_automated_responses(risk_score)
}

def detect_anomalies(self, time_window='1h'):
"""Detecta anomalías en comportamiento cloud"""
anomalies = []

# Análisis de patrones de acceso
access_patterns = self.analyze_access_patterns(time_window)
if access_patterns['deviation'] > 3: # 3 desviaciones estándar
anomalies.append({
'type': 'unusual_access_pattern',
'severity': 'high',
'details': access_patterns
})

# Análisis de uso de recursos
resource_usage = self.analyze_resource_usage(time_window)
if resource_usage['spike_detected']:
anomalies.append({
'type': 'resource_usage_spike',
'severity': 'medium',
'details': resource_usage
})

return anomalies

7. Gestión de Incidentes Cloud​

7.1 Procedimiento de Respuesta a Incidentes AWS​

Incident_Response_Procedure:
Detection:
automated_sources:
- GuardDuty findings
- Security Hub alerts
- CloudWatch alarms
- Custom Lambda detections

manual_sources:
- User reports
- Security reviews
- Penetration testing

Triage:
severity_levels:
critical:
- Data breach detected
- Ransomware indicators
- Admin credential compromise
response_time: "< 15 minutes"

high:
- Suspicious API activity
- Unusual data access
- Failed authentication spikes
response_time: "< 1 hour"

medium:
- Configuration drift
- Policy violations
- Resource misuse
response_time: "< 4 hours"

Containment:
automated_actions:
- Isolate compromised instances
- Revoke suspicious credentials
- Block malicious IPs
- Snapshot affected resources

manual_actions:
- Review CloudTrail logs
- Analyze VPC Flow Logs
- Forensic image creation
- Legal team notification

Eradication:
steps:
- Remove malicious artifacts
- Patch vulnerabilities
- Reset compromised credentials
- Update security groups

Recovery:
validation:
- System integrity checks
- Security scanning
- Functionality testing
- Performance validation

restoration:
- Gradual service restoration
- Monitor for recurrence
- User communication

Lessons_Learned:
documentation:
- Incident timeline
- Root cause analysis
- Effectiveness of response
- Improvement recommendations

7.2 Automatización de Respuesta con Lambda​

import boto3
import json
from datetime import datetime

class AutomatedIncidentResponse:
def __init__(self):
self.ec2 = boto3.client('ec2')
self.iam = boto3.client('iam')
self.sns = boto3.client('sns')
self.s3 = boto3.client('s3')

def lambda_handler(self, event, context):
"""Lambda function para respuesta automática a incidentes"""
incident_type = event['detail']['type']

response_actions = {
'unauthorized_api_call': self.handle_unauthorized_api,
'suspicious_instance': self.isolate_instance,
'credential_compromise': self.revoke_credentials,
'data_exfiltration': self.block_data_transfer
}

if incident_type in response_actions:
result = response_actions[incident_type](event)
self.notify_security_team(incident_type, result)
self.create_forensic_snapshot(event)

return {
'statusCode': 200,
'body': json.dumps({
'incident_id': event['id'],
'actions_taken': result,
'timestamp': datetime.utcnow().isoformat()
})
}

return {
'statusCode': 400,
'body': json.dumps('Unknown incident type')
}

def isolate_instance(self, event):
"""Aísla instancia comprometida"""
instance_id = event['detail']['instance_id']

# Crear security group de aislamiento
isolation_sg = self.ec2.create_security_group(
GroupName=f'isolation-{instance_id}',
Description='Isolation security group for incident response'
)

# Aplicar security group restrictivo
self.ec2.modify_instance_attribute(
InstanceId=instance_id,
Groups=[isolation_sg['GroupId']]
)

# Crear snapshot para análisis forense
self.create_instance_snapshot(instance_id)

return {
'action': 'instance_isolated',
'instance_id': instance_id,
'isolation_sg': isolation_sg['GroupId']
}

8. Continuidad de Negocio y Disaster Recovery​

8.1 Estrategia Multi-Región​

Disaster_Recovery_Strategy:
Architecture:
Primary_Region: eu-west-1
DR_Region: eu-central-1

Replication:
Database:
type: "RDS Cross-Region Read Replica"
rpo: "5 minutes"
rto: "30 minutes"

Storage:
type: "S3 Cross-Region Replication"
rpo: "15 minutes"
rto: "5 minutes"

Application:
type: "ECS Blue-Green Deployment"
rpo: "0 minutes"
rto: "15 minutes"

Backup_Strategy:
Automated_Backups:
RDS:
frequency: "Daily"
retention: "35 days"
window: "03:00-04:00 UTC"

S3:
versioning: "Enabled"
lifecycle: "90 days to Glacier"
mfa_delete: "Enabled"

Secrets:
rotation: "90 days"
versioning: "Last 5 versions"

Testing:
DR_Drills:
frequency: "Quarterly"
scope: "Full failover test"
duration: "4 hours"

Backup_Restoration:
frequency: "Monthly"
scope: "Random sample restoration"
validation: "Data integrity check"

8.2 Automatización de Failover​

class DisasterRecoveryAutomation:
def __init__(self):
self.route53 = boto3.client('route53')
self.rds = boto3.client('rds')
self.ecs = boto3.client('ecs')

def initiate_failover(self, reason, authorized_by):
"""Inicia failover a región DR"""
failover_plan = {
'timestamp': datetime.utcnow().isoformat(),
'reason': reason,
'authorized_by': authorized_by,
'steps': []
}

# 1. Promover Read Replica a Primary
db_promotion = self.promote_read_replica()
failover_plan['steps'].append(db_promotion)

# 2. Actualizar DNS para apuntar a DR
dns_update = self.update_route53_records()
failover_plan['steps'].append(dns_update)

# 3. Escalar servicios en DR región
service_scaling = self.scale_dr_services()
failover_plan['steps'].append(service_scaling)

# 4. Verificar health checks
health_status = self.verify_dr_health()
failover_plan['steps'].append(health_status)

# 5. Notificar a stakeholders
self.notify_failover_complete(failover_plan)

return failover_plan

9. Compliance y Auditoría Cloud​

9.1 Controles de Cumplimiento Automatizados​

Compliance_Automation:
AWS_Config_Rules:
Medical_Device_Compliance:
- rule: "medical-s3-encryption-required"
description: "All medical data must be encrypted"
remediation: "Auto-encrypt with KMS"

- rule: "medical-rds-backup-enabled"
description: "Database backups required"
remediation: "Enable automated backups"

- rule: "medical-cloudtrail-enabled"
description: "Audit logging mandatory"
remediation: "Enable CloudTrail with validation"

- rule: "medical-mfa-required"
description: "MFA for all privileged users"
remediation: "Block access until MFA enabled"

Security_Hub:
Standards:
- "AWS Foundational Security Best Practices"
- "CIS AWS Foundations Benchmark"
- "PCI DSS"
- "HIPAA"

Custom_Controls:
- control_id: "MED-001"
title: "Medical Image Encryption"
description: "Verify all medical images are encrypted"
severity: "CRITICAL"

- control_id: "MED-002"
title: "Clinical Data Access Logging"
description: "All clinical data access must be logged"
severity: "HIGH"

Automated_Reporting:
ENS_Compliance_Report:
frequency: "Monthly"
format: "PDF + JSON"
recipients: ["compliance@legithealth.com", "ciso@legithealth.com"]

Medical_Device_Audit:
frequency: "Quarterly"
scope: "Full infrastructure scan"
retention: "7 years"

9.2 Evidencia de Cumplimiento​

class ComplianceEvidenceCollector:
def __init__(self):
self.config = boto3.client('config')
self.securityhub = boto3.client('securityhub')

def generate_ens_compliance_report(self):
"""Genera reporte de cumplimiento ENS"""
report = {
'report_date': datetime.utcnow().isoformat(),
'system': 'Legit Health Plus',
'category': 'MEDIA',
'dimensions': {
'confidentiality': 'MEDIA',
'integrity': 'ALTA',
'availability': 'MEDIA',
'authenticity': 'ALTA',
'traceability': 'ALTA'
},
'controls': {}
}

# Verificar controles ENS
ens_controls = self.get_ens_control_mappings()

for control_id, aws_rules in ens_controls.items():
compliance_status = self.check_aws_config_compliance(aws_rules)
report['controls'][control_id] = {
'status': compliance_status['status'],
'evidence': compliance_status['evidence'],
'last_evaluated': compliance_status['timestamp']
}

# Añadir findings de Security Hub
security_findings = self.get_security_hub_findings()
report['security_findings'] = security_findings

# Generar score de cumplimiento
report['compliance_score'] = self.calculate_compliance_score(report)

return report

10. Gestión de Costes y Optimización​

10.1 FinOps para Dispositivo Médico​

Cost_Management:
Budgets:
Production:
monthly_limit: 50000
alerts: [50%, 80%, 100%, 120%]

Development:
monthly_limit: 10000
alerts: [80%, 100%]

Compliance_Reserve:
annual: 100000
purpose: "Audits, certifications, remediation"

Optimization_Strategies:
Reserved_Instances:
coverage_target: 80%
term: "1 year"
payment: "Partial upfront"

Savings_Plans:
compute_commitment: 30000/month
term: "1 year"

Spot_Instances:
workloads: ["batch processing", "development", "testing"]
interruption_behavior: "terminate"

S3_Lifecycle:
medical_images:
- "0-30 days: S3 Standard"
- "31-90 days: S3 IA"
- "91-365 days: S3 Glacier"
- "365+ days: Glacier Deep Archive"

Cost_Allocation:
Tags:
- Environment: [Production, Staging, Development]
- Department: [Engineering, Clinical, Compliance]
- Project: [AI-Model, Infrastructure, Security]
- Compliance: [ENS, MDR, HIPAA]

11. Integración con Servicios de Seguridad AWS​

11.1 AWS GuardDuty para Detección de Amenazas​

GuardDuty_Configuration:
Threat_Detection:
enabled: true
finding_publishing_frequency: "15 minutes"

Detectors:
- instance_reconnaissance
- malicious_ip_communication
- cryptocurrency_mining
- credential_access
- data_exfiltration

Threat_Intel_Feeds:
- AWS managed feeds
- Custom medical device IoCs
- Healthcare sector threat intelligence

Suppression_Rules:
- name: "Known vulnerability scanners"
filter: "service.action.portProbeAction.portProbeDetails.remoteIpDetails.organization.org == 'Security Vendor'"

- name: "Authorized penetration testing"
filter: "resource.instanceDetails.tags.key == 'PenTest' AND resource.instanceDetails.tags.value == 'Authorized'"

Response_Automation:
High_Severity:
- Create Security Hub finding
- Trigger Lambda response function
- Send to SIEM
- Page on-call security

Medium_Severity:
- Create Security Hub finding
- Send to SIEM
- Email security team

Low_Severity:
- Log to CloudWatch
- Weekly summary report

11.2 AWS Security Hub Centralizado​

class SecurityHubIntegration:
def __init__(self):
self.securityhub = boto3.client('securityhub')
self.organizations = boto3.client('organizations')

def configure_medical_device_standards(self):
"""Configura estándares específicos para dispositivo médico"""
standards = [
{
'StandardsArn': 'arn:aws:securityhub:eu-west-1::standards/aws-foundational-security-best-practices/v/1.0.0',
'DisabledControls': [] # Todos los controles habilitados
},
{
'StandardsArn': 'arn:aws:securityhub:eu-west-1::standards/cis-aws-foundations-benchmark/v/1.4.0',
'DisabledControls': ['CIS.2.8'] # Excepción documentada
},
{
'StandardsArn': 'arn:aws:securityhub:eu-west-1::standards/pci-dss/v/3.2.1',
'DisabledControls': ['PCI.DSS.3.4'] # No aplicable
}
]

for standard in standards:
self.securityhub.batch_enable_standards(
StandardsSubscriptionRequests=[standard]
)

# Configurar controles personalizados
self.create_custom_medical_controls()

def create_custom_medical_controls(self):
"""Crea controles personalizados para cumplimiento médico"""
custom_controls = [
{
'Title': 'Medical Data Encryption at Rest',
'Description': 'Verify all medical data is encrypted using KMS CMK',
'ProductArn': 'arn:aws:securityhub:eu-west-1:account:product/account/default',
'GeneratorId': 'medical-encryption-check',
'Severity': {'Label': 'CRITICAL'},
'Types': ['Software and Configuration Checks/Industry and Regulatory Standards/Healthcare'],
'Compliance': {'Status': 'PASSED'}
},
{
'Title': 'Clinical API Rate Limiting',
'Description': 'Ensure API Gateway has rate limiting configured',
'ProductArn': 'arn:aws:securityhub:eu-west-1:account:product/account/default',
'GeneratorId': 'api-rate-limit-check',
'Severity': {'Label': 'HIGH'},
'Types': ['Software and Configuration Checks/AWS Security Best Practices'],
'Compliance': {'Status': 'PASSED'}
}
]

for control in custom_controls:
self.securityhub.batch_import_findings(Findings=[control])

12. Gestión de Vulnerabilidades Cloud​

12.1 Scanning Continuo de Infraestructura​

Vulnerability_Management:
Container_Scanning:
ECR_Scanning:
scan_on_push: true
scan_frequency: "daily"

Severity_Thresholds:
critical: "Block deployment"
high: "Alert and review"
medium: "Track for remediation"
low: "Monthly review"

Runtime_Scanning:
tool: "AWS Inspector"
frequency: "continuous"
coverage: "all production containers"

Infrastructure_Scanning:
AWS_Inspector:
assessment_templates:
- "Network Reachability"
- "Security Best Practices"
- "CVE scanning"
- "CIS Benchmarks"

schedule: "weekly"
scope: "all EC2 instances and containers"

Third_Party_Tools:
- tool: "Qualys VMDR"
integration: "AWS Connector"
frequency: "daily"

- tool: "Tenable.io"
integration: "API"
frequency: "continuous"

Patch_Management:
Automated_Patching:
OS_patches:
tool: "AWS Systems Manager Patch Manager"
maintenance_window: "Sunday 02:00-06:00 UTC"
approval_delay: "7 days for production"

Application_patches:
process: "CI/CD pipeline with security gates"
testing: "Automated regression + security tests"

Emergency_Patches:
critical_vulnerabilities:
sla: "24 hours"
approval: "CISO or delegate"
testing: "Expedited security validation"

13. Gestión de Secretos y Credenciales​

13.1 AWS Secrets Manager Integration​

class SecretsManagement:
def __init__(self):
self.secrets_manager = boto3.client('secretsmanager')
self.kms = boto3.client('kms')

def create_medical_app_secret(self, secret_name, secret_value, tags):
"""Crea secreto con políticas de dispositivo médico"""
# Crear política de recursos restrictiva
resource_policy = {
'Version': '2012-10-17',
'Statement': [
{
'Effect': 'Deny',
'Principal': '*',
'Action': 'secretsmanager:GetSecretValue',
'Resource': '*',
'Condition': {
'StringNotEquals': {
'aws:PrincipalTag/Environment': 'Production',
'aws:PrincipalTag/Authorized': 'True'
}
}
}
]
}

response = self.secrets_manager.create_secret(
Name=secret_name,
Description='Medical application secret - regulated data',
KmsKeyId='arn:aws:kms:eu-west-1:account:key/medical-cmk',
SecretString=json.dumps(secret_value),
Tags=tags + [
{'Key': 'Compliance', 'Value': 'MDR'},
{'Key': 'DataClassification', 'Value': 'Confidential'},
{'Key': 'Rotation', 'Value': 'Enabled'}
]
)

# Configurar rotación automática
self.configure_rotation(response['ARN'])

return response

def configure_rotation(self, secret_arn):
"""Configura rotación automática de secretos"""
self.secrets_manager.rotate_secret(
SecretId=secret_arn,
RotationLambdaArn='arn:aws:lambda:eu-west-1:account:function:secret-rotation',
RotationRules={
'AutomaticallyAfterDays': 90
}
)

14. Referencias Cruzadas y Trazabilidad​

14.1 Mapeo de Controles Cloud a Requisitos​

Control ENSServicio AWSConfiguraciónEvidencia
mp.com.1CloudFront + WAFTLS 1.3, WAF rulesCloudWatch Logs
mp.com.2VPC + Security GroupsNetwork segmentationVPC Flow Logs
mp.cryp.1KMSCMK con rotación anualCloudTrail
mp.info.3S3 + EncryptionSSE-KMSS3 Access Logs
op.acc.1IAM + CognitoMFA obligatorioCloudTrail
op.exp.8CloudWatch Logs7 años retenciónLog Groups
op.mon.1GuardDutyThreat detection activoFindings
op.cont.2Multi-region DRRTO < 4h, RPO < 15mDR tests

14.2 Integración con Sistema de Gestión de Riesgos​

Risk_Integration:
Cloud_Specific_Risks:
- risk_id: "R-CLD-001"
description: "AWS service outage affecting availability"
controls: ["Multi-region deployment", "DR procedures"]
references: ["OP.CONT.2", "OP.CONT.4"]

- risk_id: "R-CLD-002"
description: "Data breach through misconfigured S3 bucket"
controls: ["S3 Block Public Access", "Bucket policies"]
references: ["MP.INFO.3", "OP.ACC.2"]

- risk_id: "R-CLD-003"
description: "Unauthorized access to medical data"
controls: ["IAM policies", "MFA", "CloudTrail logging"]
references: ["OP.ACC.1", "OP.ACC.5", "OP.EXP.8"]

Threat_Model_References:
- "T-024-006-CLD-001: Cloud service compromise"
- "T-024-006-CLD-002: Insider threat in cloud environment"
- "T-024-006-CLD-003: Supply chain attack via cloud services"
- "T-024-006-CLD-004: Data residency violations"

15. Procedimientos Operativos Cloud​

15.1 Gestión de Cambios en Infraestructura Cloud​

Change_Management_Process:
Infrastructure_as_Code:
Version_Control:
repository: "github.com/legithealth/infrastructure"
branching: "GitFlow"
protection: "Main branch protected, require reviews"

Terraform_Workflow:
1_Plan:
- terraform plan
- security scanning (tfsec, checkov)
- cost estimation
- compliance check

2_Review:
- peer review required
- security team approval for critical resources
- change advisory board for production

3_Apply:
- terraform apply with approval
- automated testing
- monitoring validation

4_Validation:
- health checks
- security validation
- rollback plan ready

Change_Windows:
Production:
regular: "Sunday 02:00-06:00 UTC"
emergency: "With CISO approval"

Staging:
regular: "Daily 22:00-02:00 UTC"

Development:
regular: "No restrictions"

15.2 Runbooks de Operación Cloud​

# Runbook: Escalado de emergencia
class EmergencyScalingRunbook:
def __init__(self):
self.ecs = boto3.client('ecs')
self.autoscaling = boto3.client('application-autoscaling')
self.cloudwatch = boto3.client('cloudwatch')

def execute_emergency_scaling(self, service_name, scale_factor=2):
"""
Runbook para escalado de emergencia de servicios médicos

Trigger: CPU > 90% or Response Time > 2s for 5 minutes
"""
steps = []

# Step 1: Verificar estado actual
current_state = self.get_service_state(service_name)
steps.append({
'step': 'verify_current_state',
'status': 'completed',
'details': current_state
})

# Step 2: Escalar inmediatamente
scale_result = self.scale_service(
service_name,
current_state['desired_count'] * scale_factor
)
steps.append({
'step': 'immediate_scaling',
'status': 'completed',
'details': scale_result
})

# Step 3: Ajustar auto-scaling
autoscale_result = self.adjust_autoscaling_policy(
service_name,
scale_factor
)
steps.append({
'step': 'adjust_autoscaling',
'status': 'completed',
'details': autoscale_result
})

# Step 4: Notificar
self.notify_stakeholders({
'action': 'emergency_scaling',
'service': service_name,
'factor': scale_factor,
'timestamp': datetime.utcnow().isoformat()
})

# Step 5: Monitorizar
self.create_enhanced_monitoring(service_name)

return {
'runbook': 'emergency_scaling',
'execution_time': datetime.utcnow().isoformat(),
'steps': steps,
'status': 'completed'
}

16. Formación y Concienciación Cloud Security​

16.1 Programa de Formación​

Cloud_Security_Training:
Onboarding:
New_Developers:
- AWS Security Fundamentals
- Shared Responsibility Model
- IAM Best Practices
- Secure Coding for Cloud
duration: "16 hours"

New_Operations:
- AWS Well-Architected Framework
- Security Monitoring and Incident Response
- Compliance and Audit
- Cost Optimization
duration: "24 hours"

Continuous_Education:
Monthly_Security_Briefing:
topics:
- Latest threats and vulnerabilities
- New AWS security features
- Lessons learned from incidents
- Compliance updates

Quarterly_Workshops:
- Hands-on security labs
- Incident response simulations
- Architecture reviews
- Tool training

Certifications:
Required:
- AWS Certified Cloud Practitioner (all staff)
- AWS Certified Security - Specialty (security team)

Recommended:
- AWS Certified Solutions Architect
- AWS Certified DevOps Engineer
- AWS Certified Database Specialty

17. Métricas y KPIs de Seguridad Cloud​

17.1 Dashboard de Seguridad Cloud​

MétricaTargetCurrentTrendStatus
Compliance Score> 95%97.2%↑✅
Unencrypted Resources00→✅
Public S3 Buckets00→✅
MFA Coverage100%100%→✅
Patch Compliance> 98%99.1%↑✅
Security Findings (High)< 53↓✅
MTTR (Incidents)< 4h2.3h↓✅
Failed Auth Attempts< 100/day67/day↓✅
API Rate Limit Hits< 50/day23/day↓✅
Cost Optimization> 20%23%↑✅

18. Anexos​

Anexo A: Checklist de Seguridad Cloud​

  • Todos los recursos etiquetados correctamente
  • MFA habilitado para todos los usuarios
  • CloudTrail activo en todas las regiones
  • S3 Block Public Access habilitado
  • VPC Flow Logs activos
  • GuardDuty habilitado
  • Security Hub configurado
  • Config Rules activas
  • Secrets rotados < 90 días
  • Backups verificados < 30 días
  • DR test < 90 días
  • Pentest < 12 meses

Anexo B: Contactos de Emergencia AWS​

Emergency_Contacts:
AWS_Support:
tier: "Enterprise"
phone: "+1-800-xxx-xxxx"
priority: "Business Critical"

AWS_Security:
abuse: "abuse@amazonaws.com"
incident: "Via Support Console"

Internal_Escalation:
L1: "oncall-sre@legithealth.com"
L2: "security-team@legithealth.com"
L3: "ciso@legithealth.com"
Executive: "cto@legithealth.com"

Signature meaning

The signatures for the approval process of this document can be found in the verified commits at the repository for the QMS. As a reference, the team members who are expected to participate in this document and their roles in the approval process, as defined in Annex I Responsibility Matrix of the GP-001, are:

  • Author: Team members involved
  • Reviewer: JD-003, JD-004
  • Approver: JD-001
Previous
OP.NUB Servicios en la nube
Next
OP.CONT Continuidad del servicio
  • OP.NUB.1 Protección de servicios en la nube
    • Documentos de referencia
    • Guía de implantación
  • Implementación en Legit Health Plus
    • 1. Arquitectura Cloud de Legit Health Plus
      • 1.1 Visión General de la Infraestructura AWS
      • 1.2 Servicios AWS Críticos Utilizados
    • 2. Modelo de Responsabilidad Compartida
      • 2.1 Matriz de Responsabilidades AWS vs Legit Health
      • 2.2 Controles Específicos por Capa
    • 3. Gestión de Identidades y Accesos Cloud (IAM)
      • 3.1 Estrategia IAM Multinivel
      • 3.2 Roles y Políticas Críticas
    • 4. Cifrado y Protección de Datos
      • 4.1 Estrategia de Cifrado Multicapa
      • 4.2 Data Loss Prevention (DLP)
    • 5. Seguridad de Red y Perímetro
      • 5.1 Arquitectura de Seguridad en Profundidad
      • 5.2 AWS WAF Rules para Dispositivo Médico
    • 6. Monitorización y Auditoría Cloud
      • 6.1 Stack de Observabilidad Cloud-Native
      • 6.2 Security Information and Event Management (SIEM)
    • 7. Gestión de Incidentes Cloud
      • 7.1 Procedimiento de Respuesta a Incidentes AWS
      • 7.2 Automatización de Respuesta con Lambda
    • 8. Continuidad de Negocio y Disaster Recovery
      • 8.1 Estrategia Multi-Región
      • 8.2 Automatización de Failover
    • 9. Compliance y Auditoría Cloud
      • 9.1 Controles de Cumplimiento Automatizados
      • 9.2 Evidencia de Cumplimiento
    • 10. Gestión de Costes y Optimización
      • 10.1 FinOps para Dispositivo Médico
    • 11. Integración con Servicios de Seguridad AWS
      • 11.1 AWS GuardDuty para Detección de Amenazas
      • 11.2 AWS Security Hub Centralizado
    • 12. Gestión de Vulnerabilidades Cloud
      • 12.1 Scanning Continuo de Infraestructura
    • 13. Gestión de Secretos y Credenciales
      • 13.1 AWS Secrets Manager Integration
    • 14. Referencias Cruzadas y Trazabilidad
      • 14.1 Mapeo de Controles Cloud a Requisitos
      • 14.2 Integración con Sistema de Gestión de Riesgos
    • 15. Procedimientos Operativos Cloud
      • 15.1 Gestión de Cambios en Infraestructura Cloud
      • 15.2 Runbooks de Operación Cloud
    • 16. Formación y Concienciación Cloud Security
      • 16.1 Programa de Formación
    • 17. Métricas y KPIs de Seguridad Cloud
      • 17.1 Dashboard de Seguridad Cloud
    • 18. Anexos
      • Anexo A: Checklist de Seguridad Cloud
      • Anexo B: Contactos de Emergencia AWS
All the information contained in this QMS is confidential. The recipient agrees not to transmit or reproduce the information, neither by himself nor by third parties, through whichever means, without obtaining the prior written permission of Legit.Health (AI LABS GROUP S.L.)