Permissões e o AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

Este é o Guia do Desenvolvedor AWS CDK v2. A versão CDK 1 mais antiga entrou em manutenção em 1º de junho de 2022 e encerrou o suporte em 1º de junho de 2023.

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

Permissões e o AWS CDK

A AWS Construct Library usa alguns idiomas comuns e amplamente implementados para gerenciar o acesso e as permissões. O IAM módulo fornece as ferramentas necessárias para usar esses idiomas.

AWS CDK usa AWS CloudFormation para implantar mudanças. Cada implantação envolve um ator (um desenvolvedor ou um sistema automatizado) que inicia uma AWS CloudFormation implantação. Ao fazer isso, o ator assumirá uma ou mais IAM identidades (usuário ou funções) e, opcionalmente, passará uma função para. AWS CloudFormation

Se você usa AWS IAM Identity Center para se autenticar como usuário, o provedor de login único fornece credenciais de sessão de curta duração que autorizam você a atuar como uma função predefinida. IAM Para saber como o AWS CDK obtém AWS credenciais da autenticação do IAM Identity Center, consulte Compreender a autenticação do IAM Identity Center no Guia de referência de ferramentas AWS SDKs e ferramentas.

Entidades principais

Um IAM principal é uma AWS entidade autenticada que representa um usuário, serviço ou aplicativo que pode ligar AWS APIs. A AWS Construct Library suporta a especificação de diretores de várias maneiras flexíveis para permitir que eles acessem seus AWS recursos.

Em contextos de segurança, o termo “principal” se refere especificamente a entidades autenticadas, como usuários. Objetos como grupos e funções não representam usuários (e outras entidades autenticadas), mas os identificam indiretamente com o objetivo de conceder permissões.

Por exemplo, se você criar um IAM grupo, poderá conceder ao grupo (e, portanto, a seus membros) acesso de gravação a uma RDS tabela da Amazon. No entanto, o grupo em si não é um principal porque não representa uma única entidade (além disso, você não pode fazer login em um grupo).

Na IAM biblioteca CDK do, classes que identificam direta ou indiretamente os principais implementam a IPrincipalinterface, permitindo que esses objetos sejam usados de forma intercambiável nas políticas de acesso. No entanto, nem todos são diretores no sentido de segurança. Esses objetos incluem:

  1. IAMrecursos como RoleUser, e Group

  2. Diretores de serviço () new iam.ServicePrincipal('service.amazonaws.com')

  3. Diretores federados () new iam.FederatedPrincipal('cognito-identity.amazonaws.com')

  4. Diretores de contas (new iam.AccountPrincipal('0123456789012'))

  5. Principais usuários canônicos () new iam.CanonicalUserPrincipal('79a59d[...]7ef2be')

  6. AWS Organizations diretores () new iam.OrganizationPrincipal('org-id')

  7. ARNPrincípios arbitrários () new iam.ArnPrincipal(res.arn)

  8. E iam.CompositePrincipal(principal1, principal2, ...) confiar em vários diretores

Concessões

Cada construção que representa um recurso que pode ser acessado, como um bucket do Amazon S3 ou uma tabela do Amazon DynamoDB, tem métodos que concedem acesso a outra entidade. Todos esses métodos têm nomes que começam com grant.

Por exemplo, os buckets do Amazon S3 têm os métodos e grantRead (grantReadWritePython:grant_read,grant_read_write) para permitir o acesso de leitura e leitura/gravação, respectivamente, de uma entidade ao bucket. A entidade não precisa saber exatamente quais IAM permissões do Amazon S3 são necessárias para realizar essas operações.

O primeiro argumento de um método de concessão é sempre do tipo IGrantable. Essa interface representa entidades que podem receber permissões. Ou seja, ele representa recursos com funções, como IAM objetos RoleUser, Group e.

Outras entidades também podem receber permissões. Por exemplo, mais adiante neste tópico, mostraremos como conceder a um CodeBuild projeto acesso a um bucket do Amazon S3. Geralmente, a função associada é obtida por meio de uma role propriedade na entidade que está recebendo acesso.

Recursos que usam funções de execução, comolambda.Function, também são implementadosIGrantable, para que você possa conceder acesso direto a eles em vez de conceder acesso à função deles. Por exemplo, se bucket for um bucket do Amazon S3 e function for uma função Lambda, o código a seguir concede à função acesso de leitura ao bucket.

TypeScript
bucket.grantRead(function);
JavaScript
bucket.grantRead(function);
Python
bucket.grant_read(function)
Java
bucket.grantRead(function);
C#
bucket.GrantRead(function);

