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
- 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 AWS | Función | Criticidad | Controles ENS Aplicados |
---|---|---|---|
ECS Fargate | Contenedores de aplicación | CRÍTICA | mp.sw.1, op.exp.2 |
RDS PostgreSQL | Base de datos clínica | CRÍTICA | mp.info.3, op.exp.11 |
S3 | Almacenamiento de imágenes médicas | CRÍTICA | mp.info.4, mp.si.2 |
CloudFront | CDN y protección DDoS | ALTA | mp.com.1, op.mon.1 |
Cognito | Gestión de identidades | CRÍTICA | op.acc.1, op.acc.5 |
KMS | Gestión de claves de cifrado | CRÍTICA | mp.cryp.1, op.exp.11 |
CloudWatch | Monitorización y logs | ALTA | op.mon.2, op.exp.8 |
Lambda | Procesamiento serverless | MEDIA | op.exp.2, mp.sw.2 |
API Gateway | Gestión de APIs | ALTA | mp.com.2, op.acc.7 |
Secrets Manager | Gestión de secretos | CRÍTICA | mp.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
Capa | Responsable | Controles Implementados |
---|---|---|
Datos | Legit Health | Cifrado AES-256, clasificación, DLP |
Aplicación | Legit Health | SAST, DAST, dependency scanning |
Sistema Operativo | Compartido | Hardening, patching automático |
Red | Compartido | Security groups, NACLs, WAF |
Virtualización | AWS | Aislamiento, hypervisor security |
Hardware | AWS | HSM, secure disposal, physical security |
Instalaciones | AWS | Biometrics, 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
Rol | Permisos | Condiciones | MFA Requerido |
---|---|---|---|
MedicalDataProcessor | S3:GetObject (medical images) | IP whitelist, time window | Sí |
ClinicalAdmin | RDS:DescribeDBInstances | VPC only, tagged resources | Sí |
SecurityAuditor | Read-only all services | CloudTrail enabled | Sí |
IncidentResponder | Full access (emergency) | Break-glass procedure | Sí |
DataScientist | SageMaker, S3 (anonymized) | Dev environment only | Sí |
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 ENS | Servicio AWS | Configuración | Evidencia |
---|---|---|---|
mp.com.1 | CloudFront + WAF | TLS 1.3, WAF rules | CloudWatch Logs |
mp.com.2 | VPC + Security Groups | Network segmentation | VPC Flow Logs |
mp.cryp.1 | KMS | CMK con rotación anual | CloudTrail |
mp.info.3 | S3 + Encryption | SSE-KMS | S3 Access Logs |
op.acc.1 | IAM + Cognito | MFA obligatorio | CloudTrail |
op.exp.8 | CloudWatch Logs | 7 años retención | Log Groups |
op.mon.1 | GuardDuty | Threat detection activo | Findings |
op.cont.2 | Multi-region DR | RTO < 4h, RPO < 15m | DR 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étrica | Target | Current | Trend | Status |
---|---|---|---|---|
Compliance Score | > 95% | 97.2% | ↑ | ✅ |
Unencrypted Resources | 0 | 0 | → | ✅ |
Public S3 Buckets | 0 | 0 | → | ✅ |
MFA Coverage | 100% | 100% | → | ✅ |
Patch Compliance | > 98% | 99.1% | ↑ | ✅ |
Security Findings (High) | < 5 | 3 | ↓ | ✅ |
MTTR (Incidents) | < 4h | 2.3h | ↓ | ✅ |
Failed Auth Attempts | < 100/day | 67/day | ↓ | ✅ |
API Rate Limit Hits | < 50/day | 23/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