Repository navigation
Conversation
POST /api/teams, PUT /api/teams/{name} and DELETE /api/teams/{name}
are registered in the plain authenticated group with no middleware,
and the handlers had no authorization of their own. The Team admission
webhook only guards spec.resourceLimits and spec.environments[].limits,
so any authenticated user could create teams, rename or re-default any
team, and delete any team (the delete ran as the server service
account, bypassing the webhook entirely).
Create and delete now require a platform admin. Update allows a
platform admin, or a team admin of that team for everything except
resourceLimits, which stays platform-admin only to match the webhook.
Delete impersonates the caller like create and update so the apiserver
audit trail carries the real identity.
Decisions live in authorizeTeamCreate/Update/Delete with table tests.
Review follow-up. An RBAC Forbidden from the impersonated Delete call was mapped to 500; it now returns 403 with a clear message and a warning log, matching how the other impersonated writes surface admission denials.
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.
Problem
POST /api/teams,PUT /api/teams/{name}andDELETE /api/teams/{name}sit in the plain authenticated group (internal/api/router.go:495-498) and the handlers performed no authorization. The Team admission webhook (ADR-009) only guardsspec.resourceLimitsandspec.environments[].limits. Result: any authenticated user could create teams, rename or re-default any team, and delete any team. Delete ran as the server service account, so even the webhook never saw a caller.Found during the 2026-08 portal/console parity audit (server route table, H1).
Change
Create: platform admin only.Update: platform admin, or team admin of that team;resourceLimitsin the body stays platform-admin only (same split as the webhook).Delete: platform admin only, and now impersonates the caller (AsUser) like create and update so the apiserver audit trail carries the real identity.authorizeTeamCreate/authorizeTeamUpdate/authorizeTeamDeleteinhandlers/teams.go.The
/api/admin/teamsduplicates are unchanged; they keepAdminMiddlewareand now also pass through the same handler checks.Verification
CGO_ENABLED=0 go build ./...cleanCGO_ENABLED=0 go vet ./internal/api/handlers/cleanCGO_ENABLED=0 go test ./...passes; newteams_authz_test.gocovers nil session (401), platform admin, platform viewer, team admin own/other team, operator, viewer, and the resourceLimits carve-out.AdminTeamsPage(POST /admin/teams, platform admin),AdminTeamDetailPage(PUT limits/defaults, platform admin),TeamSettingsPage(PUT display fields, team admin),DELETE /teams/{t}from the admin team page. None of these paths change for their intended roles.Out of scope
Replacing the any-team-admin
AdminMiddlewareon the/adminwrite group (separate PR), member and group sync handlers (per-team checks tracked separately), audit middleware attribution.