Scheduling Notifications for Rotating Old IAM Access Keys https://www.aaronmedacco.com/blog/post/2017/07/22/scheduling-notifications-for-unused-iam-access-keys
aws events put-targets --rule Rotate-Old-Access-Keys-Notification-Scheduler --targets "Id"="1","Arn"="ARN"
aws lambda add-permission --function-name rotate-old-access-keys-notification-sender --statement-id LambdaPermission --action "lambda:InvokeFunction" --principal events.amazonaws.com --source-arn ARN
aws events put-rule --name Rotate-Old-Access-Keys-Notification-Scheduler --schedule-expression "rate(1 day)"
aws lambda create-function --function-name rotate-old-access-keys-notification-sender --runtime nodejs6.10 --handler index.handler --role ARN --zip-file fileb://index.zip --timeout 30
var AWS = require("aws-sdk");
var iam = new AWS.IAM();
var sns = new AWS.SNS();
var daysBeforeRotationRequired = 90; // Number of days from access creation before action is taken on access keys.
exports.handler = (event, context, callback) => {
var listUsersParams = {};
iam.listUsers(listUsersParams, function(err, data) {
if (err) {
console.log(err, err.stack);
}
else {
for (var i = 0; i < data.Users.length; i++) {
var userName = data.Users[i].UserName;
var listAccessKeysParams = { UserName: userName };
iam.listAccessKeys(listAccessKeysParams, function(err, data) {
if (err) {
console.log(err, err.stack);
}
else {
for (var j = 0; j < data.AccessKeyMetadata.length; j++) {
var accessKeyId = data.AccessKeyMetadata[j].AccessKeyId;
var creationDate = data.AccessKeyMetadata[j].CreateDate;
var accessKeyUserName = data.AccessKeyMetadata[j].UserName;
var now = new Date();
var whenRotationShouldOccur = dateAdd(creationDate, "day", daysBeforeRotationRequired);
if (now > whenRotationShouldOccur) {
var message = "You need to rotate access key: " + accessKeyId + " for user: " + accessKeyUserName
console.log(message);
var publishParams = {
Message: message,
Subject: "Access Keys Need Rotating For User: " + accessKeyUserName,
TopicArn: "Topic ARN"
};
sns.publish(publishParams, context.done);
}
else {
console.log("No access key rotation necessary for: " + accessKeyId + "for user: " + accessKeyUserName);
}
}
}
});
}
}
});
};
var dateAdd = function(date, interval, units) {
var ret = new Date(date); // don't change original date
switch(interval.toLowerCase()) {
case 'year' : ret.setFullYear(ret.getFullYear() + units); break;
case 'quarter': ret.setMonth(ret.getMonth() + 3*units); break;
case 'month' : ret.setMonth(ret.getMonth() + units); break;
case 'week' : ret.setDate(ret.getDate() + 7*units); break;
case 'day' : ret.setDate(ret.getDate() + units); break;
case 'hour' : ret.setTime(ret.getTime() + units*3600000); break;
case 'minute' : ret.setTime(ret.getTime() + units*60000); break;
case 'second' : ret.setTime(ret.getTime() + units*1000); break;
default : ret = undefined; break;
}
return ret;
}
aws iam attach-role-policy --policy-arn ARN --role-name rotate-old-access-keys-notification-role
aws iam create-role --role-name rotate-old-access-keys-notification-role --assume-role-policy-document file://role-trust-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
aws iam create-policy --policy-name rotate-old-access-keys-notification-policy --policy-document file://iam-policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": [
"Your Topic ARN"
]
},
{
"Effect": "Allow",
"Action": [
"iam:ListAccessKeys",
"iam:ListUsers"
],
"Resource": [
"*"
]
}
]
}
aws sns subscribe --topic-arn ARN --protocol email --notification-endpoint Email
aws sns create-topic --name IAM-Access-Key-Rotation-Topic