Created
January 18, 2020 22:19
-
-
Save hendrixroa/0cb51450fdb8016799e2fddb1f070c7b to your computer and use it in GitHub Desktop.
Script to rotate aws keys in Gitlab CI/CD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as aws from 'aws-sdk'; | |
import { RequestAPI, RequiredUriUrl } from 'request'; | |
import * as request from 'request-promise-native'; | |
// Update the credentials depending of environment | |
aws.config.update({ | |
accessKeyId: process.env[`AWS_KEY_${process.env.STAGE}`], | |
region: process.env.AWS_DEFAULT_REGION, | |
secretAccessKey: process.env[`AWS_SECRET_${process.env.STAGE}`], | |
}); | |
const iam = new aws.IAM(); | |
const user: string = 'deploy'; | |
export class Rotater { | |
private client: RequestAPI< | |
request.RequestPromise, | |
request.RequestPromiseOptions, | |
RequiredUriUrl | |
>; | |
constructor() { | |
this.client = request.defaults({ | |
baseUrl: 'https://gitlab.com/api/v4', | |
headers: { | |
'PRIVATE-TOKEN': process.env.GITLAB_REGISTRY, | |
}, | |
json: true, | |
}); | |
} | |
public async createAccessKey() { | |
const newerKey: any = await iam | |
.createAccessKey({ | |
UserName: user, | |
}) | |
.promise(); | |
return newerKey.AccessKey; | |
} | |
public async makeInactiveAccesskey(keyId: string) { | |
await iam | |
.updateAccessKey({ | |
AccessKeyId: keyId, | |
Status: 'Inactive', | |
UserName: user, | |
}) | |
.promise(); | |
} | |
public async deleteOldKey(oldKey: string) { | |
await iam | |
.deleteAccessKey({ | |
AccessKeyId: oldKey, | |
UserName: user, | |
}) | |
.promise(); | |
} | |
public async getAccessKey() { | |
const keys: any = await iam | |
.listAccessKeys({ | |
UserName: user, | |
}) | |
.promise(); | |
return keys.AccessKeyMetadata[0]; | |
} | |
public getDiffDays(dateStart: Date, dateEnd: Date): number { | |
return Math.floor( | |
(Date.UTC(dateEnd.getFullYear(), dateEnd.getMonth(), dateEnd.getDate()) - | |
Date.UTC( | |
dateStart.getFullYear(), | |
dateStart.getMonth(), | |
dateStart.getDate(), | |
)) / | |
(1000 * 60 * 60 * 24), | |
); | |
} | |
public async rotate() { | |
const userKey: any = await this.getAccessKey(); | |
const diffdays: number = this.getDiffDays( | |
new Date(userKey.CreateDate), | |
new Date(), | |
); | |
// tslint:disable-next-line: no-console | |
console.log(`The current age of key is ${diffdays}`); | |
if (diffdays >= 90) { | |
// Create newer key, make inactive old key, delete old key | |
const newerKey: any = await this.createAccessKey(); | |
await this.makeInactiveAccesskey(userKey.AccessKeyId); | |
await this.deleteOldKey(userKey.AccessKeyId); | |
// Update the gitlab environment variables for each projects target per environment [staging, prod] | |
const projectIds: any = JSON.parse(process.env | |
.TARGET_PROJECT_IDS as string); | |
const stage: string = process.env.STAGE as string; | |
for (const id of projectIds) { | |
const payloadKey: any = { | |
environment_scope: '*', | |
key: `AWS_KEY_${stage}`, | |
masked: false, | |
protected: false, | |
value: newerKey.AccessKeyId, | |
variable_type: 'env_var', | |
}; | |
const resultUpdateKey = await this.client.put( | |
`/projects/${id}/variables/AWS_KEY_${stage}`, | |
{ | |
body: payloadKey, | |
}, | |
); | |
const payloadSecret: any = { | |
environment_scope: '*', | |
key: `AWS_SECRET_${stage}`, | |
masked: false, | |
protected: false, | |
value: newerKey.SecretAccessKey, | |
variable_type: 'env_var', | |
}; | |
const resultUpdateSecret = await this.client.put( | |
`/projects/${id}/variables/AWS_SECRET_${stage}`, | |
{ | |
body: payloadSecret, | |
}, | |
); | |
// tslint:disable-next-line: no-console | |
console.log( | |
`The key has been updated successfully for the project_id ${id}`, | |
); | |
} | |
} else { | |
// tslint:disable-next-line: no-console | |
console.log(`The current key (${diffdays} days) age is safe`); | |
process.exit(0); | |
} | |
} | |
} | |
const rotater: Rotater = new Rotater(); | |
rotater | |
.rotate() | |
.then() | |
.catch(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment