Problema

En entornos de producción, una aplicación que depende de S3 puede dejar de leer o escribir objetos de forma inesperada. El síntoma típico es un error 403/AccessDenied, 404/NoSuchKey o timeout al intentar acceder a un bucket que funcionaba minutos o horas antes. El problema no está limitado a una cuenta o región; cualquier arquitectura que combine IAM, bucket policies, KMS, VPC endpoints y automatizaciones puede verse afectada. El objetivo es disponer de un proceso de diagnóstico que funcione sin importar cuál sea la causa raíz.

Causa

Los fallos de acceso a S3 suelen derivar de una combinación de configuraciones que cambian con el tiempo:

  1. IAM permissions – una política adjunta al rol/usuario que ejecuta la aplicación se modificó o expiró (por ejemplo, políticas basadas en condiciones de tiempo o de origen).
  2. Bucket policy – reglas explícitas que deniegan accesos desde ciertas VPC, IP o condiciones de MFA pueden haber sido actualizadas.
  3. SCP (Service Control Policy) – en organizaciones con AWS Organizations, un SCP nuevo puede estar bloqueando s3:* para la OU del recurso.
  4. KMS key – si el bucket usa SSE‑KMS y la clave fue deshabilitada, rotada sin actualizar la política de uso, los objetos quedan ilegibles.
  5. VPC endpoint – la eliminación o cambio de un Interface VPC Endpoint para S3 rompe la ruta privada y fuerza el tráfico a internet, donde las políticas de origen pueden fallar.
  6. CloudTrail / Config – una regla de guardia que revoca permisos automáticamente al detectar anomalías puede haber disparado.
  7. Cambios de infraestructura – despliegues de IaC (Terraform, CloudFormation) que sustituyen roles o buckets sin sincronizar permisos.

En la práctica, el 60 % de los incidentes de este tipo se reducen a una combinación de IAM y bucket policy; el resto involucra KMS o VPC endpoints.

Solución

Adoptar un enfoque estructurado permite aislar rápidamente la causa. El proceso se divide en cuatro fases: recolección de datos, validación de identidad, inspección de políticas y pruebas de conectividad.

1. Recolección de datos

  • Identifica el ARN del rol/usuario que la aplicación usa (aws sts get-caller-identity).
  • Anota el nombre del bucket y la clave del objeto que falla.
  • Extrae los últimos eventos de CloudTrail relacionados con s3:GetObject o s3:PutObject para el bucket en cuestión (aws cloudtrail lookup-events).

2. Validación de identidad

Confirma que el principal tiene los permisos esperados:

aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/app-role \
  --action-names s3:GetObject s3:PutObject \
  --resource-arns arn:aws:s3:::my-bucket/* \
  --output text

El simulador muestra si alguna condición (por ejemplo, aws:SourceVpce) está bloqueando la operación. Si el resultado incluye explicitDeny, la causa está en una política superior (SCP o bucket policy).

3. Inspección de políticas

  • Bucket policy: descarga y revisa con aws s3api get-bucket-policy. Busca cláusulas Deny que incluyan aws:SourceVpc o aws:PrincipalArn.
  • IAM policy: revisa las políticas adjuntas al rol/usuario (aws iam list-attached-role-policies). Asegúrate de que no haya condiciones de fecha (aws:CurrentTime) que hayan expirado.
  • SCP: en la consola de Organizations o con aws organizations list-policies, verifica si un SCP nuevo restringe s3:*.

Si encuentras una regla de denegación, corrígela o crea una excepción explícita para el principal.

4. Verificación de KMS y VPC endpoint

  • KMS: ejecuta aws kms describe-key --key-id alias/my-key y revisa KeyState. Si está Disabled o PendingDeletion, habilita la clave o actualiza la política de uso.
  • VPC endpoint: lista los endpoints con aws ec2 describe-vpc-endpoints --filters Name=service-name,Values=*.s3.amazonaws.com. Confirma que el endpoint está en el mismo VPC y que la política del endpoint permite el bucket.

5. Prueba de conectividad directa

Desde una instancia dentro del mismo VPC, intenta acceder al objeto usando la CLI sin variables de entorno que puedan sobrescribir credenciales:

aws s3api get-object --bucket my-bucket --key path/file.txt /tmp/file.txt

Si funciona, el problema está en la capa de autorización; si falla con el mismo error, revisa la ruta de red (endpoint, NAT, firewall).

6. Reversión rápida

En producción, la prioridad es restaurar el acceso. Algunas acciones de mitigación rápida:

  • Adjuntar una política de permiso amplio temporal (AmazonS3FullAccess) al rol, siempre que sea seguro.
  • Crear un bucket policy de “allow all” limitado a la VPC del cliente mientras se investiga.
  • Habilitar la clave KMS en modo Enabled si estaba deshabilitada.

Una vez restablecido el flujo, vuelve a aplicar la política mínima requerida.

Cuándo aplicar esta solución

  • Síntomas: errores 403/AccessDenied, 404/NoSuchKey, o tiempo de espera al acceder a objetos S3 que antes funcionaban.
  • Entorno: cualquier arquitectura que use IAM roles, bucket policies, KMS o VPC endpoints (incluye Lambda, ECS, EKS, EC2).
  • No aplica: problemas de latencia de red sin relación con autorización, o fallos de S3 a nivel de servicio (AWS Service Health Dashboard). En esos casos, la solución pasa por esperar a que AWS restaure el servicio.

Código

# 1. Obtener ARN del rol que ejecuta la app
aws sts get-caller-identity --query Arn --output text

# 2. Simular permisos para GetObject/PutObject
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/app-role \
  --action-names s3:GetObject s3:PutObject \
  --resource-arns arn:aws:s3:::my-bucket/* \
  --output text

# 3. Descargar bucket policy
aws s3api get-bucket-policy --bucket my-bucket --query Policy --output text | jq .

# 4. Verificar estado de la clave KMS
aws kms describe-key --key-id alias/my-key --query KeyMetadata.KeyState --output text

# 5. Listar VPC endpoints para S3
aws ec2 describe-vpc-endpoints \
  --filters Name=service-name,Values=*.s3.amazonaws.com \
  --query "VpcEndpoints[*].{Id:VpcEndpointId,State:State,Policy:PolicyDocument}" \
  --output table

Verificación

  1. Ejecuta aws s3api head-object contra el mismo objeto; un código 200 confirma que la autorización está resuelta.
  2. Revisa CloudTrail: el último evento debe mostrar eventName: GetObject con errorCode: null.
  3. En la consola de S3, abre el objeto y verifica que la vista previa carga sin errores.

Si los tres pasos pasan, el problema está corregido. Mantén la política mínima y elimina cualquier permiso temporal que hayas añadido.

Notas adicionales

  • Auditoría continua: habilita Config Rules para s3-bucket-public-read-prohibited y s3-bucket-server-side-encryption-enabled. Estas reglas alertan antes de que un cambio provoque un bloqueo.
  • Automatiza la simulación: incluye el comando simulate-principal-policy en tus pipelines de CI/CD cada vez que actualices roles o políticas.
  • Evita denegaciones implícitas: recuerda que una política de bucket sin Allow explícito a un principal equivale a denegar.
  • Documenta cambios de infraestructura: registra en el changelog de Terraform cualquier modificación de aws_iam_role, aws_s3_bucket_policy o aws_kms_key.

Con este proceso estructurado, la mayoría de los incidentes de acceso a S3 pueden diagnosticarse y resolverse en menos de una hora, reduciendo el tiempo de inactividad y manteniendo la postura de seguridad.