misc: made project key and data key creation concurrency safe

This commit is contained in:
Sheen Capadngan
2024-07-30 23:03:53 +05:30
committed by =
parent d41011e056
commit 4d032cfbfa
+34 -13
View File
@@ -134,9 +134,12 @@ export const kmsServiceFactory = ({
org = await orgDAL.findById(orgId); org = await orgDAL.findById(orgId);
} else { } else {
org = await orgDAL.findById(orgId);
if (!org.kmsDefaultKeyId) {
const keyId = await orgDAL.transaction(async (tx) => { const keyId = await orgDAL.transaction(async (tx) => {
org = await orgDAL.findById(orgId, tx);
if (org.kmsDefaultKeyId) {
return org.kmsDefaultKeyId;
}
const key = await generateKmsKey({ const key = await generateKmsKey({
isReserved: true, isReserved: true,
orgId: org.id, orgId: org.id,
@@ -151,18 +154,13 @@ export const kmsServiceFactory = ({
tx tx
); );
await keyStore.setItemWithExpiry( await keyStore.setItemWithExpiry(`${KeyStorePrefixes.WaitUntilReadyKmsOrgKeyCreation}${orgId}`, 10, "true");
`${KeyStorePrefixes.WaitUntilReadyKmsOrgKeyCreation}${orgId}`,
10,
"true"
);
return key.id; return key.id;
}); });
return keyId; return keyId;
} }
}
} finally { } finally {
await lock?.release(); await lock?.release();
} }
@@ -192,7 +190,6 @@ export const kmsServiceFactory = ({
kmsId: kmsDoc.orgKms.id kmsId: kmsDoc.orgKms.id
}); });
// fetch encryptedDataKey straight from kmsDoc by joining it in query :D
const orgKmsDataKey = await orgKmsDecryptor({ const orgKmsDataKey = await orgKmsDecryptor({
cipherTextBlob: kmsDoc.orgKms.encryptedDataKey cipherTextBlob: kmsDoc.orgKms.encryptedDataKey
}); });
@@ -326,9 +323,12 @@ export const kmsServiceFactory = ({
org = await orgDAL.findById(orgId); org = await orgDAL.findById(orgId);
} else { } else {
org = await orgDAL.findById(orgId);
if (!org.kmsEncryptedDataKey) {
const orgDataKey = await orgDAL.transaction(async (tx) => { const orgDataKey = await orgDAL.transaction(async (tx) => {
org = await orgDAL.findById(orgId, tx);
if (org.kmsEncryptedDataKey) {
return;
}
const dataKey = randomSecureBytes(); const dataKey = randomSecureBytes();
const kmsEncryptor = await encryptWithKmsKey( const kmsEncryptor = await encryptWithKmsKey(
{ {
@@ -358,6 +358,7 @@ export const kmsServiceFactory = ({
return dataKey; return dataKey;
}); });
if (orgDataKey) {
return orgDataKey; return orgDataKey;
} }
} }
@@ -401,6 +402,11 @@ export const kmsServiceFactory = ({
project = await projectDAL.findById(projectId); project = await projectDAL.findById(projectId);
} else { } else {
const kmsKeyId = await projectDAL.transaction(async (tx) => { const kmsKeyId = await projectDAL.transaction(async (tx) => {
project = await projectDAL.findById(projectId, tx);
if (project.kmsSecretManagerKeyId) {
return project.kmsSecretManagerKeyId;
}
const key = await generateKmsKey({ const key = await generateKmsKey({
isReserved: true, isReserved: true,
orgId: project.orgId, orgId: project.orgId,
@@ -464,6 +470,12 @@ export const kmsServiceFactory = ({
project = await projectDAL.findById(projectId); project = await projectDAL.findById(projectId);
} else { } else {
const projectDataKey = await projectDAL.transaction(async (tx) => {
project = await projectDAL.findById(projectId, tx);
if (project.kmsSecretManagerEncryptedDataKey) {
return;
}
const dataKey = randomSecureBytes(); const dataKey = randomSecureBytes();
const kmsEncryptor = await encryptWithKmsKey({ const kmsEncryptor = await encryptWithKmsKey({
kmsId: kmsKeyId kmsId: kmsKeyId
@@ -473,9 +485,13 @@ export const kmsServiceFactory = ({
plainText: dataKey plainText: dataKey
}); });
await projectDAL.updateById(projectId, { await projectDAL.updateById(
projectId,
{
kmsSecretManagerEncryptedDataKey: cipherTextBlob kmsSecretManagerEncryptedDataKey: cipherTextBlob
}); },
tx
);
await keyStore.setItemWithExpiry( await keyStore.setItemWithExpiry(
`${KeyStorePrefixes.WaitUntilReadyKmsProjectDataKeyCreation}${projectId}`, `${KeyStorePrefixes.WaitUntilReadyKmsProjectDataKeyCreation}${projectId}`,
@@ -483,6 +499,11 @@ export const kmsServiceFactory = ({
"true" "true"
); );
return dataKey; return dataKey;
});
if (projectDataKey) {
return projectDataKey;
}
} }
} finally { } finally {
await lock?.release(); await lock?.release();