Skip to content

Commit

Permalink
Merge branch 'main' into l2_fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mergify[bot] committed Feb 8, 2023
2 parents 5e7f04b + d3df40f commit e6fd324
Show file tree
Hide file tree
Showing 24 changed files with 805 additions and 42 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-iam/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ declare const table: dynamodb.Table;
table.grant(fn, 'dynamodb:PutItem');
```

The `grant*` methods accept an `IGrantable` object. This interface is implemented by IAM principal resources (groups, users and roles) and resources that assume a role such as a Lambda function, EC2 instance or a Codebuild project.
The `grant*` methods accept an `IGrantable` object. This interface is implemented by IAM principal resources (groups, users and roles), policies, managed policies and resources that assume a role such as a Lambda function, EC2 instance or a Codebuild project.

You can find which `grant*` methods exist for a resource in the [AWS CDK API Reference](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-construct-library.html).

Expand Down
34 changes: 33 additions & 1 deletion packages/@aws-cdk/aws-iam/lib/managed-policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { IGroup } from './group';
import { CfnManagedPolicy } from './iam.generated';
import { PolicyDocument } from './policy-document';
import { PolicyStatement } from './policy-statement';
import { AddToPrincipalPolicyResult, IGrantable, IPrincipal, PrincipalPolicyFragment } from './principals';
import { undefinedIfEmpty } from './private/util';
import { IRole } from './role';
import { IUser } from './user';
Expand Down Expand Up @@ -100,7 +101,7 @@ export interface ManagedPolicyProps {
* Managed policy
*
*/
export class ManagedPolicy extends Resource implements IManagedPolicy {
export class ManagedPolicy extends Resource implements IManagedPolicy, IGrantable {
/**
* Import a customer managed policy from the managedPolicyName.
*
Expand Down Expand Up @@ -202,6 +203,8 @@ export class ManagedPolicy extends Resource implements IManagedPolicy {
*/
public readonly path: string;

public readonly grantPrincipal: IPrincipal;

private readonly roles = new Array<IRole>();
private readonly users = new Array<IUser>();
private readonly groups = new Array<IGroup>();
Expand Down Expand Up @@ -263,6 +266,8 @@ export class ManagedPolicy extends Resource implements IManagedPolicy {
props.statements.forEach(p => this.addStatements(p));
}

this.grantPrincipal = new ManagedPolicyGrantPrincipal(this);

this.node.addValidation({ validate: () => this.validateManagedPolicy() });
}

Expand Down Expand Up @@ -316,3 +321,30 @@ export class ManagedPolicy extends Resource implements IManagedPolicy {
return result;
}
}

class ManagedPolicyGrantPrincipal implements IPrincipal {
public readonly assumeRoleAction = 'sts:AssumeRole';
public readonly grantPrincipal: IPrincipal;
public readonly principalAccount?: string;

constructor(private _managedPolicy: ManagedPolicy) {
this.grantPrincipal = this;
this.principalAccount = _managedPolicy.env.account;
}

public get policyFragment(): PrincipalPolicyFragment {
// This property is referenced to add policy statements as a resource-based policy.
// We should fail because a managed policy cannot be used as a principal of a policy document.
// cf. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#Principal_specifying
throw new Error(`Cannot use a ManagedPolicy '${this._managedPolicy.node.path}' as the 'Principal' or 'NotPrincipal' in an IAM Policy`);
}

public addToPolicy(statement: PolicyStatement): boolean {
return this.addToPrincipalPolicy(statement).statementAdded;
}

public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult {
this._managedPolicy.addStatements(statement);
return { statementAdded: true, policyDependable: this._managedPolicy };
}
}
34 changes: 33 additions & 1 deletion packages/@aws-cdk/aws-iam/lib/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { IGroup } from './group';
import { CfnPolicy } from './iam.generated';
import { PolicyDocument } from './policy-document';
import { PolicyStatement } from './policy-statement';
import { AddToPrincipalPolicyResult, IGrantable, IPrincipal, PrincipalPolicyFragment } from './principals';
import { generatePolicyName, undefinedIfEmpty } from './private/util';
import { IRole } from './role';
import { IUser } from './user';
Expand Down Expand Up @@ -100,7 +101,7 @@ export interface PolicyProps {
* Policies](http://docs.aws.amazon.com/IAM/latest/UserGuide/policies_overview.html)
* in the IAM User Guide guide.
*/
export class Policy extends Resource implements IPolicy {
export class Policy extends Resource implements IPolicy, IGrantable {

/**
* Import a policy in this app based on its name
Expand All @@ -118,6 +119,8 @@ export class Policy extends Resource implements IPolicy {
*/
public readonly document = new PolicyDocument();

public readonly grantPrincipal: IPrincipal;

private readonly _policyName: string;
private readonly roles = new Array<IRole>();
private readonly users = new Array<IUser>();
Expand Down Expand Up @@ -178,6 +181,8 @@ export class Policy extends Resource implements IPolicy {
props.statements.forEach(p => this.addStatements(p));
}

this.grantPrincipal = new PolicyGrantPrincipal(this);

this.node.addValidation({ validate: () => this.validatePolicy() });
}

Expand Down Expand Up @@ -260,3 +265,30 @@ export class Policy extends Resource implements IPolicy {
return this.groups.length + this.users.length + this.roles.length > 0;
}
}

class PolicyGrantPrincipal implements IPrincipal {
public readonly assumeRoleAction = 'sts:AssumeRole';
public readonly grantPrincipal: IPrincipal;
public readonly principalAccount?: string;

constructor(private _policy: Policy) {
this.grantPrincipal = this;
this.principalAccount = _policy.env.account;
}

public get policyFragment(): PrincipalPolicyFragment {
// This property is referenced to add policy statements as a resource-based policy.
// We should fail because a policy cannot be used as a principal of a policy document.
// cf. https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#Principal_specifying
throw new Error(`Cannot use a Policy '${this._policy.node.path}' as the 'Principal' or 'NotPrincipal' in an IAM Policy`);
}

public addToPolicy(statement: PolicyStatement): boolean {
return this.addToPrincipalPolicy(statement).statementAdded;
}

public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult {
this._policy.addStatements(statement);
return { statementAdded: true, policyDependable: this._policy };
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-iam/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"devDependencies": {
"@aws-cdk/assertions": "0.0.0",
"@aws-cdk/cdk-build-tools": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/integ-runner": "0.0.0",
"@aws-cdk/integ-tests": "0.0.0",
"@aws-cdk/cfn2ts": "0.0.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "21.0.0",
"files": {
"21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": {
"source": {
"path": "ManagedPolicyIntegDefaultTestDeployAssert27007DC6.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
}
},
"dockerImages": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"Parameters": {
"BootstrapVersion": {
"Type": "AWS::SSM::Parameter::Value<String>",
"Default": "/cdk-bootstrap/hnb659fds/version",
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
}
},
"Rules": {
"CheckBootstrapVersion": {
"Assertions": [
{
"Assert": {
"Fn::Not": [
{
"Fn::Contains": [
[
"1",
"2",
"3",
"4",
"5"
],
{
"Ref": "BootstrapVersion"
}
]
}
]
},
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
}
]
}
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"version": "20.0.0",
"version": "21.0.0",
"files": {
"368422c5e22c8b7707ddebb8f45bea20bd1c541adb0778d8e86c2e1854900523": {
"df45fa697f19036987d5bfe10fdcfba6de6d5d93be8e406edfc43fcc13fedc33": {
"source": {
"path": "aws-cdk-iam-managed-policy.template.json",
"packaging": "file"
},
"destinations": {
"current_account-current_region": {
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
"objectKey": "368422c5e22c8b7707ddebb8f45bea20bd1c541adb0778d8e86c2e1854900523.json",
"objectKey": "df45fa697f19036987d5bfe10fdcfba6de6d5d93be8e406edfc43fcc13fedc33.json",
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@
"Action": "sqs:SendMessage",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"Role1ABCC5F0",
"Arn"
]
}
}
],
"Version": "2012-10-17"
Expand All @@ -54,13 +64,55 @@
"Action": "lambda:InvokeFunction",
"Effect": "Allow",
"Resource": "*"
},
{
"Action": "iam:*",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt": [
"Role1ABCC5F0",
"Arn"
]
}
}
],
"Version": "2012-10-17"
},
"Description": "",
"Path": "/"
}
},
"Role1ABCC5F0": {
"Type": "AWS::IAM::Role",
"Properties": {
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
}
},
"Parameters": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"version":"20.0.0"}
{"version":"21.0.0"}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
{
"version": "20.0.0",
"version": "21.0.0",
"testCases": {
"integ.managed-policy": {
"ManagedPolicyInteg/DefaultTest": {
"stacks": [
"aws-cdk-iam-managed-policy"
],
"diffAssets": false,
"stackUpdateWorkflow": true
"assertionStack": "ManagedPolicyInteg/DefaultTest/DeployAssert",
"assertionStackName": "ManagedPolicyIntegDefaultTestDeployAssert27007DC6"
}
},
"synthContext": {},
"enableLookups": false
}
}
Loading

0 comments on commit e6fd324

Please sign in to comment.