Automated IAM Clean-up

Cloud Engineering

Cisco ISE

1. Project Description

1.1 Background

1.2 Description of the business and Cloud benefits examined

1.3 Cloud deployment plan and strategy

1.4 DevOps/DevSecOps recommendations*

1.5 High availability and fault tolerance recommendations*

1.6 Business continuity and disaster recovery recommendations*

1.7 Threat Modeling and Mitigation*

Use Scenarios

External Dependencies

Internal Dependencies

Implementation Assumptions

External Security Notes

Internal Security Notes

Trust Levels

Entry Points

Assets

Data Flow Diagrams

Threats

1.8 Compliance requirements

2. Cloud Solution Architecture or Implementation Solution

2.1 Security Use cases

2.2 Security Requirements

2.3 Security Architecture & Building Blocks

2.4 Cloud Security Architecture and Network Topology

2.5 Security Architectural Characteristics*

2.6 Incident detection and Response Strategies

2.7 Applied Security Design Patterns and Best Practices (Optional)

2.8 Guidance for Security & Compliance assessments

2.9 Security Testing*

3. Conclusions and Recommendations

4. References

5. Annexes

           5.1 Lambda-iam-user-cleanup.py

           5.2 Iam-user-cleanup-lambda.yaml

Automated IAM Clean-up

Final Report

1. Project Description

1.1 Background

Identity and Access Management (IAM) ensures that users are given sufficient levels of access to cloud resources and no more. As companies grow, the number of IAM users and access keys increases but they often overlook when there is a need to review and scale down, such as when employees leave the companies or a particular access key is no longer required. This poses a security risk to the company cloud infrastructure as unused users or keys can be exploited to illegally access the servers, and with privilege escalations in case the users being exploited have too much access, they can severely damage the company system or extract sensitive data for ransoms.

Automated IAM Clean-up addresses the security problem of unused IAM users and access keys by periodically checking the status of IAM users and associated access keys and sending the report to designated emails. With predetermined conditions, idle users can be automatically deleted from the system and administrators can see the output from an automatically generated report.

1.2 Description of the business and Cloud benefits examined

Leaving individuals with access to critical accounts can result in serious problems. The solution to this is access management automation to keep track of user access and remove IDs when necessary. In Cloud an IAM is an ID, it provides access privileges to applications, data, and functionality. Many businesses still rely on manual IAM management either due to budget constraints or complacency.

Examples of organizations that may benefit from Automated IAM Clean-up may be an organization with high turnover, those with a large list of contractors, or a University. Looking at the University example, they constantly have a large number, sometimes in the 1000s, of students graduating, leaving, transferring, etc. To manually remove each student IAM would not only be taxing an individual, it is prone to errors. Automating the removal process will negate the threat of possible missing a students IAM access privileges leading to security issues.

There is currently a rapid proliferation of various identities associated with cloud service environments. Simply, the more cloud services used by an organization, the more identities are provisioned for these environments. Identity and access management (IAM) management has become increasingly more difficult.

Improper de-provisioning of IAM roles for former employees or students Software as a Service (SaaS) accounts shows a lack of control over account lifecycle. Taking all of these into consideration, IAM Automated Cleanup project will be beneficial within large organizations where manual checks would lead to mistakes and exposures.

1.3 Cloud deployment plan and strategy

We will need an AWS account and particularly following services: CloudWatch Events & Logs, SNS, IAM, Lambda & S3

CloudWatch Events will trigger the lambda function based on predefined conditions. CloudWatch Logs will monitor and log the lambda function executions. SNS will deliver email notifications of new Access Reports to users that subscribe to the topic. IAM will be used to determine access to resources, with the goal of achieving least privilege permissions. It will grant access to the S3 bucket to view reports and also access to managing the lambda function, events and logs. Lambda function will be the main idea in this architecture and will retrieve and analyze IAM users and access keys and add them to an access report based on determined conditions. S3 will be used to store the Access Report logs in a centralized location.

1.4 DevOps/DevSecOps recommendations*

CloudWatch and CloudTrail of AWS should be enabled to use the IAM Cleanup tool. Tool should leverage these services to monitor and log efficiently and create reports for deserted users. There is no particular requirement for Lambda function deployment since it would be very basic and compatible in every possible situation when it is properly deployed.

1.5 High availability and fault tolerance recommendations*

The IAM Cleanup uses various AWS services that already offer high availability such as CloudWatch, SNS, Lambda & S3. For example:

●      CloudWatch Logs and Events are managed services that capture logs and fire events at scheduled intervals. There is no server to manage.

●      SNS is a publish-subscribe service maintained by Amazon, provides a reliable mechanism for our script to execute and inform IT admins promptly at the end of its execution.

●      Lambda is a serverless function as a service, also managed by Amazon. This gives an advantage that the script can run reliably and predictably, without us worrying about server resources.

●      S3 is an object storage service with high availability, durability and infinite scalability. The final reports in S3 are, therefore, always accessible.

As a result, the Automated IAM Cleanup is highly available and fault tolerant by design, since all of its components are managed and maintained by AWS.  

1.6 Business continuity and disaster recovery recommendations*

Given a scenario that a University runs a web application to manage students’ course registrations and materials at www.example.com. When a staff in the IT department leaves and his IAM user, which originally has a very broad permission policy, is not cleaned up, the result is the system is vulnerable to IAM-related attacks. In this case, the attackers can either bring down the system, or cause damage to existing data, resulting in system downtime and potential data loss. Two BC & DR solution strategies that minimize the impacts of such incidents are Warm Standby and Multi-Site.

Warm Standby: also called an active-passive setup where there is a scaled-down, fully functional, standby infrastructure in another Region. This strategy decreases the time to recovery because the application is always running in another Region. When there is an incident in the production infrastructure, the standby, scaled-down infrastructure can take over and handle traffic. It also can scale up to meet the higher traffic from the production site.

(Hararei, n.d.)

As such, the RTO can be very fast as traffic can be redirected to the standby stack within 15 minutes.  RPO will also be very short, ranging from a few minutes to under 3 hours, as the database server in the standby stack is a replication of the primary database in the production stack. In case an incident occurs, RPO is the time it takes to reverse replicate from the standby database to the primary database.

Multi-Site: Also called an active-active setup which runs a fully set-up, fully functional, and fully scaled copy of production infrastructure in another region. To prepare, a fully scaled version of production infrastructure is set up and running in another region, ready to take traffic without any scaling up required.

