mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: promote MinimumImplicitMember experiment to GA (#27472)
Promotes the `minimum-implicit-member` experiment to GA and removes it.
## What changes
- The `minimum-implicit-member` experiment constant, its
`RoleOptions.MinimumImplicitMember` toggle, and the global
`rbac.MinimumImplicitMember()` accessor are deleted. The minimal-member
behavior is now the only behavior: `organization-member` and
`organization-service-account` carry only the floor (read-self records,
notifications, and similar) and grant **no workspace permissions**.
Workspace access lives exclusively on the
`organization-workspace-access` role.
- The experiment gate on customizing `default_org_member_roles` (`PATCH
/organizations/{org}`) is removed; the built-in-roles-only validation
remains.
- The dashboard's Default Roles section and the implied-roles display on
the members page are no longer experiment-gated.
- Admin docs: new "Default member roles" section in
`docs/admin/users/organizations.md`, cross-linked from
`groups-roles.md`.
## Why this is safe for existing deployments
Migration `000516` (shipped earlier) backfilled
`default_org_member_roles` with `['organization-workspace-access']` on
every organization. Members therefore keep exactly the effective
permissions they had with the experiment off; the workspace elevation
flows through the default role instead of being baked into
`organization-member`.
**Rollback caveat:** rolling back past this release restores the bundled
elevation, silently re-granting workspace access to members of
organizations that cleared their default roles.
## Review
Deep-review R1 findings are addressed in `chore: address deep-review
findings` (copy fixes, read-only Default Roles for viewers, removable
overlapping explicit grants, RBAC prose restoration, test
de-tautologizing, docs). Point-by-point disposition is in the PR
comments.
---
Generated by Coder Agents on behalf of @Emyrk.
This commit is contained in:
+11
-7
@@ -384,13 +384,17 @@ func New(options *Options) *API {
|
||||
options.Logger, options.DeploymentValues.Experiments.Value(),
|
||||
)
|
||||
|
||||
if bool(options.DeploymentValues.DisableOwnerWorkspaceExec) || bool(options.DeploymentValues.DisableWorkspaceSharing) || bool(options.DeploymentValues.DisableChatSharing) || experiments.Enabled(codersdk.ExperimentMinimumImplicitMember) {
|
||||
rbac.ReloadBuiltinRoles(&rbac.RoleOptions{
|
||||
NoOwnerWorkspaceExec: bool(options.DeploymentValues.DisableOwnerWorkspaceExec),
|
||||
NoWorkspaceSharing: bool(options.DeploymentValues.DisableWorkspaceSharing),
|
||||
NoChatSharing: bool(options.DeploymentValues.DisableChatSharing),
|
||||
MinimumImplicitMember: experiments.Enabled(codersdk.ExperimentMinimumImplicitMember),
|
||||
})
|
||||
// Only reload when an option deviates from the defaults so the zero
|
||||
// value keeps the stock builtin roles. Constructing the full options
|
||||
// struct here (rather than mirroring individual fields in the guard)
|
||||
// ensures a newly added RoleOptions field cannot be silently ignored.
|
||||
roleOptions := rbac.RoleOptions{
|
||||
NoOwnerWorkspaceExec: bool(options.DeploymentValues.DisableOwnerWorkspaceExec),
|
||||
NoWorkspaceSharing: bool(options.DeploymentValues.DisableWorkspaceSharing),
|
||||
NoChatSharing: bool(options.DeploymentValues.DisableChatSharing),
|
||||
}
|
||||
if roleOptions != (rbac.RoleOptions{}) {
|
||||
rbac.ReloadBuiltinRoles(&roleOptions)
|
||||
}
|
||||
|
||||
if options.DeploymentValues.DisableWorkspaceSharing {
|
||||
|
||||
Reference in New Issue
Block a user