Update how credential data is saved in db when using aws secrets manager (#4271)

* Update how credential data is saved in db when using aws secrets manager

* Run lint-fix and update env example
This commit is contained in:
Ilango
2025-04-09 14:07:18 +05:30
committed by GitHub
parent 4277819c5f
commit 36870e94d4
3 changed files with 58 additions and 46 deletions
+22 -7
View File
@@ -543,6 +543,15 @@ const getEncryptionKey = async (): Promise<string> => {
return process.env.FLOWISE_SECRETKEY_OVERWRITE
}
try {
if (USE_AWS_SECRETS_MANAGER && secretsManagerClient) {
const secretId = process.env.SECRETKEY_AWS_NAME || 'FlowiseEncryptionKey'
const command = new GetSecretValueCommand({ SecretId: secretId })
const response = await secretsManagerClient.send(command)
if (response.SecretString) {
return response.SecretString
}
}
return await fs.promises.readFile(getEncryptionKeyPath(), 'utf8')
} catch (error) {
throw new Error(error)
@@ -561,18 +570,24 @@ const decryptCredentialData = async (encryptedData: string): Promise<ICommonObje
if (USE_AWS_SECRETS_MANAGER && secretsManagerClient) {
try {
const command = new GetSecretValueCommand({ SecretId: encryptedData })
const response = await secretsManagerClient.send(command)
if (encryptedData.startsWith('FlowiseCredential_')) {
const command = new GetSecretValueCommand({ SecretId: encryptedData })
const response = await secretsManagerClient.send(command)
if (response.SecretString) {
const secretObj = JSON.parse(response.SecretString)
decryptedDataStr = JSON.stringify(secretObj)
if (response.SecretString) {
const secretObj = JSON.parse(response.SecretString)
decryptedDataStr = JSON.stringify(secretObj)
} else {
throw new Error('Failed to retrieve secret value.')
}
} else {
throw new Error('Failed to retrieve secret value.')
const encryptKey = await getEncryptionKey()
const decryptedData = AES.decrypt(encryptedData, encryptKey)
decryptedDataStr = decryptedData.toString(enc.Utf8)
}
} catch (error) {
console.error(error)
throw new Error('Credentials could not be decrypted.')
throw new Error('Failed to decrypt credential data.')
}
} else {
// Fallback to existing code
+1
View File
@@ -9,6 +9,7 @@ PORT=3000
# SECRETKEY_AWS_ACCESS_KEY=<your-access-key>
# SECRETKEY_AWS_SECRET_KEY=<your-secret-key>
# SECRETKEY_AWS_REGION=us-west-2
# SECRETKEY_AWS_NAME=FlowiseEncryptionKey
# NUMBER_OF_PROXIES= 1
# CORS_ORIGINS=*
+35 -39
View File
@@ -59,7 +59,6 @@ import { StatusCodes } from 'http-status-codes'
import {
CreateSecretCommand,
GetSecretValueCommand,
PutSecretValueCommand,
SecretsManagerClient,
SecretsManagerClientConfig
} from '@aws-sdk/client-secrets-manager'
@@ -1394,6 +1393,29 @@ export const getEncryptionKey = async (): Promise<string> => {
if (process.env.FLOWISE_SECRETKEY_OVERWRITE !== undefined && process.env.FLOWISE_SECRETKEY_OVERWRITE !== '') {
return process.env.FLOWISE_SECRETKEY_OVERWRITE
}
if (USE_AWS_SECRETS_MANAGER && secretsManagerClient) {
const secretId = process.env.SECRETKEY_AWS_NAME || 'FlowiseEncryptionKey'
try {
const command = new GetSecretValueCommand({ SecretId: secretId })
const response = await secretsManagerClient.send(command)
if (response.SecretString) {
return response.SecretString
}
} catch (error: any) {
if (error.name === 'ResourceNotFoundException') {
// Secret doesn't exist, create it
const newKey = generateEncryptKey()
const createCommand = new CreateSecretCommand({
Name: secretId,
SecretString: newKey
})
await secretsManagerClient.send(createCommand)
return newKey
}
throw error
}
}
try {
return await fs.promises.readFile(getEncryptionKeyPath(), 'utf8')
} catch (error) {
@@ -1412,39 +1434,7 @@ export const getEncryptionKey = async (): Promise<string> => {
* @returns {Promise<string>}
*/
export const encryptCredentialData = async (plainDataObj: ICredentialDataDecrypted): Promise<string> => {
if (USE_AWS_SECRETS_MANAGER && secretsManagerClient) {
const secretName = `FlowiseCredential_${randomBytes(12).toString('hex')}`
logger.info(`[server]: Upserting AWS Secret: ${secretName}`)
const secretString = JSON.stringify({ ...plainDataObj })
try {
// Try to update the secret if it exists
const putCommand = new PutSecretValueCommand({
SecretId: secretName,
SecretString: secretString
})
await secretsManagerClient.send(putCommand)
} catch (error: any) {
if (error.name === 'ResourceNotFoundException') {
// Secret doesn't exist, so create it
const createCommand = new CreateSecretCommand({
Name: secretName,
SecretString: secretString
})
await secretsManagerClient.send(createCommand)
} else {
// Rethrow any other errors
throw error
}
}
return secretName
}
const encryptKey = await getEncryptionKey()
// Fallback to existing code
return AES.encrypt(JSON.stringify(plainDataObj), encryptKey).toString()
}
@@ -1465,14 +1455,20 @@ export const decryptCredentialData = async (
if (USE_AWS_SECRETS_MANAGER && secretsManagerClient) {
try {
logger.info(`[server]: Reading AWS Secret: ${encryptedData}`)
const command = new GetSecretValueCommand({ SecretId: encryptedData })
const response = await secretsManagerClient.send(command)
if (encryptedData.startsWith('FlowiseCredential_')) {
const command = new GetSecretValueCommand({ SecretId: encryptedData })
const response = await secretsManagerClient.send(command)
if (response.SecretString) {
const secretObj = JSON.parse(response.SecretString)
decryptedDataStr = JSON.stringify(secretObj)
if (response.SecretString) {
const secretObj = JSON.parse(response.SecretString)
decryptedDataStr = JSON.stringify(secretObj)
} else {
throw new Error('Failed to retrieve secret value.')
}
} else {
throw new Error('Failed to retrieve secret value.')
const encryptKey = await getEncryptionKey()
const decryptedData = AES.decrypt(encryptedData, encryptKey)
decryptedDataStr = decryptedData.toString(enc.Utf8)
}
} catch (error) {
console.error(error)