(Hararei, n.d.)

Recovery: when there is an incident in the production infrastructure, it just takes an DNS swapping to bring up the system.

(Hararei, n.d.)

As such, the RTO can be real-time.  RPO will also be very quick, in minutes,  as the database is an active replica of the primary database.

1.7 Threat Modeling and Mitigation*

Use Scenarios

ID - Description

  • 1 - Insecure S3 bucket policy
  • 2 - Unprotected AWS root user access of IAM user
  • 3 - Vulnerable lambda function implementation
  • 4 - Use IAM to control access on S3 and Amazon SNS
  • 5 - Ensure S3 reports are not publicly accessible

External Dependencies

The External Dependency lists dependencies on Cloud services that can impact security. These are assumptions that are made about their usage or behavior. Inconsistencies can lead to security weaknesses.

ID - Description

  • 1 - restrict the serview in your vpc: you services should restrict with your selected vpc so that it can’t be accessible from outside the network.
  • 2 - restrict the service in using the availability zone: when you deploy the services you should restrict the service by availability zone.
  • 3 - implement the least-privilege access:When you grant permissions, you decide who receives them, which topics the permissions are for, and specific API actions that you want to allow for these topics. Implementing the principle of least privilege is important to reducing security risks.
  • 4 - Implement server-side encryption:To mitigate data leakage issues, use encryption at rest to encrypt your messages using a key stored in a different location from the location that stores your messages. Server-side encryption (SSE) provides data encryption at rest.

Internal Dependencies

The Internal Dependency lists dependencies within Cloud services that can impact security. These are assumptions that are made about their usage or behavior. Inconsistencies can lead to security weaknesses.

ID -Description

  • 1 - S3 bucket implementation
  • 2 - AWS root user access
  • 3 - Lambda function
  • 4 - CloudWatch
  • 5 - Amazon SNS

Implementation Assumptions

ID - Description

  • 1 - ensure that lambda function is not vulnerable and provides proper output
  • 2 - ensure that AWS root users are protected
  • 3 - ensure that you have role based IAM user access with least access permission
  • 4 - ensure that your S3 buckets are not publicly accessible and restrict the file upload permission on S3
  • 5 - restrict the access privilege of the service for IAM users.
  • 6 - restrict the IAM access for CloudWatch

External Security Notes

ID - Description

  • 1 - Lambda function code update must only be granted to authorized IAM users, to prevent unauthorized modifications to the function code
  • 2 - Limit the function execution permission to the limited only administrator user
  • 3 - S3 reports should be restricted to the administrator users

Internal Security Notes

The Internal Security Notes table includes security information that is relevant only to a person reading the threat model, and can be used to explain choices and design decisions that are made.

ID - Description

  • 1 - In the lambda function, the IAM user selection criteria function should be bulletproof. if they found any inaccuracy then the wrong user can be cleaned up.
  • 2 - configure the notify email on sns for sending the the log  who have the admin permission
  • 3 - Use multi-factor authentication (MFA) with each account.
  • 4 - Use SSL/TLS to communicate with AWS resources.
  • 5 - Set up API and user activity logging with AWS CloudTrail.
  • 6 - Use AWS encryption solutions, along with all default security controls within AWS services.
  • 7 - Use advanced managed security services such as Amazon Macie, which assists in discovering and securing personal data that is stored in Amazon S3.

Trust Levels

The Trust Levels table describes privilege levels that are associated with Entry Points and Protected Resources.

ID - Name - Description

  • 1 - End user client - All general user of aws IAM service
  • 2 - Administrator console - IAM user who have the all administrative privilege
  • 3 - Internal consumer applications - N/A
  • 4 - Public consumer applications - N/A
  • 5 - Entry point 1 - N/A

Entry Points

Not applicable as the Automated IAM Cleanup is run automatically at scheduled intervals, without user’s interaction. There is also no external entity as the script interacts with other AWS services and does not communicate with external service providers.

Assets

The Assets table describes the data or functionality that the component needs to protect. It lists the minimum Access Category that should be allowed to access the resource.

ID - Name - Description

  • 1 - IAM User list - This list should be accessible only by admin users
  • 2 - Lambda function - Lambda function should be restricted to only dev users
  • 3 - Cloudwatch log - Cloudwatch log read access should be restricted to only dev users
  • 4 - SNS - SNS subscription should be accessible only by admin users
  • 5 - S3 bucket - S3 bucket read access  should be accessible only by admin users. No write access should be granted to any user.

Threats

The Threats to the component are listed in the Threats tables. These do not imply vulnerabilities. Rather, they are actions that a malicious external entity might try to do to exploit the system. (Hewko, 2021)

Threats

ID - 1

  • Name - CloudWatch Event Execution Integrity
  • Threat Action - Cloud watch events being tampered so that the IAM cleanup function frequency is reduced, or stopped altogether.  
  • STRIDE Classification - Tampering
  • Mitigated? - Yes
  • Known Countermeasure - Enforce proper access control for CloudWatch events management using IAM roles.
  • Assets - CloudWatch Events

ID - 2

  • Name - Lambda Function Integrity
  • Threat Action - Lambda function being altered so that user cleanup doesn’t get executed properly
  • STRIDE Classification - Tampering
  • Mitigated? - Yes
  • Known Countermeasure - Enforce proper access control for Lambda function editing using IAM roles. Logging Lambda executions into CloudWatch logs to ensure functionality is correct. Logging any changes with CloudTrail to ensure accountability.
  • Assets - Lambda Function

ID - 3

  • Name - Cloudwatch Log Integrity
  • Threat Action - CloudWatch logs being tampered with or deleted to obfuscate any malicious activity.
  • STRIDE Classification - Tampering
  • Mitigated? - Yes
  • Known Countermeasure - Enforce proper access control for CloudWatch events management using IAM roles. Write access only granted to services, denied for all users.  
  • Assets - Cloudwatch Logs

ID - 4

  • Name - S3 Bucket Confidentiality
  • Threat Action - S3 Bucket cleanup reports being leaked to unauthorized users.
  • STRIDE Classification - Elevation of Privileges
  • Mitigated? - Yes
  • Known Countermeasure - Enforce proper access control for S3 reading using IAM roles.
  • Assets - S3 Bucket

1.8 Compliance requirements

IAM Automated Cleanup does not have a specific compliance requirement since it utilizes mainly the IAM & CloudWatch functionality. Third-party audit reports can be done using AWS Artifact (AWS, 2022).

