Origin/18124 custom role feature#22815
Open
maxgraustenzel-create wants to merge 16 commits into
Open
Conversation
Member
|
@maxgraustenzel-create Please first submit a proposal in the community repository for discussion. |
|
This PR is being marked stale due to a period of inactivty. If this PR is still relevant, please comment or remove the stale label. Otherwise, this PR will close in 30 days. |
This is the proposal: |
|
Tagging issue #18308 to this since it's also related to some of the issues opened. |
1a2ee15 to
236bb14
Compare
- Portal: replace hardcoded built-in role buttons in project member
list, add-member, and add-group dialogs with dynamic role list loaded
from API; built-in roles show translated names + blue badge; custom
roles listed after a divider; scroll when list overflows
- Portal: role column in member datagrid now resolves role name via API
(translated for built-ins, raw name for custom roles)
- Backend: fire audit log events for role create / update / delete;
add UpdateRoleEvent topic and metadata; subscribe all three topics
in handler init so events actually reach the audit log handler
- Backend: fix typo in DeleteRoleEvent audit message ("robot" → "role")
- DB: add 0190 migration schema placeholder
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend: add checkNoEscalation to member handler — CreateProjectMember and UpdateProjectMember now verify that every permission in the target role is held by the calling user before accepting the request. Sysadmins pass through unconditionally via the RBAC layer. Returns 403 Forbidden on escalation attempt, closing the TODO in member controller isValidRole. Frontend: compute assignableRoleIds from the current user's own role permissions (loaded via forkJoin with the member list). Built-in roles below projectAdmin level and custom roles that are a strict subset of the caller's permissions remain selectable; others are disabled and visually dimmed in the action dropdown, add-member, and add-group dialogs. Default selection in add-member/add-group modals snaps to the first assignable role so the form is always valid on open. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sysadmin_flag lives on SessionUserBackend; the resolved SessionUser type only exposes has_admin_role — fixes TS2339 compilation error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Migration 0040 renames master → maintainer before 0190 runs, so the UPDATE was silently skipping the maintainer role. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Role permission cache (L1 sync.Map + L2 Redis) in controller/role/controller.go
eliminates per-request role_permission DB queries after first warm-up
- Restore isValidRole() validation in member controller
- Fix permissions endpoint: open to all authenticated users (used by project UI)
- Remove orm.Debug=true and leftover debug log.Debug("*** ...") statements
- Uncomment and fix RBAC evaluator tests for fork's 3-arg NewBuilderForUser
- Remove TODO placeholder comments from production code
- Add [TIMING:*] instrumentation to measure permission evaluation breakdown:
Can(), project_get, project_assemble, list_roles_sql, builder, role_get
- Extended timing to project controller and DAO for detailed DB breakdown
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ckstop The L1+L2 role-permission cache had two correctness gaps: - L2 had no TTL (cache.Default() Expiration=0), so out-of-band SQL changes to role_permission were never reflected until a core restart. - invalidateRole() cleared only the local L1; Get() reads L1 first, so other nodes served stale permissions until their process restarted. Fix: - Global Redis "version token" (role:version) bumped on every in-app write; nodes poll it throttled to ~1s and bump a local generation that invalidates all L1 entries → cross-node propagation within ~1s. Lock-free (atomics+CAS). - 30-min TTL on both L1 (per-entry expiresAt) and L2 (Save expiration) as a self-healing backstop for out-of-band changes. - Read order: version-refresh -> L1 (gen+TTL) -> L2 -> DB (populates both). Write order: bump version -> delete L2 -> delete L1. - Documented the bounded cache-aside repopulation race. Also fixes a pre-existing test bug: TestUpdateCustomRole never mocked roleMgr.Update (failed on the committed baseline too). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings in upstream through eb944bb (incl. Angular 21 / Clarity 18 / Node 22 portal upgrade and go.mod OSS bumps). Backend auto-merged and builds clean. Conflicts resolved (portal): kept the custom-roles feature logic while adopting upstream's Angular-21 control-flow syntax: - member.component.html: @if blocks + getMemberRoleDisplayName() - add-group/add-group.component.html: @for over dynamic roles with builtin badges - package-lock.json: took upstream's Angular-21 lockfile (fork adds no npm deps) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Angular 19+ makes components standalone by default. The fork's RolesComponent, AddRoleComponent and RolePermissionsPanelComponent are declared in roles.module.ts, so they must opt out of standalone (NG6008). Portal now builds green under Angular 21 / Clarity 18 / Node 22. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a runtime toggle so Get() with permissions can skip L1/L2 entirely and read the role + role_permission from the DB on every Can() call. Replaces the fragile build-time source-stripping used for the no-cache perf baseline (which broke after the version-key refactor) with a same-binary env switch. Off by default. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Prepare the custom-roles branch for a clean merge request: - Remove all [TIMING:*] perf-logging (Can/builder/evaluator/project_ctrl/ list_roles_sql/security_ctx) and the timing-only changes in dao.go, session.go and project/controller.go (reverted to upstream). - Drop the per-role permission lookup's timing scaffolding in rbac/project/evaluator.go, keeping the feature (ctl_r.Get) and adding proper error handling; collapse a redundant nested if-err. - Remove the "TODO MGS" scratch comment and the commented-out dead code (convertScope/toScope/SetProject/CreateSec/IsValidSec) plus the now-unused regex vars and regexp import in controller/role/controller.go. No functional change to the custom-roles feature or the permission cache. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
End-to-end checks for the custom-roles feature: role CRUD + built-in immutability, built-in role permissions via ListRole, project/group/robot member anti-escalation, sysadmin bypass, is_builtin display flags, and edge cases (zero-permission role, empty-roles fallback). Run: python3 tests/integration/test_custom_roles.py --url <harbor> --user admin --password <pw> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add clrDgSelectionType="multi" to the roles datagrid so Clarity 18 renders the selection checkbox column (binding [(clrDgSelected)] to an array alone is no longer sufficient), and migrate the row iteration from *ngFor to @for to match every other datagrid in the portal. Without the checkboxes admins could not select a role to enable the Edit/Delete actions in the action bar. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
850fcfc to
2af19e6
Compare
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.
This change adds custom roles to harbor.
IMPORTANT: This is a POC, the feature is not finalized. The goal is to have some discussion about the proposed design before finalizing the implementation.
Directly Solved Issues:
#18124 RBAC - be able to create a custom role
#18143 Create custom project roles
#21222 Add role for security auditor
#15711 Add a readonly admin role in Harbor
#12062 Make permission system more fine-grained
#21306 - Read-only auditor role (December 2024 - very recent!)
#8632 - Limited guest role
#1486 - Guest shouldn't see all members (from 2016!)
...
Partially Solved Issues:
#10159 - Repository-level permissions (48 👍 - highest demand!)
...
Design changes :
TODO (Partial):
For more details:
Harbor_Custom_Roles_CURRENT_STATUS.md
Harbor_Custom_Roles_Documentation.pdf
https://claude.ai/share/98f704a9-f643-41d6-828e-f2afc81e68bf