Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance: added encryption on LLM keys #1883

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion agenta-web/.env.local.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Rename this file to .env.local and provide the secret values to access them in the app
# .env.local should not be committed to git

NEXT_PUBLIC_OPENAI_API_KEY=
NEXT_PUBLIC_OPENAI_API_KEY=
NEXT_PUBLIC_LLM_ENCRYPTION_KEY="add a secure key to encrypt your llm keys"
8 changes: 8 additions & 0 deletions agenta-web/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions agenta-web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"autoprefixer": "10.4.14",
"axios": "^1.4.0",
"classnames": "^2.3.2",
"crypto-js": "^4.2.0",
"dayjs": "^1.11.10",
"diff": "^5.2.0",
"dotenv": "^16.3.1",
Expand Down Expand Up @@ -90,6 +91,7 @@
"devDependencies": {
"@swc/cli": "^0.3.12",
"@swc/core": "^1.4.15",
"@types/crypto-js": "^4.2.2",
"@types/node": "^20.8.10",
"cypress": "^13.4.0",
"node-mocks-http": "^1.12.2",
Expand Down
4 changes: 2 additions & 2 deletions agenta-web/src/components/AppSelector/AppSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {useAppsData} from "@/contexts/app.context"
import {useProfileData} from "@/contexts/profile.context"
import CreateAppStatusModal from "./modals/CreateAppStatusModal"
import {usePostHogAg} from "@/hooks/usePostHogAg"
import {LlmProvider, getAllProviderLlmKeys} from "@/lib/helpers/llmProviders"
import {LlmProvider, getAllDecryptedProviderLlmKeys} from "@/lib/helpers/llmProviders"
import ResultComponent from "../ResultComponent/ResultComponent"
import {dynamicContext} from "@/lib/helpers/dynamic"

Expand Down Expand Up @@ -195,7 +195,7 @@ const AppSelector: React.FC = () => {
setStatusModalOpen(true)

// attempt to create and start the template, notify user of the progress
const apiKeys = getAllProviderLlmKeys()
const apiKeys = getAllDecryptedProviderLlmKeys()
await createAndStartTemplate({
appName: newApp,
templateId: template_id,
Expand Down
16 changes: 13 additions & 3 deletions agenta-web/src/lib/helpers/llmProviders.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from "lodash"
import {camelToSnake} from "./utils"
import {encryptText, decryptText} from "./utils"

const llmAvailableProvidersToken = "llmAvailableProvidersToken"

Expand Down Expand Up @@ -48,10 +48,11 @@ export const getApikeys = () => {
}

export const saveLlmProviderKey = (providerName: string, keyValue: string) => {
// TODO: add encryption here
const keys = getAllProviderLlmKeys()
const item = keys.find((item: LlmProvider) => item.title === providerName)
if (item) item.key = keyValue
const encryptedKeyValue = encryptText(keyValue)

if (item) item.key = encryptedKeyValue
localStorage.setItem(llmAvailableProvidersToken, JSON.stringify(keys))
}

Expand All @@ -74,6 +75,15 @@ export const getAllProviderLlmKeys = () => {
}
return providers
}
export const getAllDecryptedProviderLlmKeys = () => {
const providers = getAllProviderLlmKeys()
return providers.map((provider) => {
if (provider.key) {
provider.key = decryptText(provider.key)
}
return provider
})
}

export const removeSingleLlmProviderKey = (providerName: string) => {
const keys = getAllProviderLlmKeys()
Expand Down
27 changes: 25 additions & 2 deletions agenta-web/src/lib/helpers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import dayjs from "dayjs"
import utc from "dayjs/plugin/utc"
import {notification} from "antd"
import Router from "next/router"
import {getAllProviderLlmKeys, getApikeys} from "./llmProviders"
import {getAllDecryptedProviderLlmKeys, getApikeys} from "./llmProviders"
import CryptoJS from "crypto-js"

if (typeof window !== "undefined") {
//@ts-ignore
Expand Down Expand Up @@ -46,7 +47,7 @@ export const EvaluationTypeLabels: Record<EvaluationType, string> = {
}

export const apiKeyObject = () => {
const apiKeys = getAllProviderLlmKeys()
const apiKeys = getAllDecryptedProviderLlmKeys()

if (!apiKeys) return {}

Expand Down Expand Up @@ -327,3 +328,25 @@ export const getInitials = (str: string, limit = 2) => {

return initialText
}

const ENCRYPTION_KEY = process.env.NEXT_PUBLIC_LLM_ENCRYPTION_KEY as string
export const encryptText = (data: string) => {
try {
const encryptedKey = CryptoJS.AES.encrypt(data, ENCRYPTION_KEY).toString()
return encryptedKey
} catch (error) {
return data
}
}

export const decryptText = (encryptedKey: string) => {
try {
if (!encryptedKey) return ""

const bytes = CryptoJS.AES.decrypt(encryptedKey, ENCRYPTION_KEY)
const originalKey = bytes.toString(CryptoJS.enc.Utf8)
return originalKey
} catch (error) {
return encryptedKey
}
}
Loading