Blog de Amazon Web Services (AWS)

Cómo restringir el acceso al bucket de Amazon S3 a un rol de IAM específico

Por Chris Craig, Senior CDA na AWS

2 de abril de 2021: En la sección «Conceder acceso entre cuentas a un bucket para un rol de IAM específico», actualizamos la segunda política para corregir un error.


 

Soy ingeniero de soporte en AWS, los clientes suelen preguntarme cómo pueden limitar el acceso desde y hacia un bucket de Amazon S3 a una función específica de AWS Identity and Access Management (IAM).  En general, intentan hacerlo de la misma manera que lo harían con un usuario de IAM: mediante una política de bucket que introduce explícitamente denegar para todos los principales (usuarios de la interfaz de usuario y roles) a los que no desean conceder acceso.  La desventaja de este enfoque es el mantenimiento necesario de la política de bucket.  Si se añadía un nuevo usuario de IAM a la cuenta con «s3: *» para la acción, el usuario tendría acceso al bucket.  En lugar de especificar la lista de usuarios cuyo acceso desea bloquear, puede invertir la lógica y aprovechar el elemento NotPrincipal de la declaración de política Deny bucket.  Este elemento crea una denegación explícita para cualquier usuario que no aparezca en este campo.

Sin embargo, este enfoque de lógica invertida es problemático con las funciones de IAM, ya que el valor principal de la función consiste en dos nombres de recursos de Amazon (ARN): la función ARN y la función de ARN asumida.  La función de ARN es el identificador del propio perfil de IAM y la función de ARN asumida es la que identifica la sesión de rol en los registros.  Al utilizar el elemento NotPrincipal, debe incluir ambos ARN para que funcione este enfoque, y el segundo de estos ARN debe incluir un nombre de variable.  Normalmente, especificaría un comodín (*) donde colocaría la variable de cadena, pero eso no está permitido en los elementos Principal o NotPrincipal.  En esta entrada de blog, muestro cómo se puede restringir el acceso al bucket de S3 a un rol de IAM o a un usuario de IAM específico en una cuenta con condiciones, en lugar de utilizar el elemento NotPrincipal.  Incluso si otro usuario de la misma cuenta tiene una política de administración o una política con s3: *, se le denegará si no aparecen explícitamente en la lista.  Puede utilizar este enfoque, por ejemplo, para configurar un bucket, por ejemplo, el acceso a un grupo de Auto Scaling.  También puede utilizar este enfoque para limitar el acceso a un bucket con una necesidad de seguridad de alto nivel.

 

Descripción general de la solución

La solución de esta publicación usa una política de bucket para controlar el acceso a un bucket de S3, incluso si un recurso tiene acceso a la API de S3 completa.  El siguiente diagrama ilustra cómo funciona esto para un bucket de la misma cuenta.

Diagram illustrating how this solution works for a bucket in the same account

  1. La política de usuario y la política de roles de IAM otorgan acceso a «s3: *».
  2. La política de bucket de S3 restringe el acceso únicamente a Role.
  3. Tanto el usuario de IAM como el rol pueden acceder a los buckets de la cuenta.  El rol puede acceder a ambos cubos, pero el usuario solo puede acceder al bucket sin la política de bucket adjunta.  Si bien role y el usuario tienen todos los permisos «s3: *», la política de bucket niega el acceso al bucket a cualquier persona que no haya asumido el rol.

La principal diferencia en el enfoque multicuenta es que cada bucket debe tener una política de bucket adjunta.  El siguiente diagrama ilustra cómo funciona esto en un escenario de implementación con varias cuentas.

Diagram illustrating how the solution works in a cross-account deployment scenario

  1. La política de roles de IAM y la política de usuarios de IAM de la cuenta de bucket otorgan acceso a «s3: *»
  2. La política de bucket niega el acceso a cualquier persona si el user:id no es el mismo que el del rol, y define lo que Role puede hacer con el bucket.
  3. La política de bucket permite el acceso al rol de la otra cuenta.
  4. El usuario y el rol de IAM pueden acceder al bucket sin la política denegar en el bucket.  El role puede acceder a ambos cubos porque Deny es solo para directores cuyo user:id no es el mismo que el de Role.

