El Comportamiento Esperado y el Error 403 Access Denied

Al interactuar con Amazon S3 (Simple Storage Service)—ya sea descargando un archivo a través de un navegador web, subiendo artefactos mediante la CLI de AWS, o leyendo archivos de configuración mediante una aplicación que se ejecuta en EC2—el comportamiento esperado es una transacción rápida y sin problemas que da como resultado un estado HTTP 200 OK.

Sin embargo, uno de los obstáculos más frustrantes y frecuentes que enfrentan los administradores en la nube es el error 403 Access Denied o la excepción AccessDenied.

Debido a que AWS aplica un modelo de confianza cero por defecto (se deniega todo el acceso a menos que se permita explícitamente), cualquier permiso faltante en la cadena de autorización resultará en un 403. Además, un Deny (Denegar) explícito en cualquier lugar de tus políticas anulará por completo cualquier Allow (Permitir).

Requisitos Previos

Antes de solucionar el problema, reúne el siguiente contexto:

  • El nombre exacto del Bucket de S3.
  • El Usuario de IAM, Rol de IAM (si se usa EC2/EKS/Lambda), o las Claves de Acceso de AWS que se utilizan para la solicitud.
  • Si la solicitud proviene de la misma cuenta de AWS o de una conexión entre cuentas (cross-account).
  • Si los objetos están cifrados con KMS.

Causas Principales del Error S3 403 Access Denied

Un error 403 Access Denied en S3 normalmente se reduce a una de estas capas de seguridad superpuestas:

  1. Permisos IAM Faltantes: El usuario o rol de IAM que intenta la acción carece de s3:GetObject (para descargar), s3:PutObject (para subir) o s3:ListBucket.
  2. Conflictos en la Política del Bucket: El bucket S3 tiene un Bucket Policy .json que carece de una declaración de recurso (resource statement) o contiene un Effect: Deny explícito para el usuario/dirección IP.
  3. El Bloqueo de Acceso Público está Habilitado: Si estás intentando hacer público un bucket para el alojamiento de sitios web, la configuración global “Block Public Access” rechazará las solicitudes públicas, independientemente de lo que diga la Política del Bucket.
  4. Errores de Descifrado KMS: Si el bucket utiliza AWS KMS (Key Management Service) para el cifrado, el usuario IAM necesita s3:GetObject y kms:Decrypt. Si falta el permiso de la clave KMS, S3 arroja un 403.
  5. Propiedad del Objeto vs Propiedad del Bucket: En escenarios entre cuentas, la Cuenta A sube un archivo al bucket de la Cuenta B. La Cuenta B intenta leerlo y obtiene un 403 porque la Cuenta A es propietaria del objeto de forma implícita.

Solución Paso a Paso

1. Identificar la Acción Permitida Exacta Necesaria

Primero, determina qué está intentando hacer la aplicación o el usuario. Si estás subiendo un archivo a través de CLI:

aws s3 cp file.txt s3://my-cloud-bucket/

Esto requiere s3:PutObject. Si estás intentando ver el contenido del bucket mediante aws s3 ls, esto requiere s3:ListBucket.

2. Verificar los Permisos del Usuario/Rol IAM

Navega a la Consola de IAM y encuentra el Usuario o Rol asociado a tu sistema. Deben tener una política que otorgue acceso al ARN exacto del bucket.

Una política IAM correcta que permite lectura/escritura se ve así:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::my-cloud-bucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-cloud-bucket/*"
            ]
        }
    ]
}

Nota Crucial: El recurso arn:aws:s3:::my-bucket se aplica al bucket en sí (para ListBucket). El recurso arn:aws:s3:::my-bucket/* se aplica a los objetos dentro del bucket (para GetObject/PutObject). ¡Mezclar estos ARNs es una causa principal de los errores 403!

3. Revisar la Política del Bucket (Bucket Policy)

Navega a la Consola de S3, selecciona tu bucket y haz clic en la pestaña Permisos. Desplázate hacia abajo hasta la Política del Bucket (Bucket Policy).

Incluso si tu Usuario de IAM tiene privilegios completos de Administrador, un Deny explícito en la Política del Bucket lo anulará. Por ejemplo, si ves una política destinada a restringir el acceso a una IP específica de VPN:

{
    "Effect": "Deny",
    "Principal": "*",
    "Action": "s3:*",
    "Resource": "arn:aws:s3:::my-cloud-bucket/*",
    "Condition": {
        "NotIpAddress": {"aws:SourceIp": "203.0.113.0/24"}
    }
}

Si realizas pruebas desde una IP fuera de ese rango, recibirás un 403.

4. Hacer Objetos Públicos (Alojamiento Web)

Si tu objetivo es alojar un sitio web estático o imágenes públicas y recibes un 403:

  1. Ve a la pestaña de Permisos en S3.
  2. Edita Block public access (bucket settings) y desmarca “Block all public access” (Bloquear todo el acceso público). Guarda los cambios.
  3. Añade la siguiente Política de Bucket para permitir explícitamente a Internet leer tus objetos:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-cloud-bucket/*"
        }
    ]
}

5. Comprobar el Cifrado KMS (Solución Alternativa)

Si los permisos parecen estar completamente correctos, comprueba si el bucket utiliza claves KMS administradas por el cliente (SSE-KMS). Ve a la pestaña de Propiedades del bucket S3. Si el “Default Encryption” está configurado para usar una clave KMS personalizada, tu rol IAM también debe tener permiso para descifrarla.

Adjunta una política a tu Rol IAM que permita:

{
    "Effect": "Allow",
    "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey"
    ],
    "Resource": "arn:aws:kms:us-east-1:123456789012:key/tu-id-de-clave"
}

Prevención

  • Sigue el Privilegio Mínimo: Evita las políticas amplias de s3:*. Asigna exactamente s3:GetObject y s3:PutObject a rutas ARN específicas.
  • Aprovecha el AWS Policy Simulator: Utiliza el Simulador de Políticas IAM en la consola de AWS. Puedes introducir un usuario, una acción de S3 y el nombre de un bucket, y AWS trazará exactamente qué política está permitiendo o denegando la petición.
  • Habilita “Bucket Owner Enforced”: Para problemas entre cuentas (cross-account), habilita “Bucket Owner Enforced” (Propietario del bucket aplicado) en la configuración de la Propiedad de Objetos de S3. Esto desactiva las Listas de Control de Acceso (ACLs) individuales y obliga a que todos los objetos subidos por cualquier persona sean propiedad automática del propietario del bucket, simplificando enormemente los permisos.

Resumen

  • El error 403 Access Denied en S3 está causado por conflictos entre Políticas IAM, Políticas de Bucket y claves KMS.
  • El Deny explícito anula todo, incluido el acceso de administrador.
  • Asegúrate de que los ARN especifiquen /* al conceder permisos a nivel de objeto como GetObject.
  • Desactiva “Block Public Access” si necesitas que el bucket esté abierto a internet.
  • Confirma que el rol IAM tiene acceso kms:Decrypt si tu bucket usa cifrado KMS.

Artículos Relacionados