Autorisations - AWS Cloud Development Kit (AWS CDK) v2

Ceci est le guide du AWS CDK développeur de la version 2. L'ancien CDK v1 est entré en maintenance le 1er juin 2022 et a pris fin le 1er juin 2023.

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Autorisations

La bibliothèque AWS Construct utilise quelques expressions idiomatiques courantes et largement implémentées pour gérer les accès et les autorisations. Le module IAM fournit les outils dont vous avez besoin pour utiliser ces expressions idiomatiques.

AWS CDK utilise AWS CloudFormation pour déployer les modifications. Chaque déploiement implique un acteur (un développeur ou un système automatisé) qui lance un AWS CloudFormation déploiement. Au cours de cette opération, l'acteur assumera une ou plusieurs identités IAM (utilisateur ou rôles) et transmettra éventuellement un rôle à AWS CloudFormation.

Si vous vous authentifiez AWS IAM Identity Center en tant qu'utilisateur, le fournisseur d'authentification unique fournit des informations d'identification de session de courte durée qui vous autorisent à agir en tant que rôle IAM prédéfini. Pour savoir comment AWS CDK obtenir les AWS informations d'identification grâce à l'authentification IAM Identity Center, voir Comprendre l'authentification IAM Identity Center dans le Guide de référence AWS des SDK et des outils.

Principaux

Un principal IAM est une AWS entité authentifiée représentant un utilisateur, un service ou une application qui peut appeler AWS des API. La bibliothèque AWS Construct permet de spécifier les principes de plusieurs manières flexibles pour leur permettre d'accéder à vos AWS ressources.

Dans les contextes de sécurité, le terme « principal » fait spécifiquement référence aux entités authentifiées telles que les utilisateurs. Les objets tels que les groupes et les rôles ne représentent pas les utilisateurs (ni les autres entités authentifiées) mais les identifient indirectement dans le but d'accorder des autorisations.

Par exemple, si vous créez un groupe IAM, vous pouvez accorder au groupe (et donc à ses membres) un accès en écriture à une table Amazon RDS. Cependant, le groupe lui-même n'est pas un principal car il ne représente pas une entité unique (vous ne pouvez pas non plus vous connecter à un groupe).

Dans la bibliothèque IAM du CDK, les classes qui identifient directement ou indirectement les principaux implémentent l'IPrincipalinterface, ce qui permet d'utiliser ces objets de manière interchangeable dans les politiques d'accès. Cependant, ils ne sont pas tous des principes essentiels au sens de la sécurité. Ces objets incluent :

  1. des ressources IAM telles que RoleUser, et Group

  2. Principaux de service () new iam.ServicePrincipal('service.amazonaws.com')

  3. Principaux fédérés () new iam.FederatedPrincipal('cognito-identity.amazonaws.com')

  4. Principaux du compte (new iam.AccountPrincipal('0123456789012'))

  5. Principaux utilisateurs canoniques () new iam.CanonicalUserPrincipal('79a59d[...]7ef2be')

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

  7. Principaux ARN arbitraires () new iam.ArnPrincipal(res.arn)

  8. Et de iam.CompositePrincipal(principal1, principal2, ...) faire confiance à plusieurs principes

Octrois

Chaque construction qui représente une ressource accessible, telle qu'un compartiment Amazon S3 ou une table Amazon DynamoDB, possède des méthodes qui accordent l'accès à une autre entité. Toutes ces méthodes ont des noms commençant par grant.

Par exemple, les compartiments Amazon S3 disposent des méthodes grantRead et grantReadWrite (Python :grant_read,grant_read_write) nécessaires pour permettre l'accès en lecture et en lecture/écriture, respectivement, d'une entité au compartiment. L'entité n'a pas besoin de savoir exactement quelles autorisations IAM Amazon S3 sont requises pour effectuer ces opérations.

Le premier argument d'une méthode d'octroi est toujours de type iGrantable. Cette interface représente les entités auxquelles des autorisations peuvent être accordées. C'est-à-dire qu'il représente des ressources dotées de rôles, tels que les objets IAM RoleUser, etGroup.

D'autres entités peuvent également obtenir des autorisations. Par exemple, plus loin dans cette rubrique, nous expliquons comment accorder à un CodeBuild projet l'accès à un compartiment Amazon S3. Généralement, le rôle associé est obtenu via une role propriété de l'entité à laquelle l'accès est accordé.

Les ressources qui utilisent des rôles d'exécution, telles quelambda.Function, sont également mises en œuvreIGrantable, afin que vous puissiez leur accorder l'accès directement au lieu d'accorder l'accès à leur rôle. Par exemple, s'il s'bucketagit d'un compartiment Amazon S3 et function d'une fonction Lambda, le code suivant accorde à la fonction un accès en lecture au compartiment.

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

