Red Hat Developer Hub 1.9

Explore preview of emerging and supplemental capabilities

Explore features that are new, evolving, or not yet fully covered in the core product documentation

Red Hat Customer Content Services

Abstract

Explore emerging, evolving, and supplemental capabilities in Red Hat Developer Hub, including new features and supported functionality not yet fully covered in the core documentation.

Explore emerging, evolving, and supplemental capabilities in Red Hat Developer Hub, including new features and supported functionality not yet fully covered in the core documentation.

Important

Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.

For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.

DISCLAIMER: This document includes early, evolving, or supplemental content related to RHDH capabilities. It may cover newly introduced features, features that are still maturing, or supported functionality that is not yet fully documented in the official product documentation. This content is authored by Red Hat experts, but has not yet been tested on every supported configuration.

The content in this document describes preview or early-stage capabilities that are provided to offer early guidance and improve discoverability while the documentation continues to evolve. As a result, the structure, depth, and level of detail might vary. Information may be updated, reorganized, or removed based on product changes and user feedback.

Where applicable, individual features retain their respective support status (for example, Supported, Technology Preview, or Developer Preview). Refer to the feature-specific documentation for details about the support scope.

Important

These features are for Technology Preview only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs), might not be functionally complete, and Red Hat does not recommend using them for production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.

For more information on Red Hat Technology Preview features, see Technology Preview Features Scope.

Important

Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.

For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.

1. Integrate Argo CD notifications with Red Hat Developer Hub

This guide explains how to configure Argo CD to send notifications directly to the Red Hat Developer Hub (RHDH) Notifications plugin when application sync events occur.

Important

Administrative requirements: This integration requires infrastructure-level access. To proceed, you must have:

  • cluster-admin permissions on Red Hat OpenShift Container Platform.
  • Write access to the RHDH source code or configuration.

This task is intended for Platform Engineers; it involves cluster-wide runtime changes.

Overview

The following diagram illustrates the flow from an Argo CD event in the cluster to the RHDH user interface.

┌────────────────────────────────────────────────────────────────────┐
│                    Kubernetes / OpenShift Cluster                  │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                         Argo CD                              │   │
│  │  ┌─────────────────┐     ┌────────────────────────────────┐ │   │
│  │  │ Your App        │────▶│ Notifications Controller       │ │   │
│  │  │ (with annotations)    │                                │ │   │
│  │  └─────────────────┘     └───────────────┬────────────────┘ │   │
│  └──────────────────────────────────────────┼──────────────────┘   │
└─────────────────────────────────────────────┼──────────────────────┘
                                              │ Webhook POST
                                              │ (with auth token)
                                              ▼
                    ┌────────────────────────────────────────────┐
                    │              Backstage                     │
                    │  Endpoint: /api/notifications/notifications│
                    │  ──────────────────────────────────────────│
                    │  Shows notifications to users in the UI    │
                    └────────────────────────────────────────────┘

Prerequisites

Before you begin, make sure you have the following:

  • Administrative access to the OpenShift cluster where Argo CD and RHDH are running.
  • Argo CD installed with the notifications controller enabled.
  • Network connectivity from the Argo CD namespace to the RHDH endpoint.

Part 1: Enable the notifications plugin in RHDH

Environment: RHDH Configuration.

Step 1: Enable the dynamic plugins

Add the following to your app-config.yaml or your custom RHDH ConfigMap:

dynamicPlugins:
  frontend:
    backstage-plugin-notifications:
      enabled: true
  backend:
    backstage-plugin-notifications-backend:
      enabled: true

Step 2: Generate and configure a static external access token

To allow Argo CD to authenticate with the RHDH backend, you must provide a secure token.

You can generate a random, unique string to use as a token. In your app-config.yaml, configure the token under the externalAccess section:

backend:
  auth:
    externalAccess:
      - type: static
        options:
          token: ${ARGOCD_NOTIFICATION_TOKEN} # Set this environment variable
          subject: argocd-notifications

