in lib/open-pgp-key-pair.ts [111:190]
constructor(parent: Construct, name: string, props: OpenPGPKeyPairProps) {
super(parent, name);
const codeLocation = path.resolve(__dirname, 'custom-resource-handlers', 'bin', 'pgp-secret');
const fn = new lambda.SingletonFunction(this, 'Lambda', {
uuid: 'f25803d3-054b-44fc-985f-4860d7d6ee74',
description: 'Generates an OpenPGP Key and stores the private key in Secrets Manager and the public key in an SSM Parameter',
code: new lambda.AssetCode(codeLocation),
handler: 'index.handler',
timeout: Duration.seconds(300),
runtime: lambda.Runtime.NODEJS_12_X,
// add the layer that contains the GPG binary (+ shared libraries)
layers: [new lambda.LayerVersion(this, 'GpgLayer', {
code: lambda.Code.fromAsset(path.join(__dirname, 'custom-resource-handlers', 'layers', 'gpg-layer.zip')),
})],
});
fn.addToRolePolicy(new iam.PolicyStatement({
actions: [
'secretsmanager:CreateSecret',
'secretsmanager:GetSecretValue',
'secretsmanager:UpdateSecret',
'secretsmanager:DeleteSecret',
],
resources: [Stack.of(this).formatArn({
service: 'secretsmanager',
resource: 'secret',
sep: ':',
resourceName: `${props.secretName}-??????`,
})],
}));
// To allow easy migration from verison that handled the SSM parameter in the custom resource
fn.addToRolePolicy(new iam.PolicyStatement({
actions: ['ssm:DeleteParameter'],
resources: ['*'],
}));
if (props.encryptionKey) {
props.encryptionKey.addToResourcePolicy(new iam.PolicyStatement({
actions: ['kms:Decrypt', 'kms:GenerateDataKey'],
resources: ['*'],
principals: [fn.role!.grantPrincipal],
conditions: {
StringEquals: {
'kms:ViaService': `secretsmanager.${Stack.of(this).region}.amazonaws.com`,
},
},
}));
}
const secret = new cfn.CustomResource(this, 'Resource', {
provider: cfn.CustomResourceProvider.lambda(fn),
properties: {
resourceVersion: hashFileOrDirectory(codeLocation),
identity: props.identity,
email: props.email,
expiry: props.expiry,
keySizeBits: props.keySizeBits,
secretName: props.secretName,
keyArn: props.encryptionKey && props.encryptionKey.keyArn,
version: props.version,
description: props.description,
deleteImmediately: props.removalPolicy === OpenPGPKeyPairRemovalPolicy.DESTROY_IMMEDIATELY,
},
removalPolicy: openPgpKeyPairRemovalPolicyToCoreRemovalPolicy(props.removalPolicy),
});
secret.node.addDependency(fn);
this.credential = secretsManager.Secret.fromSecretAttributes(this, 'Credential', {
encryptionKey: props.encryptionKey,
secretArn: secret.getAtt('SecretArn').toString(),
});
this.principal = new ssm.StringParameter(this, 'Principal', {
description: `The public part of the OpenPGP key in ${this.credential.secretArn}`,
parameterName: props.pubKeyParameterName,
stringValue: secret.getAtt('PublicKey').toString(),
});
}