Parfois, des autorisations doivent être appliquées pendant le déploiement de votre stack. C'est le cas lorsque vous accordez à une ressource AWS CloudFormation personnalisée l'accès à une autre ressource. La ressource personnalisée sera invoquée pendant le déploiement. Elle doit donc disposer des autorisations spécifiées au moment du déploiement.

Un autre cas est celui où un service vérifie que les bonnes politiques sont appliquées au rôle que vous lui transmettez. (Un certain nombre de AWS services le font pour s'assurer que vous n'avez pas oublié de définir les politiques.) Dans ces cas, le déploiement risque d'échouer si les autorisations sont appliquées trop tard.

Pour forcer l'application des autorisations de la subvention avant la création d'une autre ressource, vous pouvez ajouter une dépendance à la subvention elle-même, comme indiqué ici. Bien que la valeur de retour des méthodes de subvention soit généralement ignorée, chaque méthode de subvention renvoie en fait un iam.Grant objet.

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);

Rôles

Le package IAM contient une Role construction qui représente les rôles IAM. Le code suivant crée un nouveau rôle, faisant confiance au service Amazon EC2.

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 });

Vous pouvez ajouter des autorisations à un rôle en appelant la addToPolicy méthode du rôle (Python :add_to_policy), en transmettant un PolicyStatement qui définit la règle à ajouter. L'instruction est ajoutée à la politique par défaut du rôle ; si elle n'en possède aucune, elle est créée.

L'exemple suivant ajoute une déclaration de Deny politique au rôle pour les actions ec2:SomeAction et s3:AnotherAction sur les ressources bucket et otherRole (Python :other_role), à condition que le service autorisé soit 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" } } }));

Dans l'exemple précédent, nous avons créé une nouvelle entrée PolicyStatement en ligne avec l'appel addToPolicy (Python :add_to_policy). Vous pouvez également transmettre une déclaration de politique existante ou une déclaration que vous avez modifiée. L'PolicyStatementobjet dispose de nombreuses méthodes pour ajouter des principes, des ressources, des conditions et des actions.

Si vous utilisez une construction qui nécessite un rôle pour fonctionner correctement, vous pouvez effectuer l'une des opérations suivantes :

  • Transmettez un rôle existant lors de l'instanciation de l'objet de construction.

  • Laissez le concept créer un nouveau rôle pour vous, en faisant confiance au directeur de service approprié. L'exemple suivant utilise une telle construction : un CodeBuild projet.

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 });

Une fois l'objet créé, le rôle (qu'il s'agisse du rôle transmis ou du rôle par défaut créé par la construction) est disponible en tant que propriétérole. Toutefois, cette propriété n'est pas disponible sur les ressources externes. Par conséquent, ces constructions ont une méthode addToRolePolicy (Python :add_to_role_policy).

La méthode ne fait rien si la construction est une ressource externe, sinon elle appelle la méthode addToPolicy (Python :add_to_policy) de la role propriété. Cela vous évite d'avoir à traiter explicitement le cas non défini.

L'exemple suivant illustre ce qui suit :

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 }));

Politiques basées sur une ressource

Certaines ressources AWS, telles que les compartiments Amazon S3 et les rôles IAM, sont également soumises à une politique de ressources. Ces constructions ont une addToResourcePolicy méthode (Python :add_to_resource_policy), qui prend a PolicyStatement comme argument. Chaque déclaration de politique ajoutée à une politique de ressources doit spécifier au moins un principal.

Dans l'exemple suivant, le compartiment Amazon S3 bucket octroie un rôle doté de cette s3:SomeAction autorisation.

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 } }));

Utilisation d'objets IAM externes

Si vous avez défini un utilisateur, un principal, un groupe ou un rôle IAM en dehors de votre AWS CDK application, vous pouvez utiliser cet objet IAM dans votre AWS CDK application. Pour ce faire, créez une référence à celui-ci en utilisant son ARN ou son nom. (Utilisez le nom pour les utilisateurs, les groupes et les rôles.) La référence renvoyée peut ensuite être utilisée pour accorder des autorisations ou pour élaborer des déclarations de politique, comme expliqué précédemment.

Les politiques (y compris les politiques gérées) peuvent être utilisées de la même manière en utilisant les méthodes suivantes. Vous pouvez utiliser des références à ces objets partout où une politique IAM est requise.

Note

Comme pour toutes les références à AWS des ressources externes, vous ne pouvez pas modifier les objets IAM externes dans votre application CDK.