feat(api): restrict blocked teams per-endpoint via OpenAPI extension#2456
feat(api): restrict blocked teams per-endpoint via OpenAPI extension#2456mishushakov wants to merge 1 commit intomainfrom
Conversation
Blocked teams can now authenticate and access most endpoints; restricted endpoints opt in with `x-disable-team-blocked: true`. A new middleware reads the embedded spec at startup and returns 403 for blocked teams hitting any marked route (sandbox/template mutations, volume create).
PR SummaryMedium Risk Overview Reviewed by Cursor Bugbot for commit ecbd86e. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ecbd86e. Configure here.
| c.Next() | ||
|
|
||
| return | ||
| } |
There was a problem hiding this comment.
Blocked team check bypassed via AccessTokenAuth authentication
Medium Severity
The BlockedTeam middleware silently passes through when auth.GetTeamInfo returns no team info (!ok). Endpoints that accept AccessTokenAuth (which calls SetUserID, not SetTeamInfo) will never have team info in the gin context, so blocked team members can bypass the restriction by authenticating with an access token. This affects non-deprecated endpoints like PATCH /v2/templates/{templateID}, which lists AccessTokenAuth as a valid security scheme alongside ApiKeyAuth.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ecbd86e. Configure here.
| delete: | ||
| description: Kill a sandbox | ||
| tags: [sandboxes] | ||
| x-disable-team-blocked: true |
There was a problem hiding this comment.
Blocked teams cannot kill their own running sandboxes. Since TTL refresh and timeout extension are also blocked, any sandbox a team had at block-time will idle until its current TTL expires naturally. This means the platform continues serving compute for a blocked team until expiry, and an admin must intervene manually for faster cleanup. Consider whether DELETE /sandboxes/{sandboxID} should remain unblocked - it is a cleanup operation that reduces resource consumption, not a new-resource creation.
jakubno
left a comment
There was a problem hiding this comment.
Don't add it like that, please pass the intent to validateTeamUsage


Summary
x-disable-team-blocked: trueinspec/openapi.yml(applied to 18 sandbox/template/volume routes).middleware.BlockedTeamscans the embedded swagger at startup to build a(method, gin-route)lookup and returns 403 for blocked teams on marked routes; wired intopackages/api/main.goafter auth and LD context, before rate limiting.validateTeamUsageno longer short-circuits onIsBlocked(ban check unchanged);api.gen.goregenerated so the embedded spec carries the new extensions.Test plan
go test ./packages/api/... ./packages/auth/...(passing locally)GET /sandboxesbut gets 403 onPOST /sandboxes,DELETE /sandboxes/{id},POST /volumes, etc.