Às vezes, as permissões precisam ser aplicadas enquanto sua pilha está sendo implantada. Um desses casos é quando você concede a um recurso AWS CloudFormation personalizado acesso a algum outro recurso. O recurso personalizado será invocado durante a implantação, portanto, ele deve ter as permissões especificadas no momento da implantação.

Outro caso é quando um serviço verifica se a função que você passa para ele tem as políticas corretas aplicadas. (Vários AWS serviços fazem isso para garantir que você não se esqueça de definir as políticas.) Nesses casos, a implantação pode falhar se as permissões forem aplicadas tarde demais.

Para forçar a aplicação das permissões da concessão antes da criação de outro recurso, você pode adicionar uma dependência da concessão em si, conforme mostrado aqui. Embora o valor de retorno dos métodos de concessão seja geralmente descartado, todo método de concessão na verdade retorna um iam.Grant objeto.

TypeScript
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);
JavaScript
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);
Python
grant = bucket.grant_read(function) custom = CustomResource(...) custom.node.add_dependency(grant)
Java
Grant grant = bucket.grantRead(function); CustomResource custom = new CustomResource(...); custom.node.addDependency(grant);
C#
var grant = bucket.GrantRead(function); var custom = new CustomResource(...); custom.node.AddDependency(grant);

Funções

O IAM pacote contém uma Role construção que representa IAM funções. O código a seguir cria uma nova função, confiando no EC2 serviço da Amazon.

