我想在通过自定义资源初始化cdk堆栈时将初始admin用户保存到dynamodb表中,并且不确定安全传递该用户值的最佳方法。我的代码现在使用dotEnv
并将值作为环境变量传递:
import * as cdk from "@aws-cdk/core";
import * as lambda from "@aws-cdk/aws-lambda";
import * as dynamodb from "@aws-cdk/aws-dynamodb";
import * as customResource from "@aws-cdk/custom-resources";
require("dotenv").config();
export class CDKBackend extends cdk.Construct {
public readonly handler: lambda.Function;
constructor(scope: cdk.Construct, id: string) {
super(scope, id);
const tableName = "CDKBackendTable";
// not shown here but also:
// creates a dynamodb table for tableName and a seedData lambda with access to it
// also some lambdas for CRUD operations and an apiGateway.RestApi for them
const seedDataProvider = new customResource.Provider(this, "seedDataProvider", {
onEventHandler: seedDataLambda
});
new cdk.CustomResource(this, "SeedDataResource", {
serviceToken: seedDataProvider.serviceToken,
properties: {
tableName,
user: process.env.ADMIN,
password: process.env.ADMINPASSWORD,
salt: process.env.SALT
}
});
}
}
这段代码可以工作,但是以这种方式通过ADMIN, ADMINPASSWORD和SALT是安全的吗?这种方法与从AWS秘密管理器访问这些值之间的安全性差异是什么?我还计划在为所有新用户生成passwordDigest值时使用该SALT值,而不仅仅是这个admin用户。
properties
值将在部署时评估。因此,它们将成为CloudFormation模板的一部分。CloudFormation模板可以在AWS Web控制台中查看。因此,从安全角度来看,以这种方式传递机密是值得怀疑的。
解决这个问题的一种方法是使用AWS秘密管理器存储秘密。aws-cdk
与它的秘密管理器有很好的集成。一旦你创建了一个秘密,你可以通过:
const mySecretFromName = secretsmanager.Secret.fromSecretNameV2(stack, 'SecretFromName', 'MySecret')
不幸的是,在AWS自定义资源中不支持解析CloudFormation动态引用。您可以在lambda (seedDataLambda
)中自己解决这个秘密。SqlRun存储库提供了一个示例。
请记住为自定义资源lambda (seedLambda
)授予secret访问权限,例如
secret.grantRead(seedDataProvider.executionRole)