Comprenda el elemento NotPrincipal y cómo usarlo

Puede utilizar el elemento NotPrincipal de una política de bucket de IAM o S3 para limitar el acceso a los recursos a un conjunto específico de usuarios.  Este elemento le permite bloquear a todos los usuarios que no estén definidos en su matriz de valores, incluso si tienen una opción de permitir en sus propias políticas de usuario de IAM.  Como resultado, si tiene un usuario que debe tener acceso a todos los buckets excepto a uno en S3, puede definirlo desde el propio bucket, sin tener que editar la pila de políticas del usuario de IAM.

Sin embargo, para un rol de IAM, esto es más complejo porque el rol se define mediante dos ARN en la IP principal: el rol de ARN y el rol de ARN asumido.  El rol de ARN (arn:aws:iam:: accountNumber:role/ ROLE-NAME) es estático e independiente de quién haya iniciado la sesión del rol.  (A lo largo de esta publicación, recuerda reemplazar la información del marcador por la información de tu propia cuenta).  El ARN del rol asumido (arn:aws:sts:: accountNumber:assumed-role/ ROLE-NAME /ROLE-SESSION-NAME) variará según lo que se defina para el nombre de la sesión de rol.  Para comprobarlo, consulte el siguiente elemento de identidad en una entrada de AWS CloudTrail para una llamada a la API realizada por un usuario que asumió un rol.

{
  "type": "AssumedRole",
  "principalId": "AROAJI4AVVEXAMPLE:ROLE-SESSION-NAME",
  "arn": "arn:aws:sts::ACCOUNTNUMBER:assumed-role/ROLE-NAME/ROLE-SESSION-NAME",
  "accountId": "ACCOUNTNUMBER",
  "accessKeyId": "ASIAEXAMPLEKEY",
  "sessionContext": {
    "attributes": {
      "mfaAuthenticated": "false",
      "creationDate": "XXXX-XX-XXTXX:XX:XXZ"
    },
    "sessionIssuer": {
      "type": "Role",
      "principalId": "AROAJI4AVV3EXAMPLEID",
      "arn": "arn:aws:iam::ACCOUNTNUMBER:role/ROLE-NAME",
      "accountId": "ACCOUNTNUBMER",
      "userName": "ROLE-SESSION-NAME"
    }
  }
}

Conceder acceso al bucket de la misma cuenta a un rol de IAM específico

Al acceder a un bucket desde la misma cuenta, no es necesario utilizar una política de bucket en la mayoría de los casos.  Esto se debe a que una política de bucket define el acceso que ya está otorgado directamente por la política de usuario de IAM.  Las políticas de bucket de S3 se utilizan generalmente para el acceso entre cuentas, pero también puedes usarlas para restringir el acceso mediante una denegación explícita, que se aplicaría a todos los directores, ya estén en la misma cuenta de bucket o en una cuenta diferente.

Cada entidad de IAM (usuario o rol) tiene definida una variable aws:userid.  Necesitará esta variable para utilizarla en la política de bucket a fin de especificar el rol o el usuario como excepción en un elemento condicional.  El valor AWS:UserID para un rol asumido se define como UNIQUE-ROLE-ID:ROLE-SESSION-NAME (por ejemplo, aroaExampleID:UserDefinedSessionName).

Para obtener AROAEXAMPLEID para el rol de IAM, haga lo siguiente:

  1. Instale la CLI de AWS y abra una línea de comandos o un shell.
  2. Ejecute el siguiente comando: aws iam get-role —role-name ROLE-NAME.
  3. En la salida, busque la cadena RoleID, que comienza por AROA.  Lo usarás en la política de bucket para definir el alcance del acceso al bucket únicamente para ese rol.