2. Cloud Solution Architecture or Implementation Solution

2.1 Security Use cases

Security use cases are clear in the architecture. IAM cleanup project will retrieve and analyze IAM users and access keys to evaluate these users according to predetermined conditions. Idle users will be removed automatically and the whole process would be logged and reported to administrators, execution logs will be stored by CloudWatch. This will decrease the chance of overlooking old accounts and thus limit the risk of credential exposure, bad access etc. in the long run drastically. All activity within the system will be logged into CloudTrail for accountability. The reports generated by the system will be securely stored and encrypted.

2.2 Security Requirements

The security requirements that must be addressed with the proposed solution are the following:

●       Identity & Access Management (IAM) & Identity Provisioning: The solution must provide a means through which access to resources can be managed and provisioned securely by granting or revoking roles.

●      Least privileged access: This is one of the most critical security requirements, access control will be managed in such a way that only the required capabilities are granted for each role. Additionally, any role that is determined as non-needed any longer will be automatically removed or included in a report to be considered for removal by an administrator.

●      Separation of duties: Access control must be managed so that key management access is segregated into key administrator roles.

●      Storage and compute isolation: Any application data and compute resources cannot be accessible to any co-residents.  

●      Storage data protection: Any sensitive data should be securely stored and encrypted.

●      Logging and auditing: There should be a record of events in the system, so that each action is recorded and can be traced to its source. Audit data should be protected so that it can’t be tampered to assure accountability and compliance.

The following is the Shared Security Responsibility Model (Nagappan, 2022) for the service model proposed:

Responsibility - Owner

  • Information and data - Client
  • Accounts and Identities - Client
  • Identity and directory infrastructure - Shared
  • Applications - Shared
  • Network Controls - Cloud Provider
  • Operating System - Cloud Provider
  • Physical Hosts - Cloud Provider
  • Physical Network - Cloud Provider
  • Physical Datacenter - Cloud Provider
  • Physical Datacenter (Database) - Client

2.3 Security Architecture & Building Blocks

The cloud provider of choice will be AWS, the main reason being it has all the services required to implement the desired solution.

The following are the building blocks of the proposed solution:

CloudWatch Events: The role of this component is to trigger the lambda function based on predefined conditions; the event will trigger chronologically.

CloudWatch Logs: This component addresses the monitoring and logging portion of the solution architecture; execution logs of the lambda function will be sent to CloudWatch logs. This will enable having a record of any potential issues or bugs with the lambda function and make it easier to troubleshoot and fix.

SNS: The role of this component is to deliver email notifications of new Access Reports to users that subscribe to the topic. Only users with the appropriate roles can subscribe to the notifications, to ensure data protection and access control.

SNS Read Access Policy:

IAM: This component addresses the access control aspect of the solution, IAM will be used to determine access to resources, with the goal of achieving least privileged access. It will be used to grant access to the S3 bucket to view access reports, access to managing the Lambda Function, CloudWatch Events, and viewing the CloudWatch logs. It will also be used to define the roles that resources will have, such as enabling Lambda access to write into the S3 bucket. The type of access control model that will be used will be a Role Based Access Control (RBAC), roles will be assigned and segregated based on job functions.

Lambda Function: The lambda function will retrieve and analyze IAM users and access keys and add them to an access report based on predetermined conditions. This ensures high availability and fault tolerance since Lambda runs its functions in multiple availability zones in case of a service interruption in a single zone or a failure of any given compute instance.

Lambda-User-Cleanup policy

This policy is granted to the lambda function and it enables write access into the S3 Bucket. Following least privileged access, the only action granted is PutObject, since that is the only action the lambda function needs to write the reports.

Iam-lambda-dev-access policy

The Iam-lambda-dev-access policy gives developers the ability to view and edit the lambda function, making adjustments as needed.

Lambda Function Configuration

The yaml file included variables such as MinAgeKeyToReport and MinAgeKeysToDisable which need to be adjusted per organizational demands. One organization may want to delete IAM roles after 100 days while another may want the roles to be unaccessed for 20 days. This depends on the organizations and should be adjusted by developers as required. An excerpt of the variables form the iam-user-cleanup yaml file is included below

MinAgeKeysToReport:
   Type: Number
   Default: 30
   MinValue: 0
   Description: The minimum age in days of access keys to include in the report.
 MinAgeKeysToDisable:
   Type: Number
   Default: 0
   MinValue: 0
   Description: The minimum age in days of access keys to disable. Set to '0' to disablethis function.
 MinAgeKeysToDelete:
   Type: Number
   Default: 0
   MinValue: 0
   Description: The minimum age in days of access keys to delete. Set to '0' to disablethis function.
 MinAgeUnusedUsersToReport:
   Type: Number
   Default: 30
   MinValue: 0
   Description: The minimum age in days of unused users to include in the report.

As a high availability and fault tolerance measure, the lambda function has been deployed to multiple regions, to cover for the potential event where an AWS region fails due to a disaster event.

S3: This component will be used to store the Access Report logs in a centralized location. The S3 bucket can be configured so that there is no public access and only users with the required roles can have read access, only the lambda function will have permission to write into it so that any potential regulatory compliance can be achieved, and secure isolation is enforced. Lifecycle configuration can also be added.

S3 bucket storage lifecycle:

We also focused on the cost optimization pillar of the AWS well-architected framework when it came to storing the data accumulated. The cost optimization pillar focuses on avoiding unnecessary costs. Key topics include understanding spending over time and controlling fund allocation, selecting resources of the right type and quantity, and scaling to meet business needs without overspending.


This Lambda function should run daily in order to maintain accurate management of IAM roles within the AWS environment. This data must be managed appropriately to manage costs.

Transition actions define when objects transition to another storage class. In our case objects are transitioned to the S3 Standard-IA storage class 60 days after creating them, transitioned to Glacier Flexible retrieval at 180 days, and Glacier Deep Archiver at 360 days. We also enabled amazon S3 versioning and so set up transition actions for noncurrent versions as well. archive objects to the S3 Glacier Flexible Retrieval storage class one year after creating them.


Expiration actions are actions defined when objects expire. Amazon S3 deletes expired objects on your behalf. In our case it is set to 720 where the newest noncurrent version will be retained and all other noncurrent versions will be permanently deleted.

We also created a read access policy for the S3 bucket. When we created the IAM policy we followed the least privilege principle, or granting only the permissions required to perform a task. We determined that users (and roles) needed the ability to read the S3 bucket but nothing else.