Security Note: In production, use a strong, randomly generated token and store it securely.

Part 2: Argo CD configuration

Environment: OpenShift Cluster (executing oc commands).

Once RHDH is configured to receive notifications, configure the Argo CD notifications controller to send them.

Step 1: Enable the notifications controller

For OpenShift GitOps:

oc patch argocd openshift-gitops -n openshift-gitops --type merge -p '
{
  "spec": {
    "notifications": {
      "enabled": true
    }
  }
}'

For standard Argo CD, ensure the notifications controller is deployed.

Step 2: Create the notifications Secret

Store the RHDH authentication token in a cluster secret:

apiVersion: v1
kind: Secret
metadata:
  name: argocd-notifications-secret
  namespace: openshift-gitops # or argocd
type: Opaque
stringData:
  backstage-token: 'your-secret-token-here' # Must match ARGOCD_NOTIFICATION_TOKEN

Apply it:

kubectl apply -f argocd-notifications-secret.yaml

Step 3: Configure notifications

Important for OpenShift GitOps Users: The OpenShift GitOps operator manages the argocd-notifications-cm ConfigMap. If you edit the ConfigMap directly, your changes may be overwritten. Instead, always use the NotificationsConfiguration Custom Resource (CR) as shown below.

Option A: For OpenShift GitOps

Use the NotificationsConfiguration Custom Resource:

Note

This is a customizable template

The configuration below is a starting template that you can customize to fit your needs:

  • Add triggers: You can add more triggers for other events (for example, app.status.sync.status == 'Unknown', app.status.health.status == 'Healthy', app.status.health.status == 'Missing', sync running)
  • Remove triggers: Feel free to remove any triggers you don’t need.
  • Customize templates: Modify the notification titles, descriptions, severity levels, and topics to match your organization’s preferences.
  • Adjust conditions: Modify the when expressions to fine-tune when notifications are sent.

For a complete list of available trigger conditions and variables, see the Argo CD Notifications Triggers documentation.

# Get your Argo CD URL first
ARGOCD_URL=$(oc get routes -n openshift-gitops openshift-gitops-server -o jsonpath='https://{.spec.host}')
BACKSTAGE_URL="https://your-backstage-url.com"

oc apply -n openshift-gitops -f - <<EOF
apiVersion: argoproj.io/v1alpha1
kind: NotificationsConfiguration
metadata:
  name: default-notifications-configuration
  namespace: openshift-gitops
