我可以将相同的策略分配给 AWS IAM 中的用户和角色,当我尝试使用角色连接到 RDS 时,它不起作用,但当我使用用户连接时,它确实起作用。我对角色和用户设置了相同的策略,并设置了我的代码,以便我可以在直接使用用户和承担角色的用户之间切换。唯一的区别是 cred 变量中是否有凭证属性。
用户和代入角色都可以访问SecretsManager,但只有用户可以访问RDS数据库。 RDS 日志显示该角色的 PAM 身份验证失败,因此出现了问题。
const cred = false ? {} : {
credentials: await new STSClient({ region: "us-east-2" }).send(new AssumeRoleCommand({
RoleArn: "... valid role arn ...",
RoleSessionName: "Test",
})).then(role => {
if (!role.Credentials?.AccessKeyId || !role.Credentials.SecretAccessKey) throw "failed to assume role";
console.log("Role Assumed");
return {
accessKeyId: role.Credentials.AccessKeyId,
secretAccessKey: role.Credentials.SecretAccessKey,
sessionToken: role.Credentials.SessionToken,
};
})
};
const { SecretString: normalstr } = await new SecretsManagerClient({ region: "us-east-2", ...cred }).send(new GetSecretValueCommand({
SecretId: "... valid secret arn ...",
VersionStage: "AWSCURRENT",
}));
const env = JSON.parse(normalstr);
const rds = new Signer({
region: env.DB_REGION,
hostname: env.DB_HOSTNAME,
port: +env.DB_PORT,
username: auth.user,
...cred
});
const db = await getPrismaClient(rds);
db.customer.findUnique({...});
// The role gets: User `user` was denied access on the database `db.public`
// The user gets a successful query
要记住的重要一点是,我对用户和角色有相同的策略,并且两者都可以访问秘密管理器,这是策略中的项目之一,但只有用户可以访问数据库,这是政策中的其他项目。
问题最终是因为我试图使用 URL 对象构造连接字符串。不知何故,它对角色造成了破坏,但对用户却没有造成影响。我通过记录密码(签名的 RDS 令牌)然后将其直接粘贴到 PG Admin 中来解决这个问题。成功了。
长话短说:不要这样做:
const dburl = new URL("https://dud");
dburl.username = username;
dburl.password = password;
dburl.hostname = DB_HOSTNAME;
dburl.port = DB_PORT;
dburl.pathname = DB_NAME;
dburl.search = "?sslmode=require";
// cut https: and set the protocol
return "postgres:" + dburl.toString().slice(6);
这样做:
return `postgres://${encodeURIComponent(username)}:${encodeURIComponent(password)}@${DB_HOSTNAME}:${DB_PORT}/${encodeURIComponent(DB_NAME)}?sslmode=require`