S3 read access policy:

2.4 Cloud Security Architecture and Network Topology

The following is a diagram describing the architecture of the solution:

Security architecture measures:

Network Isolation: For this solution, there isn’t a requirement for isolating resources by implementing VPCs and subnets. The main reason being the serverless nature of the solution. AWS Lambda service runs functions on a secure VPC by default, this VPC is owned by AWS Lambda (AWS, 2022).

Another important isolation component is that there are no exposed endpoints for the AWS Lambda function, the only way for it to run is either via testing by development users with the assigned role, or by being triggered by the CloudWatch Event.

For Storage isolation, S3 access is protected by IAM and accessible only through the AWS console, all public access for the S3 bucket is blocked. The only write access is possessed by the Lambda function.  

Data protection mechanisms and key management services: The only data storage in the solution is the reports that are stored in the S3 bucket. AWS S3 service provides several data protection features built in by default, like 99.999999999% durability and 99.99% availability of objects over a given year (AWS, 2022). Encryption is configured both at rest and in transit.

S3 Bucket Encryption

S3 Lifecycle Management

Another data protection mechanism in use is Encryption at Rest in AWS Lambda (AWS, 2022). The required access keys for writing into the S3 bucket are encrypted using AWS Key Management Service with a customer managed key.

Lambda Access Key Encryption using KMS

In order to decrypt the encrypted access_key and key_id we had to import b64decode from base 64. This was accomplished in python by including the following in our script.

from base64 import b64decode


The access key and key id are encrypted. When called in the python script the code is decrypted and stored outside of the function handler so that they are decrypted only once per container.

Python lambda-iam-user-cleanup script showing decryption of encrypted_access_key and encrypted_key_id.

encrypted_access_key = str(os.environ['encrypted_access_key'])
encrypted_key_id = str(os.environ['encrypted_key_id'])