En el ejemplo citado anteriormente en el código de CloudTrail, este ID es el elemento principalID.  El valor de este elemento es importante porque las variables de política de AWS también se pueden comprobar como cadenas en una política de IAM.  En lugar de especificar el rol y el ARN del rol asumido en un elemento NotPrincipal, puede usar el valor aws:userId en una condición StringNotLike con una cadena comodín (*).  En el valor de aws:userID, también tendrá que añadir el usuario raíz de la cuenta para que el bucket no quede completamente inaccesible si se elimina el rol definido.  El seudónimo de la cuenta raíz es el número de cuenta.

Con el AROAEXAMPLEID que acaba de recuperar a través de la CLI de AWS, puede crear una lógica condicional para la política de bucket a fin de definir el alcance del acceso al bucket únicamente para los usuarios que utilizan este rol al acceder al bucket.  El uso de lógica condicional en lugar de un elemento NotPrincipal permite el uso de una cadena comodín (*) para permitir que se acepte cualquier nombre de sesión de rol.

Ahora que tienes el ID de rol al que quieres permitir el acceso, debes bloquear el acceso de otros usuarios de la misma cuenta que el bucket.  La política para bloquear el acceso al bucket y sus objetos a los usuarios que no utilizan el perfil de IAM o las credenciales de la cuenta raíz sería similar a la siguiente.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::MyExampleBucket",
        "arn:aws:s3:::MyExampleBucket/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userId": [
            "AROAEXAMPLEID:*",
            "111111111111"
          ]
        }
      }
    }
  ]
}

También puede utilizar esta misma política para los usuarios de IAM.  Un usuario de IAM tiene un identificador único que comienza por AIDA que puede utilizar para este propósito.  Para encontrar este identificador único, sigue estos pasos:

  1. Con la CLI de AWS instalada, abra una línea de comandos o un shell.
  2. Ejecute el comando: aws iam get-user -—username USERNAME
  3. En la salida, busque la cadena UserId, que empezará por AIDAEXAMPLEID.

Una vez que haya identificado la cadena UserID, puede colocarla en el conjunto de condiciones «aws:UserId», como se muestra en el siguiente ejemplo.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::MyExampleBucket",
        "arn:aws:s3:::MyExampleBucket/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userId": [
            "AROAEXAMPLEID:*",
            "AIDAEXAMPLEID",
            "111111111111"
          ]
        }
      }
    }
  ]
}

Conceder acceso entre cuentas a un bucket para un rol de IAM específico

En la sección anterior, mostré cómo restringir el acceso al bucket de S3 a roles de IAM o a usuarios específicos de la misma cuenta.  Ahora, voy a mostrarte cómo restringir el acceso a usuarios y roles específicos en otra cuenta.  Al conceder acceso al bucket entre cuentas a un usuario o rol de IAM, debe definir qué puede hacer ese usuario o rol de IAM con ese acceso.  Anteriormente, en el blog de seguridad de AWS, Jim Scharf escribió sobre los permisos necesarios para permitir que una entidad de IAM acceda a un bucket a través de la CLI/API y la consola C.  Según la información que se encuentra en esta entrada de blog anterior, la política de bucket de acceso a nivel de CLI/API sería similar a la siguiente:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/ROLENAME"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::MyExampleBucket"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/ROLENAME"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::MyExampleBucket/*"
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::MyExampleBucket",
                "arn:aws:s3:::MyExampleBucket/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": [
                        "AROAEXAMPLEID:*",
                        "111111111111"
                    ]
                }
            }
        }
    ]
}

