diff --git a/packages/components/src/utils.ts b/packages/components/src/utils.ts index f5bc3f05..979aa1a6 100644 --- a/packages/components/src/utils.ts +++ b/packages/components/src/utils.ts @@ -543,6 +543,15 @@ const getEncryptionKey = async (): Promise => { 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 # SECRETKEY_AWS_SECRET_KEY= # SECRETKEY_AWS_REGION=us-west-2 +# SECRETKEY_AWS_NAME=FlowiseEncryptionKey # NUMBER_OF_PROXIES= 1 # CORS_ORIGINS=* diff --git a/packages/server/src/utils/index.ts b/packages/server/src/utils/index.ts index 3aa37150..2301ce59 100644 --- a/packages/server/src/utils/index.ts +++ b/packages/server/src/utils/index.ts @@ -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 => { 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 => { * @returns {Promise} */ export const encryptCredentialData = async (plainDataObj: ICredentialDataDecrypted): Promise => { - 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)