Empowering users to manage their accounts

IAM is a very resourceful service. When used properly, the combination of user groups and security policies lets you implement very complex rules. We will create a new managed policy to grant the necessary permissions and attach it to a new group of which all users should be a part.

We will do that in the iam-groups-cf-template.py script we just created in the previous section:

  1. Reopen the script in your editor.
  2. We will first need to import a number of classes. At the top of the script, at around Line 5, we are going to add to the troposphere import section, the import of Join and Ref as follows:
from troposphere import ( 
    Template, 
    Join, 
    Ref, 
) 
  1. In addition, at around Line 11, we are going to add a new class in the troposphere.iamimport section to create a managed policy as follows:
from troposphere.iam import ( 
    Group, 
    ManagedPolicy, 
) 
  1. We will also import a number of classes from the Amazon Web Access Control Subsystem (awacs) library previously used with our Jenkins template. After the troposphere.iam import section, add the following:
from awacs.aws import ( 
    Action, 
    Allow, 
    Policy, 
    Statement, 
) 
  1. We can now create a new IAM managed policy. We will add a new resource of type ManagedPolicy. We will call it CommonIamPolicy as in the end, every human user should have it. In addition to defining its name, we will provide a description and start our policy document which contains the list of permissions to add to the specified users or groups. After the creation of the admin group resource, add the following:
t.add_resource(ManagedPolicy( 
    "CommonIamPolicy", 
    Description="Common policy to manage IAM resources", 
    PolicyDocument=Policy( 
  1. The first parameter of that policy is the specification of the version:
        Version="2012-10-17", 

 

  1. The next parameter of the policy document will be the definition of the different statements. Because admins don't want to be in the business of managing every aspect of the user accounts, our policy will give enough permissions for any user to self-manage their credentials, MFA devices, and access keys. For that, we will create a first statement that will give anyone the permissions to read the password policy defined in the previous section, and list MFA devices (physical and virtual) and users. After the definition of the version of the policy document, add the following:
        Statement=[ 
            Statement( 
                Effect=Allow, 
                Action=[ 
                    Action("iam", "GetAccountPasswordPolicy"), 
                    Action("iam", "ListUsers"), 
                    Action("iam", "ListMFADevices"), 
                    Action("iam", "ListVirtualMFADEvices") 
                ], 
                Resource=["*"] 
            ), 
  1. Our next statement will allow users that don't have any MFA devices configured to create one. In that particular case, we want to restrict the resource only to the user who is making the change. For that, we will use the policy variable ${aws:username} and the pseudo parameterAWS::AccountId. You can read more about policy variables at http://amzn.to/2mYsltz. After the previous statement, add the following:
            Statement(
Effect=Allow,
Action=[
Action("iam", "CreateVirtualMFADevice")
],
Resource=[
Join(
"",
[
"arn:aws:iam::",
Ref("AWS::AccountId"),
":mfa/${aws:username}",
]
)
]
),
  1. We will now add a third statement. This statement will allow users to self-manage their passwords, MFA, and access keys. Here too, we will restrict those actions to the current user. Once that statement is complete, we will have all the permissions needed, we can complete the creation of that resource. After the previous statement, add the following:
            Statement(
Effect=Allow,
Action=[
Action("iam", "ChangePassword"),
Action("iam", "CreateAccessKey"),
Action("iam", "CreateLoginProfile"),
Action("iam", "DeleteAccessKey"),
Action("iam", "DeleteLoginProfile"),
Action("iam", "EnableMFADevice"),
Action("iam", "GetAccessKeyLastUsed"),
Action("iam", "GetLoginProfile"),
Action("iam", "GetUser"),
Action("iam", "ListAccessKeys"),
Action("iam", "UpdateAccessKey"),
Action("iam", "UpdateLoginProfile")
],
Resource=[
Join(
"",
[
"arn:aws:iam::",
Ref("AWS::AccountId"),
":user/${aws:username}",
]
)
]
),
]
)
))
  1. Now that our managed policy is completed, we are going to create a group and reference this policy. The group will be called AllUsers and, as its name suggests, should contain all human users. After the creation of the managed policy resource, add the following:
t.add_resource(Group( 
    "AllUsers", 
    GroupName="AllUsers", 
    ManagedPolicyArns=[ 
        Ref("CommonIamPolicy") 
    ] 
)) 

Our updated script is ready. It should look like this: http://bit.ly/2uHdsOk.

We can save the changes.

If you don't have the awacs library installed, you can install it with the following command:

$ pip install awacs  

We can now update our CloudFormation stack as follows:

$ python iam-groups-cf-template.py > iam-groups-cf.template
$ aws cloudformation update-stack 
      --stack-name iam-groups 
      --template-body file://iam-groups-cf.template 
      --capabilities CAPABILITY_NAMED_IAM  

As before, we can add users to that group with the following command:

$ aws iam add-user-to-group --user-name johndoe --group-name AllUsers  

Our user, John Doe, is now a member of both the AllUsers and Admin groups. In practice, at that point, being a member of both groups doesn't make a lot of sense since Admin John can already do everything he wants. This will change in the next section as we start incorporating restrictions on what users can do without a recent MFA.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset