-
Couldn't load subscription status.
- Fork 1.3k
[CLC-2032] Fix Classic PAYG sunset bypass via websocket API #21108
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
Merged
Conversation
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
The original sunset implementation only added checks to the new gRPC API (WorkspaceServiceAPI) but missed the legacy websocket API (GitpodServerImpl). This allowed users to bypass the sunset blocking through: - Gitpod CLI/Local App (uses experimental/v1 API) - JetBrains Gateway (uses websocket API directly) - Public API with Personal Access Tokens - Dashboard when feature flag is disabled This fix adds the sunset check to both startWorkspace() and createWorkspace() methods in GitpodServerImpl, using the same isWorkspaceStartBlockedBySunset() function that's already used in WorkspaceServiceAPI. The check: - Blocks installation-owned users (no organizationId) - Blocks users in non-exempted organizations - Exempts dedicated installations - Exempts organizations in the exemptedOrganizations list Co-authored-by: Ona <no-reply@ona.com>
@corneliusludmann
corneliusludmann
marked this pull request as ready for review
October 17, 2025 11:58
@corneliusludmann
corneliusludmann
requested a review
from a team
as a code owner
October 17, 2025 11:58
nandajavarma
nandajavarma
approved these changes
Oct 17, 2025
@roboquat
roboquat
deleted the
fix/classic-payg-sunset-websocket-bypass
branch
October 17, 2025 12:19
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.
Uh oh!
There was an error while loading. Please reload this page.
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) -
GitpodServerImplincomponents/servergitpod_server_api_calls_total{method="startWorkspace"}New gRPC API -
WorkspaceServiceAPIincomponents/servergitpod.v1.WorkspaceServicegrpc_server_handled_total{grpc_service="gitpod.v1.WorkspaceService"}Experimental API -
public-api-server(separate Go service)gitpod.experimental.v1.WorkspacesServiceconnect_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_enabledfeature 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.tsRecommended 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.