[CLC-2032] Fix Classic PAYG sunset bypass via websocket API #21108
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.
Problem
The Classic PAYG sunset implementation in #21100 only added blocking checks to the new gRPC API (
WorkspaceServiceAPI
-gitpod.v1.WorkspaceService
) but missed the legacy websocket API (GitpodServerImpl
). This created multiple bypass routes that allowed blocked users to continue creating and starting workspaces.Architecture Overview
There are THREE separate workspace APIs in Gitpod:
Websocket API (OLD) -
GitpodServerImpl
incomponents/server
gitpod_server_api_calls_total{method="startWorkspace"}
New gRPC API -
WorkspaceServiceAPI
incomponents/server
gitpod.v1.WorkspaceService
grpc_server_handled_total{grpc_service="gitpod.v1.WorkspaceService"}
Experimental API -
public-api-server
(separate Go service)gitpod.experimental.v1.WorkspacesService
connect_server_handled_seconds{package="gitpod.experimental.v1.WorkspacesService"}
Bypass Routes Identified
Users can bypass the sunset blocking through:
Gitpod CLI (
gitpod workspace create/start
)gitpod.experimental.v1.WorkspacesService
(API 3)Gitpod Local App (Desktop application)
JetBrains Gateway
External integrations with Personal Access Tokens
Dashboard fallback
dashboard_public_api_workspace_enabled
feature flag is disabledAll these routes ultimately call
GitpodServerImpl.startWorkspace()
orGitpodServerImpl.createWorkspace()
which had no sunset checks.Solution
Added the sunset check to both methods in
GitpodServerImpl
:startWorkspace()
- Checks before starting existing workspacecreateWorkspace()
- Checks before creating and starting new workspaceUses the same
isWorkspaceStartBlockedBySunset()
function already implemented for the gRPC API, ensuring consistent behavior across all entry points.Why This Works
The fix is applied at the websocket API layer (
GitpodServerImpl
), which is the common backend for:This ensures ALL workspace creation/start requests are blocked, regardless of which API surface they use.
Testing
workspace-service-api.ts
Recommended Testing
gitpod workspace create <url>
should be blockedExpected Metrics After Deployment
For blocked users, you should see:
Security Impact
This closes a critical security hole that allowed users to bypass the Classic PAYG sunset restrictions. Without this fix, the sunset blocking is ineffective for:
gitpod workspace create/start
)The fix ensures sunset blocking works consistently across all API surfaces.