-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
"Create Services" permission incorrectly required for domain service selection and environment editing #4052
Description
To Reproduce
Bug Description
A member user with access to a project/service should not need the "Create Services" permission to:
- Select a service name in the domain configuration form (compose services)
- Edit environment variables on database services and compose services
Currently, both operations fail with "Permission denied" unless the user has "Create Services" (canCreateServices) enabled, even though these are read/edit operations, not service creation.
Root Cause
1. compose.loadServices requires service: ["create"] instead of service: ["read"]
File: apps/dokploy/server/api/routers/compose.ts (line ~277-283)
loadServices: protectedProcedure
.input(apiFetchServices)
.query(async ({ input, ctx }) => {
await checkServicePermissionAndAccess(ctx, input.composeId, {
service: ["create"], // BUG: should be service: ["read"]
});
return await loadServices(input.composeId, input.type);
}),This endpoint is called by the domain form (handle-domain.tsx) to populate the service name dropdown when adding/editing a domain on a compose service. Loading services from a compose file is a read-only operation — it just parses the YAML and returns Object.keys(composeData.services).
Impact: When a member user without "Create Services" permission opens the domain form for a compose service, the service name dropdown fails to load.
2. Database/Compose env editing uses update mutation which requires service: ["create"]
Files:
apps/dokploy/server/api/routers/postgres.ts—updatechecks{ service: ["create"] }apps/dokploy/server/api/routers/mysql.ts— sameapps/dokploy/server/api/routers/mariadb.ts— sameapps/dokploy/server/api/routers/redis.ts— sameapps/dokploy/server/api/routers/mongo.ts— sameapps/dokploy/server/api/routers/compose.ts—updatechecks{ service: ["create"] }
The ShowEnvironment component (show-enviroment.tsx) saves environment variables by calling the generic update mutation (e.g., api.postgres.update, api.compose.update). These all check { service: ["create"] }.
However, the frontend gates the Save button using envVars.write:
const canWrite = permissions?.envVars.write ?? false;
// ...
{canWrite && <Button>Save</Button>}This is a mismatch — the UI shows the button based on envVars.write, but the backend requires service: ["create"].
Note: The application service type has a dedicated saveEnvironment endpoint that correctly checks { envVars: ["write"] }, but database and compose services do not use it — they go through the generic update mutation.
Why This Happens (Permission Flow for Members)
- The
memberRoleinaccess-control.tsonly hasservice: ["read"](not"create") - When
checkPermissionis called with{ service: ["create"] },role.authorize()fails - It falls back to
getLegacyOverrides, which mapscanCreateServicestoservice.create - So a member needs
canCreateServices = trueto pass any{ service: ["create"] }check
Enterprise-only resources like domain and envVars have a bypass for static roles, but service is a core resource without this bypass.
Steps to Reproduce
- Create a member user
- Grant them access to a project with a compose service (via the Projects modal)
- Do NOT enable "Create Services" permission
- Log in as that member user
- Navigate to the compose service -> Domains tab
- Try to add a domain — the service name dropdown will fail to load
- Navigate to environment settings for any database/compose service
- Try to edit and save environment variables — it will fail with "Permission denied"
Current vs. Expected behavior
Expected Behavior
- Domain service selection: A member with read access to the service should be able to load the service list in the domain form
- Environment editing: A member should be able to edit environment variables based on the
envVars.writepermission, notservice.create
Suggested Fix
- Change
compose.loadServicespermission from{ service: ["create"] }to{ service: ["read"] } - For database/compose environment editing, either:
- Add dedicated
saveEnvironmentendpoints (like the application router already has) that check{ envVars: ["write"] } - Or change the
updatemutation permission check to use a more appropriate permission when onlyenvfield is being updated
- Add dedicated
Provide environment information
Operating System:
OS: N/A (code-level bug, not environment-specific)
Arch: N/A
Dokploy version: v0.28.8
VPS Provider: N/A
What applications/services are you trying to deploy?
N/A — this is a permission system bug affecting member users.
The issue is in the tRPC router permission checks, not specific to any deployment.Which area(s) are affected? (Select all that apply)
Application
Are you deploying the applications where Dokploy is installed or on a remote server?
Same server where Dokploy is installed
Additional context
No response
Will you send a PR to fix it?
Maybe, need help