diff --git a/workspaces/orchestrator/.changeset/public-rjsf-widget-config.md b/workspaces/orchestrator/.changeset/public-rjsf-widget-config.md new file mode 100644 index 00000000000..ef2b9f59dad --- /dev/null +++ b/workspaces/orchestrator/.changeset/public-rjsf-widget-config.md @@ -0,0 +1,5 @@ +--- +'@red-hat-developer-hub/backstage-plugin-orchestrator-common': patch +--- + +Expose the dedicated `orchestrator.rjsf-widgets` configuration namespace to form widget templates. Values in this namespace are public to the frontend and must not contain secrets. diff --git a/workspaces/orchestrator/docs/orchestratorFormWidgets.md b/workspaces/orchestrator/docs/orchestratorFormWidgets.md index b9042b37c33..8ed18e0ab63 100644 --- a/workspaces/orchestrator/docs/orchestratorFormWidgets.md +++ b/workspaces/orchestrator/docs/orchestratorFormWidgets.md @@ -728,6 +728,16 @@ The widgets manage waiting for asynchronous promises and chains of functions to When exposing additional keys in the future, we will consider not only the [frontend-visibility](https://backstage.io/docs/conf/defining/#visibility) but security as well, since a malicious workflow can retrieve configuration of plugins or Backstage, eventually with their secrets. That’s the reason for listing the exposed keys explicitly. +Values referenced through `rjsfConfig` are configured under `orchestrator.rjsf-widgets`: + +```yaml +orchestrator: + rjsf-widgets: + defaultEnvironment: production +``` + +All values in this namespace are exposed to the frontend and must not contain secrets. + | Key Family | Key | Value of at runtime\(skipping promises for simplicity) | | :-------------------------------------------------------------------------: | :------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | current | \[whatever property name\] | Value of other field/property of the form. The properties build hierarchy separated by `.` (dots) matching the structure of fields/objects defined by the data input schema. Arrays or branches of a complex object structure can be passed as well, data are encoded into JSON in that case. | diff --git a/workspaces/orchestrator/plugins/orchestrator-common/config.d.ts b/workspaces/orchestrator/plugins/orchestrator-common/config.d.ts index 06411a580f6..26ff417e927 100644 --- a/workspaces/orchestrator/plugins/orchestrator-common/config.d.ts +++ b/workspaces/orchestrator/plugins/orchestrator-common/config.d.ts @@ -83,6 +83,14 @@ export interface Config { */ url: string; }; + /** + * Public string values available to form widget templates through `rjsfConfig.`. + * Do not store secrets in this configuration because workflow authors can access every value. + * @deepVisibility frontend + */ + 'rjsf-widgets'?: { + [key: string]: string; + }; /** * Kafka configuration for event-triggered workflows (KafkaJS-style). * When present, the UI can show actions such as "Run as Event". diff --git a/workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useTemplateUnitEvaluator.test.tsx b/workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useTemplateUnitEvaluator.test.tsx index 8c9006592b9..6f24f13f848 100644 --- a/workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useTemplateUnitEvaluator.test.tsx +++ b/workspaces/orchestrator/plugins/orchestrator-form-widgets/src/utils/useTemplateUnitEvaluator.test.tsx @@ -121,6 +121,17 @@ describe('useTemplateUnitEvaluator', () => { ); }); + it('evaluates rjsfConfig.* units from public widget configuration', async () => { + const { result } = renderHook(() => useTemplateUnitEvaluator()); + + await expect( + result.current('rjsfConfig.defaultEnvironment', {} as any), + ).resolves.toBe('from-config'); + expect(configApi.getOptionalString).toHaveBeenCalledWith( + 'orchestrator.rjsf-widgets.defaultEnvironment', + ); + }); + it('evaluates fetch response selector units', async () => { mockedApplySelectorString.mockResolvedValue('resolved-value'); const { result } = renderHook(() => useTemplateUnitEvaluator());