fix(cost-management): enable cluster/project RBAC filtering by registering dynamic permissions with RHDH (FLPATH-4207)#3193
Conversation
…roject tiers (FLPATH-4207) Cluster-specific permissions (ros/<cluster>, ros/<cluster>/<project>) were created at runtime but never registered with createPermissionIntegrationRouter. The RHDH RBAC backend only evaluates registered permissions — unregistered ones get DENY by default, breaking the entire 3-tier RBAC model. At router init, fetch cluster/project data from upstream APIs and register all dynamic permissions. Also improve secureProxy.ts error messages (include path and error details instead of opaque "Internal proxy error"). Co-authored-by: Cursor <cursoragent@cursor.com>
Changed Packages
|
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #3193 +/- ##
==========================================
+ Coverage 60.97% 60.99% +0.01%
==========================================
Files 2098 2098
Lines 65140 65181 +41
Branches 17029 17034 +5
==========================================
+ Hits 39721 39756 +35
- Misses 25180 25186 +6
Partials 239 239
*This pull request uses carry forward flags. Click here to find out more. Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
- Extract extractStrings() and buildClusterProjectPermissions() helpers to flatten nested if/for blocks (SonarCloud cognitive complexity 33→8) - Add 8 unit tests covering both helpers (fulfilled/rejected/empty/dedup) - Add changeset for cost-management-backend patch release Co-authored-by: Cursor <cursoragent@cursor.com>
|
asmasarw
left a comment
There was a problem hiding this comment.
LGTM - ran it locally and it works fine.
PreetiW
left a comment
There was a problem hiding this comment.
The RBAC changes here aren't working as expected — registering permissions in createPermissionIntegrationRouter only affects the metadata endpoint, not the authorization flow. Please refer to the Backstage Permission concepts and PRs #1996 / #2102 for the correct approach.



Summary
Cluster-specific RBAC permissions (
ros/<cluster>,ros/<cluster>/<project>, and theircost/equivalents) are created dynamically at runtime byfetchDynamicPermissions()but were never registered withcreatePermissionIntegrationRouter. RHDH's RBAC backend usesPluginPermissionMetadataCollectorto validate permission names before evaluating them against Casbin policies — unregistered permissions default to DENY. This broke the entire 3-tier RBAC model: onlyros.plugin(tier 1) ever worked.Changes
router.ts— At router init, fetch cluster/project data from the upstream Cost Management APIs and register allros/<cluster>,ros/<cluster>/<project>,cost/<cluster>, andcost/<cluster>/<project>permissions with the integration router. UsesPromise.allSettledso a partial failure (e.g. one API down) doesn't block other permissions from registering.secureProxy.ts— Improved error logging and response messages. Previously returned opaque"Internal proxy error"for all non-SSO exceptions; now includes the request path and error details for easier debugging.A/B Test Evidence — Permission Registration
Tested on live RHDH 1.9 cluster (ocp-edge73-0, OCP 4.19). Queried
/api/permission/plugins/policieswith identical configuration, only swapping the plugin image:WITHOUT fix (stock 2.2.0): cost-management plugin registers 3 permissions —
ros.plugin,ros.apply,cost.plugin. Zero dynamic permissions. AnypermissionsSvc.authorize()call forros/ocp-edge73-0-xfvktreturns DENY.WITH fix (2.2.0-rc.1): cost-management plugin registers 174 permissions — the same 3 static plus 171 dynamic cluster/project permissions across 57 unique clusters. Examples:
ros/ocp-edge73-0-xfvkt,ros/ocp-edge73-0-xfvkt/rhdh-operator,ros/ocp-test-mc8h6, etc.This confirms that
createPermissionIntegrationRouterregistration is required for RHDH's RBAC to evaluate these permissions. PRs #1996/#2102 correctly implemented the authorization logic (filterAuthorizedClustersAndProjectscallingauthorize()per cluster), but those calls always returned DENY because the permission names were not registered. This PR completes the circuit.Proof the fix works
Verified on a live RHDH instance (
ocp-edge73) with OCI imagequay.io/gharden/cost-management-dynamic-plugins:2.2.0-rc.1.Tier 1:
ros.plugin— full access (396 containers, no filters)No permissions — access denied
Tier 2:
ros/<cluster>only — cluster-filtered (10 containers, down from 396)Tier 3:
ros/<cluster>/<project>only — cluster+project filteredBackend audit logs
CI
flightpath-ros #95 — 84 passed, 2 failed (pre-existing), 4 skipped. 20 of 21 FLPATH-4207 RBAC tests passed; 1 failure ("full-access user should see data across clusters") is under investigation.
Limitation
Dynamic permissions are registered once at startup. New clusters added after RHDH starts won't be recognized until the pod restarts. A periodic refresh mechanism would be a more complete solution.
Related