Skip to content

Commit

Permalink
feat(aws-iam): support maxSessionDuration for Role (#545)
Browse files Browse the repository at this point in the history
Allow specifying a maximum session duration for roles.

Fixes #543
  • Loading branch information
Elad Ben-Israel committed Aug 13, 2018
1 parent 488e65b commit a283a39
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 0 deletions.
34 changes: 34 additions & 0 deletions packages/@aws-cdk/aws-iam/lib/role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ export interface RoleProps {
* Acknowledging IAM Resources in AWS CloudFormation Templates.
*/
roleName?: string;

/**
* The maximum session duration (in seconds) that you want to set for the
* specified role. If you do not specify a value for this setting, the
* default maximum of one hour is applied. This setting can have a value
* from 1 hour (3600sec) to 12 (43200sec) hours.
*
* Anyone who assumes the role from the AWS CLI or API can use the
* DurationSeconds API parameter or the duration-seconds CLI parameter to
* request a longer session. The MaxSessionDuration setting determines the
* maximum duration that can be requested using the DurationSeconds
* parameter.
*
* If users don't specify a value for the DurationSeconds parameter, their
* security credentials are valid for one hour by default. This applies when
* you use the AssumeRole* API operations or the assume-role* CLI operations
* but does not apply when you use those operations to create a console URL.
*
* @link https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use.html
*/
maxSessionDurationSec?: number;
}

/**
Expand Down Expand Up @@ -85,11 +106,14 @@ export class Role extends Construct implements IIdentityResource, IPrincipal, ID
this.assumeRolePolicy = createAssumeRolePolicy(props.assumedBy);
this.managedPolicies = props.managedPolicyArns || [ ];

validateMaxSessionDuration(props.maxSessionDurationSec);

const role = new cloudformation.RoleResource(this, 'Resource', {
assumeRolePolicyDocument: this.assumeRolePolicy as any,
managedPolicyArns: undefinedIfEmpty(() => this.managedPolicies),
path: props.path,
roleName: props.roleName,
maxSessionDuration: props.maxSessionDurationSec
});

this.roleArn = role.roleArn;
Expand Down Expand Up @@ -140,3 +164,13 @@ function createAssumeRolePolicy(principal: PolicyPrincipal) {
.addPrincipal(principal)
.addAction(principal.assumeRoleAction));
}

function validateMaxSessionDuration(duration?: number) {
if (duration === undefined) {
return;
}

if (duration < 3600 || duration > 43200) {
throw new Error(`maxSessionDuration is set to ${duration}, but must be >= 3600sec (1hr) and <= 43200sec (12hrs)`);
}
}
59 changes: 59 additions & 0 deletions packages/@aws-cdk/aws-iam/test/test.role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,64 @@ export = {
}));

test.done();
},

'maxSessionDuration': {

'is not specified by default'(test: Test) {
const stack = new Stack();
new Role(stack, 'MyRole', { assumedBy: new ServicePrincipal('sns.amazonaws.com') });
expect(stack).toMatch({
Resources: {
MyRoleF48FFE04: {
Type: "AWS::IAM::Role",
Properties: {
AssumeRolePolicyDocument: {
Statement: [
{
Action: "sts:AssumeRole",
Effect: "Allow",
Principal: {
Service: "sns.amazonaws.com"
}
}
],
Version: "2012-10-17"
}
}
}
}
});
test.done();
},

'can be used to specify the maximum session duration for assuming the role'(test: Test) {
const stack = new Stack();

new Role(stack, 'MyRole', { maxSessionDurationSec: 3700, assumedBy: new ServicePrincipal('sns.amazonaws.com') });

expect(stack).to(haveResource('AWS::IAM::Role', {
MaxSessionDuration: 3700
}));

test.done();
},

'must be between 3600 and 43200'(test: Test) {
const stack = new Stack();

const assumedBy = new ServicePrincipal('bla');

new Role(stack, 'MyRole1', { assumedBy, maxSessionDurationSec: 3600 });
new Role(stack, 'MyRole2', { assumedBy, maxSessionDurationSec: 43200 });

const expected = (val: any) => `maxSessionDuration is set to ${val}, but must be >= 3600sec (1hr) and <= 43200sec (12hrs)`;
test.throws(() => new Role(stack, 'MyRole3', { assumedBy, maxSessionDurationSec: 60 }), expected(60));
test.throws(() => new Role(stack, 'MyRole4', { assumedBy, maxSessionDurationSec: 3599 }), expected(3599));
test.throws(() => new Role(stack, 'MyRole5', { assumedBy, maxSessionDurationSec: 43201 }), expected(43201));

test.done();
}
}

};

0 comments on commit a283a39

Please sign in to comment.