feat: allow dynamically enabling and disabling extensions

Signed-off-by: aramissennyeydd <aramis.sennyey@doordash.com>
This commit is contained in:
aramissennyeydd
2026-03-08 18:08:09 -04:00
committed by Patrik Oldsberg
parent 00381fa7b2
commit 25b7ddd664
23 changed files with 458 additions and 21 deletions
@@ -0,0 +1,7 @@
---
'@backstage/frontend-app-api': patch
---
Extensions with an `enabled` predicate are now evaluated before app tree instantiation, so pages that do not meet their conditions are excluded from the router tree.
`prepareSpecializedApp().finalize()` is now async. Extensions whose `enabled` predicate references `permissions` are checked against the current user's allowed permissions (via a single batched call to `permissionApiRef`) before the app tree is instantiated.
@@ -0,0 +1,5 @@
---
'@backstage/frontend-defaults': patch
---
Updated `createApp` to await the now-async `finalize()` call from `prepareSpecializedApp`, enabling permission-gated extensions to be resolved before the app tree is rendered.
@@ -0,0 +1,7 @@
---
'@backstage/frontend-plugin-api': patch
---
Added `enabled` option to `createExtension`, `createExtensionBlueprint`, and `AppNodeSpec`, accepting a `FilterPredicate` from `@backstage/filter-predicates` to conditionally enable extensions based on feature flags or other runtime conditions.
Added `permissions` option to `createFrontendPlugin` and `createFrontendModule`, allowing plugins and modules to declare which permissions they use. These permissions are checked at app startup so that extensions can conditionally enable themselves using a `permissions` predicate, e.g. `enabled: { permissions: { $contains: 'catalog.entity.create' } }`.