From 9747e832acf70c387ee9711628c66b696872c254 Mon Sep 17 00:00:00 2001 From: Mauricio Siu Date: Mon, 10 Aug 2026 16:41:08 -0600 Subject: [PATCH] feat: enhance vault provider access control and environment variable handling - Updated the environment autocomplete component to include projectId and environmentId in vault secret fetching logic. - Added authorization checks in the vault provider router to ensure users have access to the specified project and environment. - Modified the vault provider schema to include projectId and optional environmentId for better validation. - Improved error handling for unauthorized access and invalid vault provider assignments. --- .../components/shared/env-autocomplete.ts | 18 +++++++++-- .../server/api/routers/vault-provider.ts | 30 ++++++++++++++++++ .../server/src/db/schema/vault-provider.ts | 2 ++ packages/server/src/utils/vault/index.ts | Bin 4538 -> 4626 bytes 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/apps/dokploy/components/shared/env-autocomplete.ts b/apps/dokploy/components/shared/env-autocomplete.ts index 3bad00b4b..0b6039976 100644 --- a/apps/dokploy/components/shared/env-autocomplete.ts +++ b/apps/dokploy/components/shared/env-autocomplete.ts @@ -85,9 +85,13 @@ export const useEnvCompletionSource = ({ const vaultSecret = /^vault\.([a-zA-Z0-9_-]+)\.([^}\n]*)$/.exec(inner); if (vaultSecret) { const provider = providers?.find((p) => p.name === vaultSecret[1]); - if (!provider) return null; + if (!provider || !projectId) return null; const names = await utils.vaultProvider.listSecretNames - .fetch({ vaultProviderId: provider.vaultProviderId }) + .fetch({ + vaultProviderId: provider.vaultProviderId, + projectId, + environmentId, + }) .catch(() => [] as string[]); return { from: innerFrom + `vault.${vaultSecret[1]}.`.length, @@ -176,6 +180,14 @@ export const useEnvCompletionSource = ({ return null; }, - [providers, projectEnv, environmentEnv, includeShared, utils], + [ + providers, + projectEnv, + environmentEnv, + includeShared, + projectId, + environmentId, + utils, + ], ); }; diff --git a/apps/dokploy/server/api/routers/vault-provider.ts b/apps/dokploy/server/api/routers/vault-provider.ts index d59ffca69..4ca3b5789 100644 --- a/apps/dokploy/server/api/routers/vault-provider.ts +++ b/apps/dokploy/server/api/routers/vault-provider.ts @@ -2,6 +2,7 @@ import { createVaultProvider, findVaultProviderInOrganization, findVaultProvidersByOrganizationId, + isVaultProviderAssigned, listVaultProviderSecretNames, maskVaultProviderConfig, mergeVaultProviderConfig, @@ -9,6 +10,7 @@ import { testVaultProviderConnection, updateVaultProvider, } from "@dokploy/server"; +import { findMemberByUserId } from "@dokploy/server/services/permission"; import { TRPCError } from "@trpc/server"; import { audit } from "@/server/api/utils/audit"; import { @@ -129,6 +131,34 @@ export const vaultProviderRouter = createTRPCRouter({ input.vaultProviderId, ctx.session.activeOrganizationId, ); + + if (ctx.user.role !== "owner" && ctx.user.role !== "admin") { + const { accessedProjects } = await findMemberByUserId( + ctx.user.id, + ctx.session.activeOrganizationId, + ); + if (!accessedProjects.includes(input.projectId)) { + throw new TRPCError({ + code: "UNAUTHORIZED", + message: "You don't have access to this project", + }); + } + } + + if ( + !isVaultProviderAssigned( + provider.assignments, + input.projectId, + input.environmentId, + ) + ) { + throw new TRPCError({ + code: "FORBIDDEN", + message: + "This vault provider is not enabled for the given project/environment", + }); + } + return await listVaultProviderSecretNames(provider.config); }), }); diff --git a/packages/server/src/db/schema/vault-provider.ts b/packages/server/src/db/schema/vault-provider.ts index 2b78c9008..6056e54cf 100644 --- a/packages/server/src/db/schema/vault-provider.ts +++ b/packages/server/src/db/schema/vault-provider.ts @@ -140,4 +140,6 @@ export const apiTestVaultProvider = z.object({ export const apiListVaultSecretNames = z.object({ vaultProviderId: z.string().min(1), + projectId: z.string().min(1), + environmentId: z.string().optional(), }); diff --git a/packages/server/src/utils/vault/index.ts b/packages/server/src/utils/vault/index.ts index 5d69cdf45b9ee9ec99c90731a9b50c09f719488c..b5908cb851ce7c5b3048b86791d7e416ecb7cded 100644 GIT binary patch delta 213 zcmdm`JV|APIg3haML~X1i9&LIUU7*+W^q_zX--K%QGQuwN@|f~adBpPUTVr@PZoEr zf};Ga)Z`M+6f1?|lA_GKbR90v)V#9HqWrwv)I6ZLJxpTqY8H>lKUo|m+p}71u4O&O xqQb=q1d2FJ*8t0MP7dS}wSq8jkw