# Decrypt code should run once and variables stored outside of the function
# handler so that these are decrypted once per container
access_key = boto3.client('kms').decrypt(
   CiphertextBlob=b64decode(encrypted_access_key),
   EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')
   
# Decrypt code should run once and variables stored outside of the function
# handler so that these are decrypted once per container
key_id = boto3.client('kms').decrypt(
   CiphertextBlob=b64decode(encrypted_key_id),
   EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')

Once the values are decrypted they can be used as the aws_access_key and aws_secret_access_key in the Boto3 sessions and the S3 resource can be created from the session. An excerpt of the python script showing this is below.

   #Creating Session With Boto3.
   session = boto3.Session(
   aws_access_key_id=key_id,
   aws_secret_access_key=access_key
   )
   #Creating S3 Resource From the Session.
   s3 = session.resource('s3')
   timeObj = datetime.datetime.now()
   object = s3.Object('iam-lambda-cleanup-cscie49', str(timeObj) + '-iam-cleanup-report.txt')
   result = object.put(Body=report)

Access controls and Identity & Access management services: This is handled by AWS IAM, ensuring least privileged access, so that users are only granted the bare minimum access required to fulfill their functionalities.

The type of access control enforced will be Role Based Access Control, which restricts user access to an object based on the assigned role. These roles are defined based on job functions (Nagappan, 2022).

The following are the two types of roles based on functions within the system.

The first is the admin role which has access to viewing the S3 bucket and subscribing to SNS notifications.

The second is the developer role which has access to editing the lambda function and read access for CloudWatch logs.

Monitoring/logging: CloudWatch logs will be used to log all execution information coming from the cleanup Lambda function.

Cloudwatch log activity

Successful function execution log event

Failed function execution log event, having logs can make it easier for developer users to troubleshoot and diagnose any unusual activity.

Auditing controls: All activities within the system will be logged with CloudTrail, so that non repudiation can be guaranteed

Example of a record of the lambda function code being updated, having CloudTrail in place ensures that actions within the system can have accountability.

2.6 Incident detection and Response Strategies

The NIST’s CyberSecurity framework can be used as the primary strategy to detect and respond to incidents regarding unauthorized access from old IAM users and access keys.

●      Identify

○      Unauthorized access is defined as when old IAM users or access keys that should no longer be granted access to the cloud infrastructure are still able to do so. The users either left the organization or their permissions were revoked due to department transfers, or for other reasons. The access keys that were created a long time ago and are not actively tracking at the moment. When these resources are inactive for a long time, they are at risk of being misused or leaked and should be monitored carefully. Examples of such incidents are: running a script on EC2 instances, modification of IAM policies, modification of security groups, etc…

●      Protect

○      The Automated IAM Clean-Up in this report provides a proactive protection operation that periodically scans and cleans up all inactive users and keys, preventing them from accessing the system illegally.

●      Detect

○      When incidents occur, Amazon GuardDuty can detect backdoors to EC2 instances, privilege escalation and unauthorized access. There are also tools such AWS CloudTrails that trace all the API calls in AWS that we can use to detect incidents regarding IAM users and keys.

●      Respond

○      The immediate actions to respond to IAM-related threats are to disable the users and keys, effectively shutting down the unauthorized access. Then, an analysis should be conducted to review the areas that were accessed and what damages have been done. We should also review the IAM Clean-up function to tweak certain parameters such as the Inactivity Window to further harden its security control.

●      Recover

○      Unauthorized accesses, particularly those using highly privileged permissions, might cause considerable damages to the cloud infrastructure. To recover from such incidents, continuous backups and snapshots are key to ensure the smooth recovery. Periodically reviewing IAM users and keys should also be considered to proactively prevent these incidents.

2.7 Applied Security Design Patterns and Best Practices (Optional)

The following best practices should be followed for IAM

●      Lock AWS root account’s access keys, which are the most powerful keys that have full access to the Cloud infrastructure.

●      Avoid using passwords or access keys. Instead, use IAM roles to access AWS services, which are more secure and have no long-term credentials to maintain.

●      Grant the least possible permissions to users requesting access. These make sure that persons are able to perform the necessary actions.

●      Use AWS managed policies, which are predefined, managed and controlled by AWS for a certain set of permissions.

●      Validate IAM policies before and during their lifecycle, to make sure that the policies are up-to-date and suitable for what they are for.

●      Create a strong password policy for all users

●      Enable Multi-Factor Authentication, which requires IAM users to do 2-step authentication with either a hardware or software token generator.

●      Enforce a policy to block sharing access keys

●      Rotate access keys regularly

●      Clean up obsolete and unnecessary users and keys

●      Continuously monitor activities in AWS Cloud by using tools such as CloudTrails, Cloudwatch, GuardDuty.

(AWS, 2022)

2.8 Guidance for Security & Compliance assessments

Security assessments for IAM can be done as follows:

●      Identify all IAM actions and policies that are not resource-constrained. Usually, an action should be tied to specific AWS resources. Wildcard (*) actions should be flagged out for more extensive monitoring and audits. Examples: s3:GetObject, ssm:GetParameter, or secretsmanager:GetSecretValue which are considered as data exfiltration commands.

●      Watch out for IAM Roles that can be assumed by AWS Compute Services such as EC2, ECS, EKS, or Lambda, as they can pose greater risk than user-defined roles, particularly resources that are configured to access the Internet.

Compliance assessments can be done with AWS Audit Manager, which automatically runs compliance monitoring scripts to ensure IAM credentials such as users and access keys comply with relevant industry standards or specific compliance programmes.

2.9 Security Testing*

Penetration Testing such as IAM privilege escalation can be used to challenge the IAM system. The following scenarios are examples:

●      An attacker using a user’s credential with permissions such as iam:PassRole and ec2:RunInstances permissions can create an EC2 instance and pass an existing role to it. They can then login to the instance and request the associated AWS keys from the EC2 instance metadata, which ultimately gives them access to all the permissions that the associated instance profile has.

●      An attacker with the iam:CreateAccessKey can create an access key for other users and assume the other users’ roles to access AWS services.

3. Conclusions and Recommendations

Project scenario requirements are to showcase “Cloud Security” and demonstrate overall learning of security concepts applied to real-world Cloud deployment scenarios. Our project, Automated IAM User Cleanup, involves deploying an AWS Lambda function with AWS Serverless Application Model (SAM) to provide regular insights on IAM Users and AWS Access Key usage within an account. This allows organizations to secure their AWS account aligned with the AWS Well-Architected Framework. Most specifically, the Security Pillar which focuses on the protection of information and systems. This pillar specifically mentions managing user permission which the automation of IAM cleanup improves dramatically. Upon implementation, results identify orphaned IAM users and AWS Access Keys, take action to remove IAM Users automatically, and AWS Access Keys no longer needed, and reduce identity sprawl. This adequately meets the first part of the stated project scenario requirement. The project showcases Cloud Security and demonstrates our overall learning of security concepts. In addition to the aforementioned, we also implemented the following best practice security strategies. We blocked all public access to the S3 bucket, used KMS in the lambda python script to encrypt the access key and key id both in the script and in transit to ensure storage protection. Additionally, we used EventBridge to deliver real-time data from AWS to the AWS Lambda function to ensure isolation by removing the need of having any exposed lambda endpoints. The logging was addressed by recording all lambda execution logs into CloudWatch.CloudTrail was implemented to fulfill the requirement of being able to audit any action within the system since it records all event history as well as the user or service that initiates it. This history is searchable and downloadable which creates a trail for an AWS admin user to monitor and audit.

This project may be applied in real-world cloud deployment solutions for organizations with a high turnover. It is highly undesirable to have employees who have left an organization to maintain access and privileges. Universities would also have a use case scenario for this Automated IAM User Cleanup solution as they constantly have students leaving. To manually remove and track perhaps hundreds of students each year is near impossible.

Taking a closer look at the organization's scenario and reviewing the possible situations where Automated IAM User Cleanup is not implemented, employees and contractors are the number one cause of data breaches, and the majority (56%) of security professionals say insider threats are on the rise according to a Haystax, a threat prevention company, survey. Privileged users with access to sensitive information are thought to pose the most significant threat (60%), with consultants and contractors a close second (57%), followed by regular employees (51%). These threats are believed to be on the rise due to a few reasons: insufficient data protection solutions and strategies, an increased number of devices with access to sensitive data, and more employees, contractors, and partners accessing the network. The City of Calgary in Canada was sued for $92.9 million in 2017 for a privacy breach impacting more than 3,700 of its employees. Disgruntled employees may cause situations of similar consequence. Perhaps they feel unjustly let go, overlooked for a promotion, or even attempting to gain a competitive advantage for a new employer (RedTeamSecurity, 2022).

Automating the reduction of employees removed from an organization using this architecture will assure that individuals’ IAM credentials are removed appropriately and reduce the risk of this occurring dramatically.

There are many additional examples of similar situations: the former network administrator for the city of San Francisco held the city's systems hostage by refusing to give up the passwords. Why? He felt his supervisors were incompetent. A network engineer for oil and gas company EnerVest found out he would be fired and sabotaged the company's systems by returning them to their original factory settings. A hospital worker stole forms containing patient information and is thought to have filed fraudulent income tax returns. Keep in mind that it is more difficult to detect and prevent internal attacks than external attacks. Haystax’s respondents would agree with this at a rate of 66%. These are just a few of many thousands of real-world examples which could have been prevented if their credentials had been correctly removed. (RedTeamSecurity, 2022)

Our recommendation for all organizations is to follow security best practices and use cases in AWS Identity, and Access Management provided by AWS. Continue to use least privilege IAM policies, lock your AWS account root user access keys, use access levels to review IAM permissions, enable MFA, and follow Security best practices in IAM. AWS provides these best practices and, if followed, will help secure AWS resources. In addition to AWS best practices, we would recommend Automating IAM User Cleanup to avoid a potential security risk at a high financial cost.

4. References

●      Nagappan, Ramesh. (2022). CSCI E-49 Lecture 2: Evolution of Cloud Computing, Delivery Models, Shared Responsibilities, Design Principles, Anti-patterns. Retrieved april 27, 2022, from Harvard University Extension School Cloud Security Canvas: https://canvas.harvard.edu

●      Amazon Web Services. (2022). DEPLOYING IAM LAMBDA CLEANUP WITH AWS SAM. Well Architected Labs. Retrieved april 7 2022, from https://wellarchitectedlabs.com/security/200_labs/200_automated_iam_user_cleanup/1_lambda_iam_cleanup/

●      Hararei Solutions. (sd). Warm Standby Strategy for Disaster Recovery . Retrieved April 27, 2022, from https://hararei.com/pages/aws-dr-warm-standby.html

●      Amazon Web Services. (2022). Compliance Validation for AWS Identity and Access Management. Retrieved april 7 2022, from https://docs.aws.amazon.com/IAM/latest/UserGuide/iam-compliance-validation.html

●      Hewko, A. (2021, september 2). What Is STRIDE Threat Modeling | Explanation and Examples. Software Secured. Retrieved may 1 2022, from https://www.softwaresecured.com/stride-threat-modeling/

●      Amazon Web Services. (2022). Data protection in Amazon S3. Retrieved april 27 2022, from  https://docs.aws.amazon.com/AmazonS3/latest/userguide/DataDurability.html

●      Amazon Web Services. (2022). Data protection in AWS Lambda. Retrieved may 7 2022, from  https://docs.aws.amazon.com/lambda/latest/dg/security-dataprotection.html

●      Amazon Web Services. (2022). Using AWS Lambda environment variables - AWS Lambda. Retrieved may 7 2022, from https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html

●      Amazon Web Services. (2022). Networking and VPC Configurations. Retrieved april 27 2022, from https://docs.aws.amazon.com/lambda/latest/operatorguide/networking-vpc.html

●       Nagappan, Ramesh. (2022). CSCI E-49 Week 9 Lecture 1: Access Control Strategies. Retrieved April 17, 2022, from Harvard University Extension School Cloud Security Canvas: https://canvas.harvard.edu

●      Dao, V. (2020, December 7). Using AWS KMS In AWS Lambda. Retrieved May 8, 2022, from https://dev.to/vumdao/using-aws-kms-in-aws-lambda-2jm2

●      Amazon Web Services. (2022). Using Versioning in S3 Buckets. Retrieved may 7 2022, from https://docs.aws.amazon.com/AmazonS3/latest/userguide/Versioning.html

●      Amazon Web Services. (2022). Security best practices in IAM. Retrieved may 7 2022, from https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege

●      Amazon Web Services (2022). AWS Lambda Features. Retrieved April 26 2022, from Serverless Computing - AWS Lambda Features - Amazon Web Services

●      Tozzy,C ( 2022, march 18). Compare High Availability vs Fault Tolerance in AWS. Retrieved April 20 2022 https://www.techtarget.com/searchcloudcomputing/tip/Compare-high-availability-vs-fault-tolerance-in-AWS

●      Amazon Web Services (2022). Disaster Recovery Workloads on AWS. Retrieved April 20 2022, from https://docs.aws.amazon.com/whitepapers/latest/disaster-recovery-workloads-on-aws/disaster-recovery-options-in-the-cloud.html

●      RedTeamSecurity (2022), Danger In Your Ranks: 7 Times Employees Caused Damaging Data Breaches. Retrieved April 27 2022, from https://www.redteamsecure.com/blog/danger-ranks-7-times-employees-caused-data-breaches

●      Amazon Web Services. (2022), What is IAM?. Retrieved April 26, 2022, from https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.htm

●      Amazon Web Services (2022). AWS Well-Architected. Retrieved April 26 2022, from https://aws.amazon.com/architecture/well-architected/?wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&wa-lens-whitepapers.sort-order=desc

5. Annexes

5.1 Lambda-iam-user-cleanup.py

Lambda-iam-user-cleanup.py
import json
import boto3
import datetime
import time
import os
import datetime
from base64 import b64decode

minAgeKeysToReport = int(os.environ['MinAgeKeysToReport'])
minAgeKeysToDisable = int(os.environ['MinAgeKeysToDisable'])
minAgeKeysToDelete = int(os.environ['MinAgeKeysToDelete'])
minAgeUnusedUsersToReport = int(os.environ['MinAgeUnusedUsersToReport'])
minAgeUnusedUsersToDisable = int(os.environ['MinAgeUnusedUsersToDisable'])
minAgeUnusedUsersToDelete = int(os.environ['MinAgeUnusedUsersToDelete'])
minAgeRolesToReport = int(os.environ['MinAgeRolesToReport'])
minAgeRolesToDisable = int(os.environ['MinAgeRolesToDisable'])
minAgeRolesToDelete = int(os.environ['MinAgeRolesToDelete'])
CleanupAnalyzerArn = os.environ['CleanupAnalyzer']
encrypted_access_key = str(os.environ['encrypted_access_key'])
encrypted_key_id = str(os.environ['encrypted_key_id'])

# Decrypt code should run once and variables stored outside of the function
# handler so that these are decrypted once per container
access_key = boto3.client('kms').decrypt(
   CiphertextBlob=b64decode(encrypted_access_key),
   EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')
   
# Decrypt code should run once and variables stored outside of the function
# handler so that these are decrypted once per container
key_id = boto3.client('kms').decrypt(
   CiphertextBlob=b64decode(encrypted_key_id),
   EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']}
)['Plaintext'].decode('utf-8')

def lambda_handler(event, context):
   client = boto3.client('iam')
   
   today = datetime.datetime.now()
   
   report = ''
   
   # Iterate over all the users
   userResponse = client.list_users()
   for u in userResponse['Users']:
       # Work out when the user was last used
       passwordLastUsed = u['PasswordLastUsed'] if 'PasswordLastUsed' in u else u['CreateDate']
       daysSinceUsed = (today - passwordLastUsed.replace(tzinfo=None)).days
       deleted = False
       # If the feature is enabled (>0) and the days since used > delete setting
       if (minAgeUnusedUsersToDelete > 0 and daysSinceUsed >= minAgeUnusedUsersToDelete):
           # Delete the user
           client.delete_user(UserName=u['UserName'])
           report += 'User {0} has not logged in since {1} and has been deleted\n'.format(
               u['UserName'],
               passwordLastUsed)
           deleted = True
       # else, if the features is enabled and the days since used > disable setting
       elif (minAgeUnusedUsersToDelete > 0 and daysSinceUsed >= minAgeUnusedUsersToDisable):
           # Force a password reset
           client.update_login_profile(
               UserName=u['UserName'],
               PasswordResetRequired=True)
           report += 'User {0} has not logged in since {1} and has been disabled\n'.format(
               u['UserName'],
               passwordLastUsed)
       # else, if the days since used > report setting
       elif (daysSinceUsed >= minAgeUnusedUsersToReport):
           # add the user to the report
           report += 'User {0} has not logged in since {1} and needs cleanup\n'.format(
               u['UserName'],
               passwordLastUsed)
       
       # If we haven't deleted the user
       if not deleted:
           # Get their access keys
           keysResponse = client.list_access_keys(
               UserName=u['UserName'])
           # For each of their keys
           for k in keysResponse['AccessKeyMetadata']:
               # Get when the key was last used
               lastUsedResponse = client.get_access_key_last_used(AccessKeyId=k['AccessKeyId'])
               keyLastUsed = lastUsedResponse['AccessKeyLastUsed']['LastUsedDate'] if 'LastUsedDate' inlastUsedResponse['AccessKeyLastUsed'] else k['CreateDate']
               daysSinceUsed = (today - keyLastUsed.replace(tzinfo=None)).days
               # If the feature is enabled (>0) and the days since used > delete setting
               if (minAgeKeysToDelete > 0 and daysSinceUsed >= minAgeKeysToDelete):
                   # Delete the key
                   client.delete_user(UserName=u['UserName'])
                   response = client.delete_access_key(
                       UserName=u['UserName'],
                       AccessKeyId=k['AccessKeyId']
                   )
                   report += 'User {0} has not used access key {1} in since {2} and has been deleted\n'.format(
                       u['UserName'],
                       k['AccessKeyId'],
                       keyLastUsed)
               # else, if the features is enabled and the days since used > disable setting
               elif (minAgeKeysToDisable > 0 and daysSinceUsed >= minAgeKeysToDisable):
                   # Force a password reset
                   response = client.update_access_key(
                       UserName=u['UserName'],
                       AccessKeyId=k['AccessKeyId'],
                       Status='Inactive'
                   )
                   report += 'User {0} has not used access key {1} in since {2} and has been disabled\n'.format(
                       u['UserName'],
                       k['AccessKeyId'],
                       keyLastUsed)
               # else, if the days since used > report setting
               elif (daysSinceUsed >= minAgeKeysToReport):
                   # add the user to the report
                   report += 'User {0} has not used access key {1} in since {2} and needs cleanup\n'.format(
                       u['UserName'],
                       k['AccessKeyId'],
                       keyLastUsed)
       
   # Iterate over all the roles
   rolesResponse = client.list_roles(MaxItems=1000)
   for r in [r for r in rolesResponse['Roles'] if '/aws-service-role/' not in r['Path'] and '/service-role/' not inr['Path']]:
       # We need to create a job to generate the last access report
       jobId = client.generate_service_last_accessed_details(Arn=r['Arn'])['JobId']
       
       roleAccessDetails = client.get_service_last_accessed_details(JobId=jobId)
       jobAttempt = 0
       while roleAccessDetails['JobStatus'] == 'IN_PROGRESS':
           time.sleep(jobAttempt*2)
           jobAttempt = jobAttempt + 1
           roleAccessDetails = client.get_service_last_accessed_details(JobId=jobId)
       if roleAccessDetails['JobStatus'] == 'FAILED':
           report += 'Unable to retrive last access report for role {0}. No action taken.\n'.format(
                   r['Arn'])
       else:
           lastAccessedDates = [a['LastAuthenticated'] for a in roleAccessDetails['ServicesLastAccessed'] if'LastAuthenticated' in a]
           if not lastAccessedDates:
               report += 'Role {0} has no access history. No action taken.\n'.format(
                       r['Arn'])
           else:
               roleLastUsed = min(lastAccessedDates)
               daysSinceUsed = (today - roleLastUsed.replace(tzinfo=None)).days
               # If the feature is enabled (>0) and the days since used > delete setting
               if (minAgeRolesToDelete > 0 and daysSinceUsed >= minAgeRolesToDelete):
                   # Delete the user
                   client.delete_role(RoleName=r['RoleName'])
                   report += 'Role {0} has not been used since {1} and has been deleted\n'.format(
                       r['Arn'],
                       roleLastUsed)
               # else, if the features is enabled and the days since used > disable setting
               elif (minAgeRolesToDelete > 0 and daysSinceUsed >= minAgeRolesToDelete):
                   # Force a password reset
                   client.attach_role_policy(
                       PolicyArn='arn:aws:iam::aws:policy/AWSDenyAll',
                       RoleName=r['RoleName'],
                   )
                   report += 'Role {0} has not been used since {1} and has been disabled\n'.format(
                       r['Arn'],
                       roleLastUsed)
               # else, if the days since used > report setting
               elif (daysSinceUsed >= minAgeRolesToReport):
                   # add the user to the report
                   print(r)
                   report += 'Role {0} has not been used since {1} and needs cleanup\n'.format(
                       r['Arn'],
                       roleLastUsed)

   # Get all findings from access analyzer if enabled
   if CleanupAnalyzerArn:
       analyzerClient = boto3.client('accessanalyzer')
       findings = analyzerClient.list_findings(analyzerArn=CleanupAnalyzerArn)
       filteredFindings = [f for f in findings['findings'] if f['status'] == 'ACTIVE'] # filter just active ones
       for f in filteredFindings:
           report += 'Principal {0} has permission to {1} against {2} {3}. See finding {4} in IAM Access Analyzer for more information or to archive this finding.\n'.format(
           f['principal'],
           f['action'],
           f['resourceType'],
           f['resource'],
           f['id'])
   
   if not report:
       report = 'IAM user cleanup successfully ran. No outstanding users found.'
   else:
       report = 'IAM user cleanup successfully ran.\n\n' + report
   
   snsClient = boto3.client('sns')
   snsClient.publish(
       TopicArn=os.environ['TopicTarget'],
       Subject='IAM user cleanup from ' +  context.invoked_function_arn.split(":")[4],
       Message=report
   )
   
   #Creating Session With Boto3.
   session = boto3.Session(
   aws_access_key_id=key_id,
   aws_secret_access_key=access_key
   )
   #Creating S3 Resource From the Session.
   s3 = session.resource('s3')
   txt_data = b'This is the content of the file uploaded from python boto3 asdfasdf'
   timeObj = datetime.datetime.now()
   object = s3.Object('iam-lambda-cleanup-cscie49', str(timeObj) + '-iam-cleanup-report.txt')
   result = object.put(Body=report)

5.2 Iam-user-cleanup-lambda.yaml

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: >-
 You will be billed for the AWS resources used if you create a stack from this
 template.
 Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 
 Licensed under the Apache License, Version 2.0 (the "License").
 You may not use this file except in compliance with the License.
 A copy of the License is located at
 
     https://www.apache.org/licenses/LICENSE-2.0
 
 or in the "license" file accompanying this file. This file is distributed
 on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 express or implied. See the License for the specific language governing
 permissions and limitations under the License.
Parameters:
 NotificationEmail:
   Type: String
   AllowedPattern: (?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
   ConstraintDescription: Please enter a valid email.
   Description: The email address to send the list of affected users.
 MinAgeKeysToReport:
   Type: Number
   Default: 30
   MinValue: 0
   Description: The minimum age in days of access keys to include in the report.
 MinAgeKeysToDisable:
   Type: Number
   Default: 0
   MinValue: 0
   Description: The minimum age in days of access keys to disable. Set to '0' to disable this function.
 MinAgeKeysToDelete:
   Type: Number
   Default: 0
   MinValue: 0
   Description: The minimum age in days of access keys to delete. Set to '0' to disable this function.
 MinAgeUnusedUsersToReport:
   Type: Number
   Default: 30
   MinValue: 0
   Description: The minimum age in days of unused users to include in the report.
 MinAgeUnusedUsersToDisable:
   Type: Number
   Default: 0
   Description: The minimum age in days of unused users to disable. Set to '0' to disable this function.
 MinAgeUnusedUsersToDelete:
   Type: Number
   Default: 0
   MinValue: 0
   Description: The minimum age in days of unused users to delete. Set to '0' to disable this function.
 MinAgeRolesToReport:
   Type: Number
   Default: 30
   MinValue: 0
   Description: The minimum age in days of unused users to include in the report.
 MinAgeRolesToDisable:
   Type: Number
   Default: 0
   Description: The minimum age in days of unused users to disable. Set to '0' to disable this function.
 MinAgeRolesToDelete:
   Type: Number
   Default: 0
   MinValue: 0
   Description: The minimum age in days of unused users to delete. Set to '0' to disable this function.
 AnalyzerType:
   Type: String
   AllowedValues: ['NONE','ACCOUNT','ORGANIZATION']
   Default: 'ACCOUNT'
   Description: IAM Access Analyzer produces findings on the external availability of resources within yourAWS account. If this account is the root account of an organization or the delegated administrator selectORGANIZATION, otherwise select ACCOUNT or NONE to skip this check.
Conditions:
 CreateAnalyzer: !Not [!Equals [!Ref AnalyzerType, NONE]]
Resources:
 # SNS Topic
 UserCleanupTopic:
   Type: 'AWS::SNS::Topic'
 UserCleanupSubscription:
   Type: AWS::SNS::Subscription
   Properties:
     Endpoint: !Ref NotificationEmail
     Protocol: email
     TopicArn: !Ref UserCleanupTopic
# IAM role required for Lambda to access IAM and to send the email from SNS
 UserCleanupLambdaExecutionRole:
     Type: 'AWS::IAM::Role'
     Properties:
       AssumeRolePolicyDocument:
         Version: 2012-10-17
         Statement:
           Effect: Allow
           Principal:
             Service:
               lambda.amazonaws.com
           Action:
             - 'sts:AssumeRole'
       Path: /
       Policies:
         - PolicyDocument:
             Statement:
               - Action:
                   - 'logs:CreateLogGroup'
                   - 'logs:CreateLogStream'
                   - 'logs:PutLogEvents'
                 Effect: Allow
                 Resource: 'arn:aws:logs:*:*:*'
               - Action:
                   - 'iam:DeleteAccessKey'
                   - 'iam:DeleteUser'
                   - 'iam:GetAccessKeyLastUsed'
                   - 'iam:GetUser'
                   - 'iam:ListAccessKeys'
                   - 'iam:ListUsers'
                   - 'iam:UpdateAccessKey'
                   - 'iam:UpdateUser'
                   - 'iam:ListRoles'
                   - 'iam:GenerateServiceLastAccessedDetails'
                   - 'iam:GetServiceLastAccessedDetails'
                   - 'iam:DeleteRole'
                   - 'iam:AttachRolePolicy'
                   - 'access-analyzer:ListFindings'
                 Effect: Allow
                 Resource: '*' # Explicit that this includes all users
               - Action:
                 - 'sns:Publish'
                 Effect: Allow
                 Resource: !Ref UserCleanupTopic
             Version: 2012-10-17
           PolicyName: sec-UserCleanupRole
 # Lambda function to audit the credentials
 UserCleanupLambda:
   Type: AWS::Serverless::Function
   Properties:
     Handler: lambda-iam-user-cleanup.lambda_handler
     Runtime: python3.8
     Role: !GetAtt UserCleanupLambdaExecutionRole.Arn
     Environment:
       Variables:
         MinAgeKeysToReport: !Ref MinAgeKeysToReport
         MinAgeKeysToDisable: !Ref MinAgeKeysToDisable
         MinAgeKeysToDelete: !Ref MinAgeKeysToDelete
         MinAgeUnusedUsersToReport: !Ref MinAgeUnusedUsersToReport
         MinAgeUnusedUsersToDisable: !Ref MinAgeUnusedUsersToDisable
         MinAgeUnusedUsersToDelete: !Ref MinAgeUnusedUsersToDelete
         MinAgeRolesToReport: !Ref MinAgeRolesToReport
         MinAgeRolesToDisable: !Ref MinAgeRolesToDisable
         MinAgeRolesToDelete: !Ref MinAgeRolesToDelete
         TopicTarget: !Ref UserCleanupTopic
         CleanupAnalyzer: !If [CreateAnalyzer, !Ref CleanupAnalyzer, '']
     CodeUri: lambda-iam-user-cleanup.py
     Timeout: 300
 # CloudWatch event to trigger this
 UserCleanupTrigger:
   Type: AWS::Events::Rule
   Properties:
     ScheduleExpression: 'cron(0 12 * * ? *)'
     State: 'ENABLED'
     Targets:
       -
         Arn: !GetAtt UserCleanupLambda.Arn
         Id: 'LambdaTarget'
 PermissionForEventsToInvokeLambda:
   Type: AWS::Lambda::Permission
   Properties:
     FunctionName: !Ref UserCleanupLambda
     Action: 'lambda:InvokeFunction'
     Principal: 'events.amazonaws.com'
     SourceArn: !GetAtt UserCleanupTrigger.Arn
 # Access analyzer to look at accessability of resources external to organization or account
 CleanupAnalyzer:
   Condition: CreateAnalyzer
   Type: AWS::AccessAnalyzer::Analyzer
   Properties:
     Type: !Ref AnalyzerType

Contact Me

Lets Work Together

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Stay in touch

Ready to Talk

Feel free to contact me