TypeScript
import * as iam from 'aws-cdk-lib/aws-iam'; const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), // required });
JavaScript
const iam = require('aws-cdk-lib/aws-iam'); const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com') // required });
Python
import aws_cdk.aws_iam as iam role = iam.Role(self, "Role", assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) # required
Java
import software.amazon.awscdk.services.iam.Role; import software.amazon.awscdk.services.iam.ServicePrincipal; Role role = Role.Builder.create(this, "Role") .assumedBy(new ServicePrincipal("ec2.amazonaws.com")).build();
C#
using Amazon.CDK.AWS.IAM; var role = new Role(this, "Role", new RoleProps { AssumedBy = new ServicePrincipal("ec2.amazonaws.com"), // required });

Você pode adicionar permissões a uma função chamando o addToPolicy método da função (Python:add_to_policy), passando um PolicyStatement que define a regra a ser adicionada. A declaração é adicionada à política padrão da função; se não tiver nenhuma, uma será criada.

O exemplo a seguir adiciona uma declaração de Deny política à função das ações ec2:SomeAction e s3:AnotherAction dos recursos bucket e otherRole (Python:other_role), sob a condição de que o serviço autorizado seja. AWS CodeBuild

TypeScript
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com', }}}));
JavaScript
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com' }}}));
Python
role.add_to_policy(iam.PolicyStatement( effect=iam.Effect.DENY, resources=[bucket.bucket_arn, other_role.role_arn], actions=["ec2:SomeAction", "s3:AnotherAction"], conditions={"StringEquals": { "ec2:AuthorizedService": "codebuild.amazonaws.com"}} ))
Java
role.addToPolicy(PolicyStatement.Builder.create() .effect(Effect.DENY) .resources(Arrays.asList(bucket.getBucketArn(), otherRole.getRoleArn())) .actions(Arrays.asList("ec2:SomeAction", "s3:AnotherAction")) .conditions(java.util.Map.of( // Map.of requires Java 9 or later "StringEquals", java.util.Map.of( "ec2:AuthorizedService", "codebuild.amazonaws.com"))) .build());
C#
role.AddToPolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.DENY, Resources = new string[] { bucket.BucketArn, otherRole.RoleArn }, Actions = new string[] { "ec2:SomeAction", "s3:AnotherAction" }, Conditions = new Dictionary<string, object> { ["StringEquals"] = new Dictionary<string, string> { ["ec2:AuthorizedService"] = "codebuild.amazonaws.com" } } }));

No exemplo anterior, criamos uma nova PolicyStatement linha com a chamada (addToPolicyPython:). add_to_policy Você também pode transmitir uma declaração de política existente ou uma que você tenha modificado. O PolicyStatementobjeto tem vários métodos para adicionar princípios, recursos, condições e ações.

Se você estiver usando uma construção que exige uma função para funcionar corretamente, você pode fazer o seguinte:

  • Passe uma função existente ao instanciar o objeto de construção.

  • Deixe que a construção crie uma nova função para você, confiando no diretor de serviço apropriado. O exemplo a seguir usa essa construção: um CodeBuild projeto.

TypeScript
import * as codebuild from 'aws-cdk-lib/aws-codebuild'; // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole: iam.IRole | undefined = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole, });
JavaScript
const codebuild = require('aws-cdk-lib/aws-codebuild'); // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole });
Python
import aws_cdk.aws_codebuild as codebuild # imagine role_or_none is a function that might return a Role object # under some conditions, and None under other conditions some_role = role_or_none(); project = codebuild.Project(self, "Project", # if role is None, the Project creates a new default role, # trusting the codebuild.amazonaws.com service principal role=some_role)
Java
import software.amazon.awscdk.services.iam.Role; import software.amazon.awscdk.services.codebuild.Project; // imagine roleOrNull is a function that might return a Role object // under some conditions, and null under other conditions Role someRole = roleOrNull(); // if someRole is null, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal Project project = Project.Builder.create(this, "Project") .role(someRole).build();
C#
using Amazon.CDK.AWS.CodeBuild; // imagine roleOrNull is a function that might return a Role object // under some conditions, and null under other conditions var someRole = roleOrNull(); // if someRole is null, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal var project = new Project(this, "Project", new ProjectProps { Role = someRole });

Depois que o objeto é criado, a função (seja a função passada ou a padrão criada pela construção) fica disponível como propriedaderole. No entanto, essa propriedade não está disponível em recursos externos. Portanto, essas construções têm um método addToRolePolicy (Pythonadd_to_role_policy:).

O método não faz nada se a construção for um recurso externo e, caso contrário, chama o método addToPolicy (Python:add_to_policy) da role propriedade. Isso evita o trabalho de lidar explicitamente com o caso indefinido.

O exemplo a seguir demonstra:

TypeScript
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, // ... and so on defining the policy }));
JavaScript
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW // ... and so on defining the policy }));
Python
# project is imported into the CDK application project = codebuild.Project.from_project_name(self, 'Project', 'ProjectName') # project is imported, so project.role is undefined, and this call has no effect project.add_to_role_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, # ... and so on defining the policy )
Java
// project is imported into the CDK application Project project = Project.fromProjectName(this, "Project", "ProjectName"); // project is imported, so project.getRole() is null, and this call has no effect project.addToRolePolicy(PolicyStatement.Builder.create() .effect(Effect.ALLOW) // .. and so on defining the policy .build();
C#
// project is imported into the CDK application var project = Project.FromProjectName(this, "Project", "ProjectName"); // project is imported, so project.role is null, and this call has no effect project.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, // ... and so on defining the policy }));

Políticas de recursos

Alguns recursos AWS, como buckets e IAM funções do Amazon S3, também têm uma política de recursos. Essas construções têm um addToResourcePolicy método (Pythonadd_to_resource_policy:), que usa a PolicyStatement como argumento. Cada declaração de política adicionada a uma política de recursos deve especificar pelo menos um principal.

No exemplo a seguir, o bucket do Amazon S3 bucket concede uma função com a s3:SomeAction permissão para si mesmo.

TypeScript
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));
JavaScript
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));
Python
bucket.add_to_resource_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=["s3:SomeAction"], resources=[bucket.bucket_arn], principals=role))
Java
bucket.addToResourcePolicy(PolicyStatement.Builder.create() .effect(Effect.ALLOW) .actions(Arrays.asList("s3:SomeAction")) .resources(Arrays.asList(bucket.getBucketArn())) .principals(Arrays.asList(role)) .build());
C#
bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Actions = new string[] { "s3:SomeAction" }, Resources = new string[] { bucket.BucketArn }, Principals = new IPrincipal[] { role } }));

Usando IAM objetos externos

Se você definiu um IAM usuário, diretor, grupo ou função fora do seu AWS CDK aplicativo, você pode usar esse IAM objeto em seu AWS CDK aplicativo. Para fazer isso, crie uma referência a ele usando seu nome ARN ou seu nome. (Use o nome para usuários, grupos e funções.) A referência retornada pode então ser usada para conceder permissões ou criar declarações de política, conforme explicado anteriormente.

As políticas (incluindo políticas gerenciadas) podem ser usadas de forma semelhante usando os métodos a seguir. Você pode usar referências a esses objetos em qualquer lugar em que uma IAM política seja necessária.

nota

Como acontece com todas as referências a AWS recursos externos, você não pode modificar IAM objetos externos no seu CDK aplicativo.