From 5e75e6228241ac350743963fa93aa4924a9516a7 Mon Sep 17 00:00:00 2001 From: Maysun J Faisal Date: Wed, 10 Jun 2026 17:07:37 -0400 Subject: [PATCH] feat: enable DCR authentication for Lightspeed MCP servers - Add custom Lightspeed OCI images with DCR support (dcr-0.4.0) - Configure MCP server with auth: dcr in values.yaml - Enable experimentalDynamicClientRegistration - Add @backstage/plugin-auth for OAuth2 consent page Co-authored-by: Cursor --- .../rhdh/templates/rbac-policy-configmap.yaml | 23 +++++++++ charts/rhdh/values.yaml | 50 ++++++++++++++++--- scripts/setup-secrets.sh | 8 +-- 3 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 charts/rhdh/templates/rbac-policy-configmap.yaml diff --git a/charts/rhdh/templates/rbac-policy-configmap.yaml b/charts/rhdh/templates/rbac-policy-configmap.yaml new file mode 100644 index 0000000..3a370fe --- /dev/null +++ b/charts/rhdh/templates/rbac-policy-configmap.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: rbac-policy + namespace: {{ .Release.Namespace }} +data: + rbac-policy.csv: | + p, role:default/mcp-admin, catalog.entity.read, read, allow + p, role:default/mcp-admin, catalog.entity.create, create, allow + p, role:default/mcp-admin, catalog.entity.delete, delete, allow + p, role:default/mcp-admin, catalog.entity.refresh, update, allow + p, role:default/mcp-admin, catalog.location.read, read, allow + p, role:default/mcp-admin, catalog.location.create, create, allow + p, role:default/mcp-admin, scaffolder.task.create, create, allow + p, role:default/mcp-admin, scaffolder.task.read, read, allow + p, role:default/mcp-admin, lightspeed.chat.read, read, allow + p, role:default/mcp-admin, lightspeed.chat.create, create, allow + p, role:default/mcp-admin, lightspeed.chat.delete, delete, allow + p, role:default/mcp-admin, lightspeed.chat.update, update, allow + p, role:default/mcp-admin, lightspeed.mcp.read, read, allow + p, role:default/mcp-admin, lightspeed.mcp.manage, update, allow + p, role:default/mcp-admin, lightspeed.notebooks.use, update, allow + g, user:default/mfaisal, role:default/mcp-admin diff --git a/charts/rhdh/values.yaml b/charts/rhdh/values.yaml index 81672ec..5bde0d3 100644 --- a/charts/rhdh/values.yaml +++ b/charts/rhdh/values.yaml @@ -4,6 +4,24 @@ global: includes: - "dynamic-plugins.default.yaml" plugins: + ##### Disable upstream lightspeed (replaced by custom DCR builds) ##### + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed:bs_1.49.4__2.8.5 + disabled: true + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed-backend:bs_1.49.4__2.8.5 + disabled: true + + ##### OAuth2 consent page plugin (required for DCR) ##### + - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-auth:pr_2498__0.1.6 + disabled: false + pluginConfig: + dynamicPlugins: + frontend: + backstage.plugin-auth: + dynamicRoutes: + - path: /oauth2 + importName: Router + module: PluginRoot + ##### Custom sign in page plugin ##### - package: oci://quay.io/redhat-ai-dev/rolling-demo-customized-sign-in-page:v0.1.1 disabled: false @@ -329,7 +347,7 @@ global: lightspeed: enabled: true plugins: - - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed:bs_1.49.4__2.9.0 + - package: oci://quay.io/maysunfaisal/rhdh-plugin-lightspeed:dcr-0.6.0!red-hat-developer-hub-backstage-plugin-lightspeed disabled: false pluginConfig: dynamicPlugins: @@ -340,7 +358,7 @@ global: module: Alpha ref: lightspeedTranslationRef dynamicRoutes: - - path: /lightspeed + - path: /intelligent-assistant importName: LightspeedPage mountPoints: - mountPoint: application/listener @@ -356,7 +374,7 @@ global: config: id: lightspeed priority: 100 - - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-lightspeed-backend:bs_1.49.4__2.9.0 + - package: oci://quay.io/maysunfaisal/rhdh-plugin-lightspeed-backend:dcr-0.6.0!red-hat-developer-hub-backstage-plugin-lightspeed-backend disabled: false secret: create: false @@ -418,6 +436,10 @@ backstage: enabled: true experimentalRefreshToken: enabled: true + experimentalDynamicClientRegistration: + enabled: true + allowedRedirectUriPatterns: + - '*' session: secret: "${BACKEND_SECRET}" providers: @@ -556,15 +578,22 @@ backstage: - resolver: emailMatchingUserEntityProfileEmail lightspeed: notebooks: - enabled: true + enabled: false queryDefaults: - model: ${NOTEBOOKS_QUERY_MODEL} - provider_id: ${NOTEBOOKS_QUERY_PROVIDER_ID} + model: "${NOTEBOOKS_QUERY_MODEL}" + provider_id: "${NOTEBOOKS_QUERY_PROVIDER_ID}" mcpServers: - name: mcp-integration-tools - token: ${MCP_TOKEN} + auth: dcr mcpActions: namespacedToolNames: false + permission: + enabled: true + rbac: + policies-csv-file: /opt/app-root/src/rbac-policy.csv + admin: + users: + - name: user:default/mfaisal integrations: github: - apps: @@ -671,6 +700,10 @@ backstage: extraVolumeMounts: - name: dynamic-plugins-root mountPath: /opt/app-root/src/dynamic-plugins-root + - name: rbac-policy + mountPath: /opt/app-root/src/rbac-policy.csv + subPath: rbac-policy.csv + readOnly: true # tmp backstage volume for scaffolder tasks - name: backstage-tmp mountPath: /tmp @@ -701,6 +734,9 @@ backstage: emptyDir: {} - name: extensions-catalog emptyDir: {} + - name: rbac-policy + configMap: + name: rbac-policy initContainers: - name: install-dynamic-plugins image: '{{ include "backstage.image" . }}' diff --git a/scripts/setup-secrets.sh b/scripts/setup-secrets.sh index 0976f1d..bee3fae 100755 --- a/scripts/setup-secrets.sh +++ b/scripts/setup-secrets.sh @@ -28,10 +28,12 @@ SECRET_NAME="llama-stack-secrets" log "Creating $SECRET_NAME secret..." kubectl create secret generic "$SECRET_NAME" \ --namespace="$RHDH_NAMESPACE" \ - --from-literal=ENABLE_VLLM="true" \ + --from-literal=ENABLE_VLLM="${ENABLE_VLLM:-}" \ + --from-literal=ENABLE_OPENAI="${ENABLE_OPENAI:-}" \ --from-literal=ENABLE_VALIDATION="true" \ - --from-literal=VLLM_URL="$VLLM_URL" \ - --from-literal=VLLM_API_KEY="$VLLM_API_KEY" \ + --from-literal=VLLM_URL="${VLLM_URL:-}" \ + --from-literal=VLLM_API_KEY="${VLLM_API_KEY:-}" \ + --from-literal=OPENAI_API_KEY="${OPENAI_API_KEY:-}" \ --from-literal=VALIDATION_PROVIDER="$VALIDATION_PROVIDER" \ --from-literal=VALIDATION_MODEL_NAME="$VALIDATION_MODEL_NAME" \ --from-literal=NOTEBOOKS_QUERY_PROVIDER_ID="$NOTEBOOKS_QUERY_PROVIDER_ID" \