spec:
  # Context provides variables available in templates
  context:
    argocdUrl: ${ARGOCD_URL}

  # Webhook service configuration
  services:
    service.webhook.backstage: |
      url: ${BACKSTAGE_URL}/api/notifications/notifications
      headers:
      - name: Content-Type
        value: application/json
      - name: Authorization
        value: Bearer \$backstage-token

  # Notification templates
  # Note: We use custom names with '-backstage' suffix to avoid conflicts with default templates
  templates:
    template.app-sync-succeeded-backstage: |
      webhook:
        backstage:
          method: POST
          body: |
            {
              "recipients": {
                "type": "entity",
                "entityRef": "{{index .app.metadata.annotations "backstage.io/entity-ref"}}"
              },
              "payload": {
                "title": "{{.app.metadata.name}} - Sync Succeeded",
                "description": "Application {{.app.metadata.name}} has been synced successfully.\n\nHealth: {{.app.status.health.status}}\nRevision: {{.app.status.sync.revision}}",
                "link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
                "severity": "low",
                "topic": "argocd.sync.succeeded"
              }
            }

    template.app-sync-failed-backstage: |
      webhook:
        backstage:
          method: POST
          body: |
            {
              "recipients": {
                "type": "entity",
                "entityRef": "{{index .app.metadata.annotations "backstage.io/entity-ref"}}"
              },
              "payload": {
                "title": "{{.app.metadata.name}} - Sync Failed",
                "description": "Application {{.app.metadata.name}} sync has failed.\n\nPhase: {{.app.status.operationState.phase}}\nMessage: {{.app.status.operationState.message}}",
                "link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
                "severity": "high",
                "topic": "argocd.sync.failed"
              }
            }

    template.app-health-degraded-backstage: |
      webhook:
        backstage:
          method: POST
          body: |
            {
              "recipients": {
                "type": "entity",
                "entityRef": "{{index .app.metadata.annotations "backstage.io/entity-ref"}}"
              },
              "payload": {
                "title": "{{.app.metadata.name}} - Health Degraded",
                "description": "Application {{.app.metadata.name}} health has degraded.\n\nStatus: {{.app.status.health.status}}",
                "link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
                "severity": "high",
                "topic": "argocd.health.degraded"
              }
            }

    template.app-deployed-backstage: |
      webhook:
        backstage:
          method: POST
          body: |
            {
              "recipients": {
                "type": "entity",
                "entityRef": "{{index .app.metadata.annotations "backstage.io/entity-ref"}}"
              },
              "payload": {
                "title": "{{.app.metadata.name}} - Deployed",
                "description": "Application {{.app.metadata.name}} has been successfully deployed and is healthy.",
                "link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}",
                "severity": "low",
                "topic": "argocd.deployed"
              }
            }

  triggers:
    trigger.on-sync-succeeded-backstage: |
      - when: app.status.operationState.phase in ['Succeeded']
        send: [app-sync-succeeded-backstage]

    trigger.on-sync-failed-backstage: |
      - when: app.status.operationState.phase in ['Error', 'Failed']
        send: [app-sync-failed-backstage]

    trigger.on-health-degraded-backstage: |
      - when: app.status.health.status == 'Degraded'
        send: [app-health-degraded-backstage]

    trigger.on-deployed-backstage: |
      - when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy'
        send: [app-deployed-backstage]
EOF

Option B: For Standard Argo CD

For non-OpenShift installations, you can edit the ConfigMap directly:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-notifications-cm
  namespace: argocd
data:
  # Context for template variables
  context: |
    argocdUrl: https://your-argocd-url.com

  # Webhook service configuration
  service.webhook.backstage: |
    url: https://your-backstage-url.com/api/notifications/notifications
    headers:
      - name: Content-Type
        value: application/json
      - name: Authorization
        value: Bearer $backstage-token

  template.app-deployed-backstage: |
    webhook:
      backstage:
        method: POST
        body: |
          {
            "recipients": {
              "type": "entity",
              "entityRef": "{{ index .app.metadata.annotations backstage.io/entity-ref }}"
            },
            "payload": {
              "title": "{{ .app.metadata.name }} - Deployed",
              "description": "Application deployed successfully.",
              "link": "{{ .context.argocdUrl }}/applications/{{ .app.metadata.name }}",
              "severity": "low",
              "topic": "argocd.deployed"
            }
          }
  template.app-health-degraded-backstage: |
    webhook:
      backstage:
        method: POST
        body: |
          {
            "recipients": {
              "type": "entity",
              "entityRef": "{{ index .app.metadata.annotations backstage.io/entity-ref }}"
            },
            "payload": {
              "title": "{{ .app.metadata.name }} - Health Degraded",
              "description": "Application health degraded.",
              "link": "{{ .context.argocdUrl }}/applications/{{ .app.metadata.name }}",
              "severity": "high",
              "topic": "argocd.health.degraded"
            }
          }
  template.app-sync-failed-backstage: |
    webhook:
      backstage:
        method: POST
        body: |
          {
            "recipients": {
              "type": "entity",
              "entityRef": "{{ index .app.metadata.annotations backstage.io/entity-ref }}"
            },
            "payload": {
              "title": "{{ .app.metadata.name }} - Sync Failed",
              "description": "Application sync has failed.",
              "link": "{{ .context.argocdUrl }}/applications/{{ .app.metadata.name }}",
              "severity": "high",
              "topic": "argocd.sync.failed"
            }
          }
  template.app-sync-succeeded-backstage: |
    webhook:
      backstage:
        method: POST
        body: |
          {
            "recipients": {
              "type": "entity",
              "entityRef": "{{ index .app.metadata.annotations backstage.io/entity-ref }}"
            },
            "payload": {
              "title": "{{ .app.metadata.name }} - Sync Succeeded",
              "description": "Application has been synced successfully.",
              "link": "{{ .context.argocdUrl }}/applications/{{ .app.metadata.name }}",
              "severity": "low",
              "topic": "argocd.sync.succeeded"
            }
          }
  trigger.on-deployed-backstage: >
    - when: app.status.operationState.phase == 'Succeeded' and
    app.status.health.status == 'Healthy'
      send: [app-deployed-backstage]
  trigger.on-health-degraded-backstage: |
    - when: app.status.health.status == 'Degraded'
      send: [app-health-degraded-backstage]
  trigger.on-sync-failed-backstage: |
    - when: app.status.operationState.phase in ['Error', 'Failed']
      send: [app-sync-failed-backstage]
  trigger.on-sync-succeeded-backstage: |
    - when: app.status.operationState.phase == 'Succeeded'
      send: [app-sync-succeeded-backstage]

Apply it:

kubectl apply -f argocd-notifications-cm.yaml

Part 3: Enable notifications for your application

Environment: OpenShift Cluster (Argo CD Application manifests).

Update individual Argo CD Application manifests to enable the notifications for specific components.

Add required annotations to your Argo CD application

Each Argo CD Application that should send notifications needs two things:

  1. The Backstage entity reference - tells Argo CD which Backstage entity should receive notifications.
  2. Trigger subscriptions - tells Argo CD which events to notify about.
Important

The subscription annotation format is notifications.argoproj.io/subscribe.<trigger-name>.<service>. The trigger name must match exactly what you configured (with the -backstage suffix).

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: my-application
  namespace: openshift-gitops
  annotations:
    # 1. Map to Backstage entity (REQUIRED)
    backstage.io/entity-ref: 'component:default/my-application'

    # 2. Subscribe to notification triggers (add the ones you want)
    notifications.argoproj.io/subscribe.on-sync-succeeded-backstage.backstage: ''
    notifications.argoproj.io/subscribe.on-sync-failed-backstage.backstage: ''
    notifications.argoproj.io/subscribe.on-health-degraded-backstage.backstage: ''
    notifications.argoproj.io/subscribe.on-deployed-backstage.backstage: ''
spec:
  # ... your application spec

Example: Complete Setup Flow

Scenario

You have a service called order-service managed by Argo CD, and you want the team to receive Backstage notifications on sync events.

  1. Backstage Catalog Entity

    # order-service/catalog-info.yaml
    apiVersion: backstage.io/v1alpha1
    kind: Component
    metadata:
      name: order-service
      description: Order processing service
      annotations:
        argocd/app-selector: 'app.kubernetes.io/instance=order-service'
    spec:
      type: service
      owner: team-orders
      lifecycle: production
  2. Argo CD Application

    # argocd/order-service-app.yaml
    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: order-service
      namespace: openshift-gitops
      annotations:
        # Link to Backstage entity
        backstage.io/entity-ref: 'component:default/order-service'
        # Subscribe to notifications (note the -backstage suffix in trigger names)
        notifications.argoproj.io/subscribe.on-deployed-backstage.backstage: ''
        notifications.argoproj.io/subscribe.on-sync-failed-backstage.backstage: ''
        notifications.argoproj.io/subscribe.on-health-degraded-backstage.backstage: ''
    spec:
      project: default
      source:
        repoURL: https://github.com/myorg/order-service
        targetRevision: main
        path: k8s/overlays/production
      destination:
        server: https://kubernetes.default.svc
        namespace: order-service
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
  3. What Happens

    1. Developer pushes code → Argo CD detects change and syncs.
    2. Sync succeeds → Argo CD notifications controller fires on-deployed-backstage trigger.
    3. Webhook sent → POST to Backstage /api/notifications/notifications.
    4. Notification appears → Team sees "🚀 order-service - Deployed" in Backstage with a link to Argo CD.

