refactor(coderd): restore agents-access cleanup migration (#28587)

## Summary

- restore the `agents-access` data cleanup migration as `000587`
(renumbered from `000585`; main advanced past that number)
- revert the temporary RBAC tolerance for retired role names now that
the migration strips stale grants
- make the migration test discover its predecessor dynamically, since
this branch does not carry main's `000585`/`000586`

## Stack context

Stacked on #28186, which retires the `agents-access` role but
intentionally ships without a migration so it can be backported across
diverged migration numbers. This layer completes the retirement on main:
it cleans up stale role grants in `users.rbac_roles`,
`organization_members.roles`, and
`organizations.default_org_member_roles`, then reverts the interim
leniency (role expansion dropping legacy names, assignment validation
ignoring them) that existed only to keep the migration-less base safe.
`rbac.ReservedRoleName` still reserves the retired name so custom roles
cannot shadow it on rollback. Do not backport this PR alongside the base
PR.

## Rollback note

The down migration restores effective access broadly because it cannot
reconstruct which users previously held the removed role.

## Validation

- `go build ./coderd/... ./enterprise/...`
- full `coderd/database/migrations`, `coderd/rbac/...`, and
`coderd/database/dbauthz` suites
- targeted members tests in `coderd`
- repository pre-commit checks (`lint/go`, `lint/ts`, etc.)

> Mux created this pull request on Mike's behalf.
This commit is contained in:
Michael Suchacz
2026-08-26 15:29:26 +02:00
committed by GitHub
parent 31146642ba
commit 45f2eb48cc
8 changed files with 107 additions and 173 deletions
+2 -5
View File
@@ -1767,11 +1767,8 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) {
}
// TODO: Replace this with "GetAuthorizationUserRoles"
// Stored role arrays may retain retired built-in role names until a
// cleanup migration lands. Hide them so consumers do not display or
// resubmit them.
resp := codersdk.UserRoles{
Roles: slices.DeleteFunc(slices.Clone(user.RBACRoles), rbac.IsRetiredRoleName),
Roles: user.RBACRoles,
OrganizationRoles: make(map[uuid.UUID][]string),
}
@@ -1790,7 +1787,7 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) {
}
for _, mem := range memberships {
resp.OrganizationRoles[mem.OrganizationMember.OrganizationID] = slices.DeleteFunc(slices.Clone(mem.OrganizationMember.Roles), rbac.IsRetiredRoleName)
resp.OrganizationRoles[mem.OrganizationMember.OrganizationID] = mem.OrganizationMember.Roles
}
httpapi.Write(ctx, rw, http.StatusOK, resp)