feat(permissions): add server.terminal to decouple server access from root SSH - #5142
Open
narcisonunez wants to merge 1 commit into
Open
feat(permissions): add server.terminal to decouple server access from root SSH#5142narcisonunez wants to merge 1 commit into
narcisonunez wants to merge 1 commit into
Conversation
narcisonunez
force-pushed
the
feat/add-terminal-permission
branch
from
August 21, 2026 14:43
5aa9c25 to
b8cb7fa
Compare
… root SSH Reaching a server implied being able to open an SSH root shell on it: the /terminal websocket only checked that the server was in the caller's accessible set, so granting a server to a developer necessarily granted root on it. Add a server.terminal action, assignable on custom roles, and require it on the remote-server terminal websocket on top of server access. Owner/admin keep it through the enterprise bypass; the local host terminal stays owner/admin only. A migration grants server.terminal to existing custom roles that already have server.read, which is the permission that surfaces the terminal today, so current setups keep working. Roles without a server entry are left alone. Note: server.create still implies root execution (server.update persists server.command and server.setup runs it over SSH), reflected in the Create description in the role editor.
narcisonunez
force-pushed
the
feat/add-terminal-permission
branch
from
August 21, 2026 15:08
b8cb7fa to
bbde5eb
Compare
narcisonunez
marked this pull request as ready for review
August 21, 2026 19:52
Comment on lines
+81
to
+83
| return await hasPermission(buildCtx(user, session.activeOrganizationId), { | ||
| server: ["terminal"], | ||
| }); |
Contributor
There was a problem hiding this comment.
Built-in members lose terminal access
When a built-in member in an organization without an enterprise license opens a remote terminal, this new check denies access because the member role has no server.terminal grant or legacy override. These members previously received access to all organization servers, and the migration updates only custom roles, so upgrading removes their remote-terminal access with no way to restore it.
Knowledge Base Used:
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reaching a server implied being able to open an SSH root shell on it: the /terminal websocket only checked that the server was in the caller's accessible set, so granting a server to a developer necessarily granted root on it.
Add a server.terminal action, assignable on custom roles, and require it on the remote-server terminal websocket on top of server access. Owner/admin keep it through the enterprise bypass; the local host terminal stays owner/admin only.
A migration grants server.terminal to existing custom roles that already have server.read, which is the permission that surfaces the terminal today, so current setups keep working. Roles without a server entry are left alone.
What is this PR about?
Please describe in a short paragraph what this PR is about.
Checklist
Before submitting this PR, please make sure that:
canarybranch.Issues related (if applicable)
Screenshots (if applicable)
Greptile Summary
This PR introduces a separate
server.terminalpermission and enforces it for remote host-terminal WebSockets while preserving the owner/admin-only local terminal.server.readand adds permission and WebSocket authorization tests.Confidence Score: 4/5
The existing remote-terminal access regression for built-in free-tier members should be fixed before merging.
The new WebSocket check requires server.terminal, but non-licensed built-in members previously received access to all organization servers and have no role grant, legacy override, or custom-role path that can satisfy the new permission.
Files Needing Attention: apps/dokploy/server/wss/authorize.ts, packages/server/src/lib/access-control.ts, and apps/dokploy/drizzle/0186_grant-server-terminal-permission.sql
Reviews (1): Last reviewed commit: "feat(permissions): add server.terminal t..." | Re-trigger Greptile
Context used: