mirror of
https://github.com/farcasclaudiu/Flowise.git
synced 2026-06-22 09:01:09 +03:00
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:
@@ -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
|
||||
|
||||
@@ -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=*
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user