Skip to content

feat(#3734): RBAC-gate the Usage tab behind permission check - #3746

Merged
mareklibra merged 5 commits into
mainfrom
agent/3734-rbac-gate-usage-tab
Aug 19, 2026
Merged

feat(#3734): RBAC-gate the Usage tab behind permission check#3746
mareklibra merged 5 commits into
mainfrom
agent/3734-rbac-gate-usage-tab

Conversation

@fullsend-ai-coder

@fullsend-ai-coder fullsend-ai-coder Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

RBAC-gate the Usage tab using the permission already defined on main by #4185 (aiCatalogAssetAccessUsageDocsPermission / ai-catalog.asset.access.usage-docs, resource-scoped). Users without that permission see a “contact owner” fallback instead of TechDocs or external links.

This does not define a new permission, does not add boost-common (already a frontend dependency), and is not a BasicPermission named ai-catalog.asset.read.usage-docs.

Scope: RHDHPLAN-1509 / RHIDP-15440 — Usage-tab slice of Issue 24 (#4062 / RHIDP-15273). Independent of issue 4 (#4042) and of #4314.

After merge, #4062 should treat UsageTab gating as done and cover the remaining graduated-visibility frontend (other Tier 2 sections, list counts, admin-link visibility).

Changes

  • Gate UsageTab with usePermission + resourceRef: stringifyEntityRef(entity): loading skeleton, allowed = existing docs, denied = permission message and optional owner link from spec.owner
  • Owner links use parseEntityRef (bare name, group:, user:); invalid spec.owner omits the link instead of throwing
  • Add @backstage/plugin-permission-react to the boost frontend plugin
  • Add i18n keys usagePermissionDenied and usageContactOwner
  • Remove the leftover TODO on the Usage tab blueprint in plugin.tsx
  • Add UsageTab.test.tsx covering loading, allowed (TechDocs / links / no docs), denied (with/without/invalid owner), and the exact permission + resourceRef

When the Backstage permission framework is not configured (dev mode), usePermission defaults to allowed: true.

Closes #3734

@fullsend-ai-coder fullsend-ai-coder Bot added the ready-for-review Agent PR ready for human review label Jul 14, 2026
@rhdh-gh-app

rhdh-gh-app Bot commented Jul 14, 2026

Copy link
Copy Markdown

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-boost workspaces/boost/plugins/boost patch v0.5.1

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.51%. Comparing base (7b22bfd) to head (0c5fefe).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3746      +/-   ##
==========================================
+ Coverage   61.49%   61.51%   +0.01%     
==========================================
  Files        2534     2534              
  Lines      101630   101649      +19     
  Branches    28460    28476      +16     
==========================================
+ Hits        62496    62526      +30     
+ Misses      38564    38553      -11     
  Partials      570      570              
Flag Coverage Δ *Carryforward flag
adoption-insights 84.55% <ø> (ø) Carriedforward from d920cc1
ai-integrations 67.70% <ø> (ø) Carriedforward from d920cc1
app-defaults 48.37% <ø> (ø) Carriedforward from d920cc1
augment 46.67% <ø> (ø) Carriedforward from d920cc1
boost 79.70% <100.00%> (+0.37%) ⬆️
bulk-import 72.79% <ø> (ø) Carriedforward from d920cc1
cost-management 13.55% <ø> (ø) Carriedforward from d920cc1
dcm 67.21% <ø> (ø) Carriedforward from d920cc1
e2e-adoption-insights 60.00% <ø> (ø) Carriedforward from d920cc1
e2e-extensions 62.13% <ø> (ø) Carriedforward from d920cc1
e2e-global-header 49.45% <ø> (ø) Carriedforward from d920cc1
e2e-homepage 43.49% <ø> (ø) Carriedforward from d920cc1
e2e-intelligent-assistant 46.68% <ø> (ø) Carriedforward from d920cc1
e2e-orchestrator 49.51% <ø> (ø) Carriedforward from d920cc1
e2e-quickstart 55.21% <ø> (ø) Carriedforward from d920cc1
e2e-scorecard 50.21% <ø> (ø) Carriedforward from d920cc1
e2e-theme 16.36% <ø> (ø) Carriedforward from d920cc1
extensions 56.59% <ø> (ø) Carriedforward from d920cc1
global-floating-action-button 71.18% <ø> (ø) Carriedforward from d920cc1
global-header 66.50% <ø> (ø) Carriedforward from d920cc1
homepage 47.50% <ø> (ø) Carriedforward from d920cc1
install-dynamic-plugins 59.95% <ø> (ø) Carriedforward from d920cc1
intelligent-assistant 75.42% <ø> (ø) Carriedforward from d920cc1
konflux 91.98% <ø> (ø) Carriedforward from d920cc1
lightspeed 69.02% <ø> (ø) Carriedforward from d920cc1
mcp-integrations 83.40% <ø> (ø) Carriedforward from d920cc1
orchestrator 70.92% <ø> (ø) Carriedforward from d920cc1
quickstart 63.74% <ø> (ø) Carriedforward from d920cc1
sandbox 79.56% <ø> (ø) Carriedforward from d920cc1
scorecard 87.36% <ø> (ø) Carriedforward from d920cc1
theme 88.91% <ø> (ø) Carriedforward from d920cc1
translations 5.12% <ø> (ø) Carriedforward from d920cc1
x2a 79.20% <ø> (ø) Carriedforward from d920cc1

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 7b22bfd...0c5fefe. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mareklibra

Copy link
Copy Markdown
Member

/fs-fix add changeset and fix the CI

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 9:12 AM UTC · Completed 9:24 AM UTC
Commit: f57257e · View workflow run →

fullsend-ai-coder Bot added a commit that referenced this pull request Jul 14, 2026
Add changeset for boost-common (minor) and boost (patch) covering the
RBAC permission gating of the Usage tab. Regenerate API reports to
include the new boostAiCatalogUsageDocsPermission export and updated
permission tuple types.

Addresses review feedback on #3746
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 1 (human-triggered)

Added changeset and regenerated API reports to fix the CI 'check api reports' failure. The changeset covers both affected packages: boost-common (minor, new permission export) and boost (patch, UI changes). API reports now reflect the new boostAiCatalogUsageDocsPermission and updated permission aggregation tuples.

Fixed (2):

  1. add changeset: Created changeset rbac-gate-usage-tab.md with minor bump for boost-common (new public boostAiCatalogUsageDocsPermission export) and patch bump for boost (UI permission gating of the Usage tab)
  2. fix the CI (API report check failure): Regenerated API reports for boost-common and boost plugins. boost-common report now includes the new boostAiCatalogUsageDocsPermission export and updated boostFunctionalPermissions (5→6) and boostPermissions (23→24) tuple types. boost report updated with new translation keys and deterministic reordering from API extractor.

Tests: passed

Updated by fullsend fix agent

@mareklibra

Copy link
Copy Markdown
Member

/fs-fix fix CI

@fullsend-ai-coder

fullsend-ai-coder Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

🤖 Finished Fix · ✅ Success · Started 10:12 AM UTC · Completed 10:27 AM UTC
Commit: f57257e · View workflow run →

fullsend-ai-coder Bot added a commit that referenced this pull request Jul 14, 2026
The report.api.md had stale ordering for union members and translation
keys. Regenerated with `yarn build:api-reports:only` so the CI
`--ci` validation passes.

Addresses review feedback on #3746
@fullsend-ai-coder

Copy link
Copy Markdown
Contributor Author

🔧 Fix agent — iteration 2 (human-triggered)

Fixed CI failure by regenerating the boost plugin's report.api.md to match api-extractor output. The file had ordering discrepancies in union members and translation keys.

Fixed (1):

  1. CI failure: check api reports and generate API reference: Regenerated report.api.md for the boost plugin using yarn build:api-reports:only. The committed file had stale ordering for union type members (ExtensionDataRef) and translation ref keys that did not match the output of api-extractor, causing the --ci validation to fail on both Node 22 and Node 24.

Tests: passed

Updated by fullsend fix agent

@mareklibra

Copy link
Copy Markdown
Member

Similar CI issues are in #3735, fixing them there first

@gabemontero
gabemontero requested a review from rohitkrai03 July 14, 2026 13:15
@gabemontero

Copy link
Copy Markdown
Contributor

@rohitkrai03 FYI

@gabemontero

Copy link
Copy Markdown
Contributor

@mareklibra - I also want to cross reference this change with the openspec's I'm curating for RHDHPLAN-1508 before we merge this

@gabemontero gabemontero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this generally aligns/overlaps/compliments the RHDHPLAN-1508 graduated-visibility capability, but has one conflict needs attention.

Overlaps/Aligns/Compliments:

The PR touches these areas we spec'd in https://github.com/gabemontero/rhdh-plugins/tree/rhdhplan-1508-openspecs :

  • Task 1.3 — Define ai-catalog.asset.read.usage-docs: PR defines this (tweak needed in conflict section
  • Task 3.1 — RequirePermission gating on Tier 2 sections: PR Gates UsageTab via usePermission , no changes needed
  • Task 3.2 — Restricted-access placeholder: PR employs "Contact owner" fallback with owner link, no changes needed

Conflict:

BasicPermission vs ResourcePermission

The PR defines the permission as a BasicPermission (no resourceType):

  export const boostAiCatalogUsageDocsPermission = createPermission({
    name: 'ai-catalog.asset.read.usage-docs',
    attributes: { action: 'read' },
  });

Our design (Decision 1) explicitly specifies it as a resource-based permission with resourceType: 'ai-catalog-asset':

  export const boostAiCatalogUsageDocsPermission = createPermission({
    name: 'ai-catalog.asset.read.usage-docs',
    attributes: { action: 'read' },
    resourceType: AI_CATALOG_ASSET_RESOURCE_TYPE,
  });

This matters because:

  • A BasicPermission only returns ALLOW/DENY — it can never return CONDITIONAL
  • Without CONDITIONAL, deployers cannot scope usage-docs visibility by category, connector, or tenant (the whole point of our isAiAssetCategory, isFromConnector, isInTenant rules)
  • If this merges as BasicPermission, we'd have to immediately change it to resource-based in RHDHPLAN-1508, which is a breaking change for any RBAC policies configured in the interim

Complementary (good work we'd keep)

  • The frontend UX pattern — loading skeleton, denied fallback with contact-owner link derived from spec.owner — is solid and aligns with our restricted-access placeholder requirement
  • 6 test cases with proper usePermission mocking — reusable pattern for other Tier 2 sections
  • i18n keys (usagePermissionDenied, usageContactOwner) — exactly what we'd need
  • Removing the TODO(RHDHPLAN-1508) comment — housekeeping we'd want

Not covered by PR (our spec still needed)

  • ai-catalog.asset.read (Tier 1 discovery) — not in PR
  • ai-catalog.admin — not in PR
  • Backend field-level filtering — not in PR
  • Backend authorizeConditional() + toQuery() — not in PR
  • Conditional permission rules — not in PR
  • Everything under epics RHIDP-15274, 15277, 15304 — not in PR

Jira note

The issue references RHIDP-15440 and RHDHPLAN-1509, not RHDHPLAN-1508. But the TODO it removes says RHDHPLAN-1508. The ai-catalog.asset.read.usage-docs permission is clearly ours (RHIDP-15272 under RHDHPLAN-1508). Either RHDHPLAN-1509 has overlapping scope with our plan, or this is simply the frontend vs. backend parts of an end to end flow. WDYT @rohitkrai03 ?

Recommendation

The PR's frontend work is good and complementary — but the permission definition needs to be ResourcePermission<'ai-catalog-asset'> before merging. I'd suggest posting a review comment flagging the BasicPermission→ResourcePermission issue and pointing to our design decision, so it can be fixed in this PR rather than creating immediate tech debt.

Comment thread workspaces/boost/plugins/boost-common/src/permissions.ts Outdated
@mareklibra
mareklibra marked this pull request as draft July 15, 2026 07:47
@sonarqubecloud

Copy link
Copy Markdown

@mareklibra

Copy link
Copy Markdown
Member

Fixed the BasicPermission vs ResourcePermission issue.

The CI is failing, a fix is part of #3735 (tarn update), let's merge it first.

@github-actions

Copy link
Copy Markdown
Contributor

This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution!

@github-actions github-actions Bot added the stale label Jul 29, 2026
@github-actions github-actions Bot closed this Aug 5, 2026
@mareklibra mareklibra reopened this Aug 19, 2026
@github-actions

Copy link
Copy Markdown
Contributor

This pull request adds a new top-level directory under workspaces/. Please follow Submitting a Pull Request for a New Workspace in CONTRIBUTING.md.

@github-actions github-actions Bot removed the stale label Aug 19, 2026
fullsend-ai-coder Bot and others added 4 commits August 19, 2026 14:53
Add RBAC permission gating to the UsageTab entity content extension
in the boost plugin. Users without the ai-catalog.asset.read.usage-docs
permission now see a "contact owner" fallback instead of documentation
content, satisfying RHDHPLAN-1509 requirements.

Changes:
- Define boostAiCatalogUsageDocsPermission (ai-catalog.asset.read.usage-docs)
  in boost-common/src/permissions.ts and add it to boostFunctionalPermissions
- Add @backstage/plugin-permission-common, @backstage/plugin-permission-react,
  and boost-common as dependencies of the boost frontend plugin
- Gate UsageTab rendering with usePermission hook: loading shows skeleton,
  denied shows permission message with optional "Contact owner" link
  derived from spec.owner, allowed renders existing docs content
- Add usagePermissionDenied and usageContactOwner i18n keys
- Remove the TODO(RHDHPLAN-1508) comment from plugin.tsx
- Add UsageTab.test.tsx with 6 test cases covering loading, allowed
  (TechDocs, external links, no docs), and denied (with/without owner)

When the Backstage permission framework is not configured (dev mode),
usePermission defaults to allowed: true, preserving current behavior.

Closes #3734
Add changeset for boost-common (minor) and boost (patch) covering the
RBAC permission gating of the Usage tab. Regenerate API reports to
include the new boostAiCatalogUsageDocsPermission export and updated
permission tuple types.

Addresses review feedback on #3746
Address PR review feedback: make boostAiCatalogUsageDocsPermission a
ResourcePermission (was BasicPermission), pass resourceRef to usePermission,
fix stale permission-count tests, and parse owner refs instead of assuming
a bare group name.
yarn build:api-reports:only --ci was failing because report.api.md
had drifted from the actual public API (translation-key and
extension-output union ordering), the same stale-report class of CI
failure fixed on PR #3747. Regenerate via yarn build:api-reports:only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@mareklibra
mareklibra force-pushed the agent/3734-rbac-gate-usage-tab branch from 37086f8 to d920cc1 Compare August 19, 2026 13:11
@mareklibra

Copy link
Copy Markdown
Member

Rebased

@mareklibra

Copy link
Copy Markdown
Member

After the rebase onto #4185, this PR no longer defines the permission — it only gates UsageTab with the existing aiCatalogAssetAccessUsageDocsPermission (ai-catalog.asset.access.usage-docs, resource-scoped). Please update the PR description (and issue #3734) so they no longer ask for a BasicPermission named ai-catalog.asset.read.usage-docs or a new boost-common dependency.

This is the RHDHPLAN-1509 / RHIDP-15440 Usage-tab slice of Issue 24 (#4062 / RHIDP-15273), not issue 4 (#4042). After merge, #4062 should treat UsageTab gating as done.

Keep a bad spec.owner from crashing the denied fallback, drop the unused
permission-common dependency, and tighten tests around the permission
object and loading skeleton.

Signed-off-by: Marek Libra <marek.libra@gmail.com>
@mareklibra
mareklibra marked this pull request as ready for review August 19, 2026 13:40
@sonarqubecloud

Copy link
Copy Markdown

@gabemontero gabemontero left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clearing my requested change bit @mareklibra

found nothings else with my revisit of this, at this point I'm fine with you curating with fullsend review and merging when you think it is good to go

@mareklibra
mareklibra merged commit 5192aef into main Aug 19, 2026
47 checks passed
@fullsend-ai-retro

fullsend-ai-retro Bot commented Aug 19, 2026

Copy link
Copy Markdown

🤖 Finished Retro · ✅ Success · Started 1:58 PM UTC · Completed 2:12 PM UTC

Commit: 0c5fefe · View workflow run →

@fullsend-ai-retro

Copy link
Copy Markdown

Retro: PR #3746 — RBAC-gate the Usage tab behind permission check

Timeline

  1. Jul 13: mareklibra created issue #3734 with explicit instructions to create a new BasicPermission named ai-catalog.asset.read.usage-docs. Triage agent ran and echoed the plan. /fs-code triggered.
  2. Jul 14: Code agent opened PR #3746 implementing the BasicPermission as specified. Two /fs-fix rounds were needed — first to add a missing changeset, second to regenerate stale report.api.md.
  3. Jul 14: gabemontero reviewed and requested changes: the permission should be a ResourcePermission<'ai-catalog-asset'> per the RHDHPLAN-1508 design, not a BasicPermission.
  4. Jul 15: mareklibra manually fixed the permission type and converted the PR to draft, waiting on upstream #3735 and #4185.
  5. Jul 29 – Aug 5: PR auto-marked stale and auto-closed while waiting for dependencies.
  6. Aug 19: mareklibra reopened the PR, rebased onto merged feat(#4041): add AI Catalog permissions, graduated visibility, and conditional rules #4185 (which landed the permission definition upstream), updated the issue description, and simplified the PR to consume the existing aiCatalogAssetAccessUsageDocsPermission. gabemontero approved. Merged.

Assessment

Code agent performed correctly given its inputs. The original issue explicitly instructed creating a BasicPermission. The code agent did exactly that. The permission type issue (BasicPermission vs ResourcePermission) was a requirement evolution — the RHDHPLAN-1508 design doc and the centralized permission work (#4185) postdated the code agent's run. gabemontero's review correctly caught the design misalignment, but this was a requirements gap, not an agent error.

Code quality was high. The agent produced 8 well-structured test cases with 100% coverage on new code. The permission-denied UX pattern (loading skeleton, denied fallback with optional contact-owner link, graceful handling of invalid owner refs) was praised by the reviewer.

Two fix iterations were avoidable. The code agent omitted a changeset and didn't regenerate API reports. Both are CI requirements that the agent should have handled in its initial commit.

Existing issues with new evidence

Proposals filed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review Agent PR ready for human review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

boost: RBAC-gate the Usage tab

2 participants