1.1. Troubleshooting

1.2. Notifications not appearing in RHDH

  1. Check notifications controller is running:

    kubectl get pods -n openshift-gitops | grep notification
  2. Check controller logs for errors:

    kubectl logs -n openshift-gitops -l app.kubernetes.io/name=argocd-notifications-controller --tail=50
  3. Check logs for backstage-related messages:

    kubectl logs -n openshift-gitops deployment/openshift-gitops-notifications-controller --tail=50 | grep -i backstage
  4. Verify webhook service is configured:

    kubectl get configmap argocd-notifications-cm -n openshift-gitops -o jsonpath='{.data.service\.webhook\.backstage}'
  5. Verify annotations on application:

    kubectl get application my-app -n openshift-gitops -o jsonpath='{.metadata.annotations}' | jq .

1.3. "notification service 'backstage' is not supported"

This error means the webhook service is not configured.

Common causes include the following:

  1. OpenShift GitOps: You edited the ConfigMap directly instead of using NotificationsConfiguration CR. The operator overwrites ConfigMap changes.
  2. Missing service configuration: The service.webhook.backstage key is not in the ConfigMap.

Solution: Use the NotificationsConfiguration CR for OpenShift GitOps (see Part 2).

1.4. Webhook Returns 400 Bad Request / "not valid JSON"

This means the trigger is using the wrong template format (text instead of JSON).

Common causes include the following:

  1. Template name conflicts: Using names like template.app-sync-succeeded that conflict with Argo CD defaults (which use email/message format, not webhook).
  2. Wrong subscription: Application is subscribed to the default trigger instead of your custom one.

Solution: Use custom template/trigger names with a suffix like -backstage:

  • Template: template.app-sync-succeeded-backstage
  • Trigger: trigger.on-sync-succeeded-backstage
  • Subscription: notifications.argoproj.io/subscribe.on-sync-succeeded-backstage.backstage

1.6. Authentication Errors

If you see 401 Unauthorized or token errors:

  1. Verify the token in argocd-notifications-secret matches your Backstage config.
  2. Check the Authorization header format: Bearer $backstage-token.
  3. Restart the notifications controller after secret changes:

    kubectl rollout restart deployment -n openshift-gitops -l app.kubernetes.io/name=argocd-notifications-controller

1.7. Security Considerations

  1. Use strong tokens - Generate random tokens with sufficient entropy.
  2. Rotate tokens periodically - Update both Argo CD secret and Backstage config.
  3. Use HTTPS - Ensure Backstage is accessible over HTTPS in production.
  4. Network policies - Consider restricting which pods can reach Backstage.

1.8. Additional Resources

Legal Notice

Copyright © 2026 Red Hat, Inc.
The text of and illustrations in this document are licensed by Red Hat under a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this document or an adaptation of it, you must provide the URL for the original version.
Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent permitted by applicable law.
Red Hat, Red Hat Enterprise Linux, the Shadowman logo, the Red Hat logo, JBoss, OpenShift, Fedora, the Infinity logo, and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.
Linux® is the registered trademark of Linus Torvalds in the United States and other countries.
Java® is a registered trademark of Oracle and/or its affiliates.
XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States and/or other countries.
MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other countries.
Node.js® is an official trademark of Joyent. Red Hat is not formally related to or endorsed by the official Joyent Node.js open source or commercial project.
The OpenStack® Word Mark and OpenStack logo are either registered trademarks/service marks or trademarks/service marks of the OpenStack Foundation, in the United States and other countries and are used with the OpenStack Foundation's permission. We are not affiliated with, endorsed or sponsored by the OpenStack Foundation, or the OpenStack community.
All other trademarks are the property of their respective owners.