Las acciones de servicio necesarias para el acceso de nivel D a la consola C, como las que se utilizarían con la funcionalidad IAM Switch Role para la consola C de AWS, se muestran en la siguiente política.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/ROLENAME"
            },
            "Action": [
                "s3:GetBucketLocation"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/ROLENAME"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::MyExampleBucket"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111111111111:role/ROLENAME"
            },
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::MyExampleBucket/*"
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::MyExampleBucket",
                "arn:aws:s3:::MyExampleBucket/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": [
                        "AROAEXAMPLEID:*",
                        "111111111111"
                    ]
                }
            }
        }
    ]
}

Para conceder acceso a la API/CLI a un usuario de IAM de otra cuenta, tendrá que añadir AIDAEXAMPLEID para el usuario de IAM a la condición «aws:userID», como hicimos en la sección anterior.  Además de la condición «aws:UserID», también tendrá que añadir el ARN completo del usuario de IAM al elemento principal de esas políticas.  Tenga en cuenta que no puede conceder el acceso entre cuentas a través de la consola de AWS a un usuario de IAM, porque ese usuario tendría que asumir un rol en la cuenta de destino, pero puede conceder el acceso al bucket mediante la API/CLI.  Sería lo siguiente:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": [
                {
                    "AWS": [
                        "arn:aws:iam::222222222222:role/ROLENAME",
                        "arn:aws:iam::222222222222:user/USERNAME"
                    ]
                }
            ],
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::MyExampleBucket"
        },
        {
            "Effect": "Allow",
            "Principal": [
                {
                    "AWS": [
                        "arn:aws:iam::222222222222:role/ROLENAME",
                        "arn:aws:iam::222222222222:user/USERNAME"
                    ]
                }
            ],
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::MyExampleBucket/*"
        },
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::MyExampleBucket",
                "arn:aws:s3:::MyExampleBucket/*"
            ],
            "Condition": {
                "StringNotLike": {
                    "aws:userId": [
                        "AROAEXAMPLEID:*",
                        "AIDAEXAMPLEID",
                        "111111111111"
                    ]
                }
            }
        }
    ]
}

Además de incluir los permisos de rol en la política de bucket, debe definir esos permisos en las políticas de rol o usuario de IAM.  Los permisos se pueden agregar a una política administrada por el cliente y adjuntarlos al rol o al usuario en la consola de IAM, con el siguiente documento de política.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListAllMyBuckets",
        "s3:GetBucketLocation"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::MyExampleBucket"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::MyExampleBucket/*"
    }
  ]
}

Siguiendo las pautas de esta publicación, puedes restringir el acceso al bucket de S3 a un rol o usuario de IAM específico en tu cuenta local y a todas las cuentas, incluso si el usuario tiene una política de administración o una política con s3: *.  Hay muchas aplicaciones de esta lógica y los requisitos pueden diferir entre los casos de uso.  Puede utilizar este enfoque, por ejemplo, para configurar un bucket o  el acceso a un grupo de Auto Scaling.  También puede utilizar este enfoque para limitar el acceso a un depósito con una necesidad de seguridad de alto nivel, como un depósito que contiene registros personales e información contable.  Recuerde que siempre es mejor conceder permisos solo a los recursos necesarios para realizar las tareas necesarias.

Si tiene comentarios sobre esta publicación, envíelos en la sección «Comentarios» que aparece más abajo. Si tiene preguntas, inicie un tema nuevo en el foro de IAM.

— Chris

 

Este artículo fue traducido del Blog da AWS en Inglés.

 


Sobre o autor

Chris Craig é Senior CDA na AWS

 

 

 

 

Revisores

Bruno Lopes es un arquitecto de soluciones sénior en el equipo de AWS LATAM. Lleva más de 14 años trabajando con soluciones de TI, y en su cartera cuenta con numerosas experiencias en cargas de trabajo de Microsoft, entornos híbridos y formación técnica para clientes como Technical Trainer y Evangelista. Ahora actúa como arquitecto de soluciones, combinando todas las capacidades para reducir la burocracia en la adopción de las mejores tecnologías a fin de ayudar a los clientes a superar sus desafíos diarios.

 

 

 

 

Dan Rezende es un arquitecto de infraestructura en la nube en el equipo de Servicios Profesionales para el Sector Público. Haber trabajado en migraciones y aprovisionamiento de infraestructuras de aplicaciones en empresas del sector público y privado. En su tiempo libre, a Dan le gusta viajar y pasar tiempo con su familia.

 

 

 

 

Alberto De Santiago Parra es Senior Technical Account Manager en AWS