docs/plans/2026-01-12-unify-predefined-roles-design.md
Move predefined role definitions from IAM manager to store package so that:
store.ListRoles() returns all roles (custom + predefined)v1 service → store
v1 service → iam manager
iam manager → store
iam manager → common/permission
store → common/permission
backend/common/permission/| Action | From | To |
|---|---|---|
| Move | backend/component/iam/permission.go | backend/common/permission/permission.go |
| Move | backend/component/iam/permission.yaml | backend/common/permission/permission.yaml |
| Action | File | Notes |
|---|---|---|
| Create | backend/store/predefined_roles.go | Define 9 roles using permission constants |
| Update | backend/store/role.go | ListRoles() appends predefined roles |
| Action | File | Notes |
|---|---|---|
| Update | backend/component/iam/manager.go | Remove PredefinedRoles field, loadPredefinedRoles(), YAML embedding |
| Delete | backend/component/iam/acl.yaml | Replaced by Go code |
| Action | File | Notes |
|---|---|---|
| Update | backend/api/v1/role_service.go | Remove manual merge with predefined roles |
| Action | File | Notes |
|---|---|---|
| Update | frontend/scripts/copy_config_files.sh | New path: ../backend/common/permission/permission.yaml |
store/predefined_roles.gopackage store
import "github.com/bytebase/bytebase/backend/common/permission"
var predefinedRoles = []*RoleMessage{
{
ResourceID: "workspaceAdmin",
Name: "Workspace admin",
Permissions: permissionSet(
permission.PermissionAuditLogsExport,
permission.PermissionInstancesCreate,
// ... all permissions
),
},
// ... 8 more roles
}
func permissionSet(perms ...permission.Permission) map[string]bool {
m := make(map[string]bool, len(perms))
for _, p := range perms {
m[string(p)] = true
}
return m
}
store/role.go - ListRolesfunc (s *Store) ListRoles(ctx context.Context, find *FindRoleMessage) ([]*RoleMessage, error) {
// existing DB query for custom roles
roles := // from DB
// Append predefined roles
roles = append(roles, predefinedRoles...)
return roles, nil
}
iam/manager.go - ChangesRemove:
PredefinedRoles field from Manager structloadPredefinedRoles() function//go:embed acl.yaml directiveUpdate ReloadCache() to use ListRoles() directly without appending predefined.
loadPredefinedRoles() or PredefinedRoles field