Red Hat Developer Hub 1.10

Configuring dynamic plugins

Configuring dynamic plugins in Red Hat Developer Hub

Red Hat Customer Content Services

Abstract

As a platform engineer, you can configure dynamic plugins in Red Hat Developer Hub (RHDH) to access your development infrastructure or software development tools.

Preface

As a platform engineer, you can configure dynamic plugins in Red Hat Developer Hub (RHDH) to access your development infrastructure or software development tools.

Chapter 1. Manage plugin catalog sources

Configure which plugin catalog index images Red Hat Developer Hub extracts to populate the Extensions UI. Separate certified Red Hat plugins from community, partner, or internal custom plugin sources to enable plugin discovery while maintaining governance over plugin installation.

1.1. Prerequisites

  • You have deployed or are preparing to deploy Red Hat Developer Hub using the Helm chart, Operator, or Red Hat Developer Hub Local.
  • You have access to the catalog index image registries you want to configure.

1.2. How primary and extra catalog index images differ

Red Hat Developer Hub can extract plugins from multiple catalog index images to populate the Extensions UI. Understanding the distinction between primary and extra catalog index images helps you control which plugins install automatically and which plugins require explicit configuration.

1.2.1. What catalog index images contain

A catalog index image is an OCI-compliant container image that packages plugin metadata and optional default configurations. Each catalog index image contains one or both of the following directories:

catalog-entities/
Plugin metadata files in Backstage software catalog descriptor format. The Extensions UI reads these files to display available plugins, their descriptions, and installation instructions.
dynamic-plugins.default.yaml
Default plugin configurations that Red Hat Developer Hub applies automatically during installation. Only the primary catalog index image provides this file.

Red Hat Developer Hub extracts these directories from catalog index images during the install-dynamic-plugins init container phase, before the main Red Hat Developer Hub application starts.

1.2.2. Primary catalog index image

The primary catalog index image is the single source of truth for default plugin configurations. You configure the primary catalog by using the CATALOG_INDEX_IMAGE environment variable.

The primary catalog provides:

  • Catalog entities for the Extensions UI
  • The dynamic-plugins.default.yaml file with out-of-the-box plugin configurations

When you deploy Red Hat Developer Hub, plugins listed in the primary catalog’s dynamic-plugins.default.yaml install automatically. This ensures a consistent baseline plugin ecosystem across Red Hat Developer Hub installations.

1.2.3. Extra catalog index images

Extra catalog index images extend plugin discovery without changing default plugin enablement. You configure extra catalogs by using the EXTRA_CATALOG_INDEX_IMAGES environment variable.

Extra catalogs provide:

  • Catalog entities for the Extensions UI
  • No dynamic-plugins.default.yaml file

Plugins from extra catalog index images appear in the Extensions UI but they do not install automatically. To install a plugin from an extra catalog, you must add explicit configuration to your dynamic-plugins.yaml file.

1.2.4. Why this separation matters

The primary versus extra catalog distinction enables governance over your plugin ecosystem:

Prevents conflicting default configurations
Only one source (the primary catalog) provides default plugin configurations. Multiple catalogs attempting to provide defaults for the same plugin would create conflicts.
Enables plugin discovery without automatic installation
Platform teams can make community, partner, and internal custom plugin catalogs visible in the Extensions UI without automatically installing untested or unapproved plugins.
Supports plugin source separation
Different catalog index images can represent different levels of trust: Red Hat certified plugins in the primary catalog, community plugins in one extra catalog, internal custom plugins in another.
Makes plugin provenance visible
The Extensions UI organizes plugins by catalog source, helping developers identify whether a plugin comes from Red Hat, the community, or an internal custom catalog.

1.2.5. Common use cases

Use extra catalog index images when you want to:

  • Offer community plugins for evaluation without automatically installing them
  • Separate certified Red Hat plugins from experimental or preview plugins
  • Provide partner-developed plugins that require approval before installation
  • Make internal custom plugins discoverable to development teams while maintaining installation control
  • Test new plugin versions in a secondary catalog before promoting them to the primary catalog

Additional resources

1.3. Extra catalog subdirectory naming conventions

Red Hat Developer Hub extracts each extra catalog index image into a separate subdirectory under /extensions/extra/. Understanding subdirectory naming rules helps you predict where catalog entities appear and troubleshoot catalog extraction issues.

1.3.1. Why subdirectory names matter

Each extra catalog index image is extracted into its own subdirectory to:

Prevent conflicts and enable source identification

Different catalog index images might provide plugins with the same name. Separate subdirectories ensure plugin metadata from one catalog does not overwrite metadata from another.

The Extensions UI uses the subdirectory name to organize plugins by catalog source. Users can determine whether a plugin comes from the Red Hat catalog, a community catalog, or an internal custom catalog.

Support verification
Platform engineers can inspect /extensions/extra/<subdirectory>/catalog-entities/ to verify that catalog extraction succeeded and that the expected plugins are available.

1.3.2. Explicit naming with the name=image_ref format

You can explicitly name a subdirectory by prefixing the catalog image reference with <name>=:

EXTRA_CATALOG_INDEX_IMAGES="community=quay.io/community/plugin-catalog:latest"

In this example, Red Hat Developer Hub extracts the catalog into /extensions/extra/community/catalog-entities/. The subdirectory name is community.

Use explicit naming to achieve the following benefits:

  • Readable, predictable subdirectory names that are independent of image registry details
  • Stable subdirectory names that do not change when you update image tags or migrate to a different registry
  • Clear source identification in the Extensions UI and verification scripts

1.3.3. Auto-derived naming from image references

If you do not provide an explicit name, Red Hat Developer Hub auto-derives the subdirectory name from the image reference by replacing /, :, and @ characters with underscores (_):

EXTRA_CATALOG_INDEX_IMAGES="quay.io/community/plugin-catalog:latest"

In this example, the subdirectory name becomes quay.io_community_plugin-catalog_latest.

Auto-derived names are useful when:

  • You are testing catalog extraction and do not need readable names
  • You have only one or two extra catalogs and subdirectory name length is not a concern
  • You want to avoid explicitly managing subdirectory names

Auto-derived names can become unwieldy when image references include long registry domains or deeply nested repository paths. For production deployments, explicit naming is recommended.

1.3.4. Duplicate subdirectory names

If you configure multiple catalog index images with the same subdirectory name, Red Hat Developer Hub logs a warning message and applies last-write-wins behavior:

EXTRA_CATALOG_INDEX_IMAGES="internal=registry.example.com/plugins:v1,internal=registry.example.com/plugins:v2"

In this example, both entries use the subdirectory name internal. The second entry (plugins:v2) overwrites the first entry (plugins:v1). The /extensions/extra/internal/catalog-entities/ directory contains only the catalog entities from plugins:v2.

You can use this behavior intentionally to override a catalog entry by placing the override later in the comma-separated list.

1.3.5. Best practices for naming

To avoid confusion and ensure maintainability:

Use explicit names in production deployments
Explicit names are easier to read, remain stable across image updates, and simplify verification scripts.
Avoid duplicate names unless intentionally overriding
Duplicate names cause one catalog to overwrite another. If you need to override a catalog, document the override behavior in your deployment configuration.
Choose short, descriptive names
Names like community, partner, or internal are easier to work with than auto-derived names like quay.io_community_plugins_catalog_v1.10.0.
Use consistent naming across deployment methods
If you deploy Red Hat Developer Hub using both Helm and Operator methods in different environments, use the same subdirectory names to simplify troubleshooting.

1.4. Configure extra catalog index images with the Helm chart

Add extra catalog index images to your Helm chart deployment to make plugins from community, partner, and internal custom catalogs discoverable in the Extensions UI.

Prerequisites

  • You have deployed or are preparing to deploy Red Hat Developer Hub using the Helm chart.
  • You have access to the catalog index image registries you want to configure.
  • You understand the distinction between primary and extra catalog index images.

Procedure

  1. Open your Helm chart values.yaml file for editing.
  2. Add the global.catalogIndex.extraImages parameter with entries for each extra catalog index image you want to configure:

    global:
      catalogIndex:
        extraImages:
          - name: community
            registry: quay.io
            repository: community/rhdh-plugin-catalog
            tag: v1.10.0
          - registry: registry.example.com
            repository: internal/custom-plugins
            tag: latest

    Where:

    name (optional)
    The subdirectory name under /extensions/extra/ where catalog entities are extracted. If omitted, Red Hat Developer Hub auto-derives the name from the image reference.
    registry (required)
    The container registry hostname.
    repository (required)
    The repository path within the registry.
    tag (required)
    The image tag.
  3. Deploy or upgrade the Helm chart:

    $ helm upgrade my-rhdh redhat-developer/backstage \
        --install \
        --values values.yaml \
        --namespace {my-product-namespace}

Verification

  1. Wait for the Red Hat Developer Hub deployment to complete and all pods to reach the Running state:

    $ kubectl get pods -n {my-product-namespace}
  2. Verify that the extra catalog entities were extracted by inspecting the install-dynamic-plugins init container logs:

    $ kubectl logs -n {my-product-namespace} \
        <pod_name> \
        -c install-dynamic-plugins

    Replace <pod_name> with the name of your Red Hat Developer Hub pod. Look for log messages indicating extraction of extra catalog index images.

  3. Verify the subdirectory structure by executing a shell in the Red Hat Developer Hub container:

    $ kubectl exec -n {my-product-namespace} <pod_name> -- ls -l /extensions/extra/

    You should see subdirectories corresponding to the name values or auto-derived names from your extraImages configuration.

  4. Verify that plugins from the extra catalogs appear in the Extensions UI:

    1. Navigate to your Red Hat Developer Hub instance in a web browser.
    2. Open the Extensions UI.
    3. Look for plugins organized under subdirectories matching your extra catalog names.
Note

Plugins from extra catalogs require explicit configuration to install.

1.5. Configure extra catalog index images with the Operator

Add extra catalog index images to your Operator deployment to make plugins from community, partner, and internal custom catalogs discoverable in the Extensions UI.

Prerequisites

  • You have installed the Red Hat Developer Hub Operator.
  • You have created or are preparing to create a Backstage custom resource.
  • You have access to the catalog index image registries you want to configure.
  • You understand the distinction between primary and extra catalog index images.

Procedure

  1. Open your Backstage custom resource YAML file for editing.
  2. Add an extraEnvs section targeting the install-dynamic-plugins container with the EXTRA_CATALOG_INDEX_IMAGES environment variable:

    apiVersion: rhdh.redhat.com/v1alpha3
    kind: {product-custom-resource-type}
    metadata:
      name: {my-product-cr-name}
    spec:
      application:
        extraEnvs:
          envs:
            - name: EXTRA_CATALOG_INDEX_IMAGES
              value: "community=quay.io/community/rhdh-plugin-catalog:v1.10.0,registry.example.com/internal/custom-plugins:latest"
          container: install-dynamic-plugins

    In this example:

  3. The first entry uses the name=image_ref format with an explicit subdirectory name (community).
  4. The second entry uses the plain image_ref format, so Red Hat Developer Hub auto-derives the subdirectory name from the image reference.
  5. Format the EXTRA_CATALOG_INDEX_IMAGES value as a comma-separated list of catalog index images. Each entry can use one of two formats:

    Explicit name format

    <name>=<image_ref>

    Example: community=quay.io/community/plugins:v1.10

    Use this format when you want a readable, stable subdirectory name.

    Plain image reference format

    <image_ref>

    Example: quay.io/community/plugins:v1.10

    Use this format when subdirectory name readability is not critical. Red Hat Developer Hub auto-derives the subdirectory name by replacing /, :, and @ characters with underscores (_).

  6. Apply the Backstage custom resource:

    $ oc apply -f backstage-cr.yaml -n {my-product-namespace}

Verification

  1. Wait for the Red Hat Developer Hub deployment to complete and the pod to reach the Running state:

    $ oc get pods -n {my-product-namespace}
  2. Verify that the extra catalog entities were extracted by inspecting the install-dynamic-plugins init container logs:

    $ oc logs -n {my-product-namespace} \
        <pod_name> \
        -c install-dynamic-plugins

    Replace <pod_name> with the name of your Red Hat Developer Hub pod. Look for log messages indicating extraction of extra catalog index images.

    If you configured duplicate subdirectory names, check for warning messages in the logs.

  3. Verify the subdirectory structure by executing a shell in the Red Hat Developer Hub container:

    $ oc exec -n {my-product-namespace} <pod_name> -- ls -l /extensions/extra/

    You should see subdirectories corresponding to the explicit names or auto-derived names from your EXTRA_CATALOG_INDEX_IMAGES configuration.

  4. Verify that plugins from the extra catalogs appear in the Extensions UI:

    1. Navigate to your Red Hat Developer Hub instance in a web browser.
    2. Open the Extensions UI.
    3. Look for plugins organized under subdirectories matching your extra catalog names.
Note

Plugins from extra catalogs require explicit configuration to install.

1.6. Configure extra catalog index images in disconnected environments

Configure extra catalog index images in disconnected environments. Mirror catalog images to an internal registry and configure the Operator to use them.

Prerequisites

  • You have deployed Red Hat Developer Hub using the Operator in a disconnected or air-gapped environment.
  • You have mirrored the primary catalog index image and any extra catalog index images to an internal container registry.
  • You have access to modify the Red Hat Developer Hub Operator deployment to add RELATED_IMAGE environment variables.
  • You understand the distinction between primary and extra catalog index images.

Procedure

  1. Mirror each extra catalog index image to your internal registry.

    $ skopeo copy \
        docker://quay.io/community/rhdh-plugin-catalog:v1.10.0 \
        docker://internal-registry.example.com/community/rhdh-plugin-catalog:v1.10.0

    Repeat this step for each extra catalog index image you want to configure.

  2. Edit the Red Hat Developer Hub Operator deployment to add RELATED_IMAGE_extra_catalog_index_<name> environment variables for each extra catalog index image. The <name> portion must match the subdirectory name you will use in the EXTRA_CATALOG_INDEX_IMAGES configuration:

    $ oc edit deployment rhdh-operator -n <operator_namespace>

    Replace <operator_namespace> with the namespace where the Red Hat Developer Hub Operator is deployed.

  3. In the Operator deployment, add environment variables to the manager container under spec.template.spec.containers:

    spec:
      template:
        spec:
          containers:
            - name: manager
              env:
                - name: RELATED_IMAGE_extra_catalog_index_community
                  value: internal-registry.example.com/community/rhdh-plugin-catalog:v1.10.0
                - name: RELATED_IMAGE_extra_catalog_index_partner
                  value: internal-registry.example.com/partner/plugin-catalog:v1.0.0

    In this example:

  4. The RELATED_IMAGE_extra_catalog_index_community variable points to the mirrored community catalog image.
  5. The RELATED_IMAGE_extra_catalog_index_partner variable points to the mirrored partner catalog image.
  6. The suffixes community and partner must match the names used in the EXTRA_CATALOG_INDEX_IMAGES configuration in the next step.
  7. Edit your Backstage custom resource to add the EXTRA_CATALOG_INDEX_IMAGES environment variable. Use the same subdirectory names (community, partner) that you used in the RELATED_IMAGE variable names:

    apiVersion: rhdh.redhat.com/v1alpha3
    kind: {product-custom-resource-type}
    metadata:
      name: {my-product-cr-name}
    spec:
      application:
        extraEnvs:
          envs:
            - name: EXTRA_CATALOG_INDEX_IMAGES
              value: "community=internal-registry.example.com/community/rhdh-plugin-catalog:v1.10.0,partner=internal-registry.example.com/partner/plugin-catalog:v1.0.0"
          container: install-dynamic-plugins
    Important

    The subdirectory names in the name=image_ref entries (community, partner) must match the suffixes in the corresponding RELATED_IMAGE_extra_catalog_index_<name> environment variables. If the names do not match, catalog extraction fails.

  8. Apply the Backstage custom resource:

    $ oc apply -f backstage-cr.yaml -n {my-product-namespace}

Verification

  1. Wait for the Red Hat Developer Hub deployment to complete and the pod to reach the Running state:

    $ oc get pods -n {my-product-namespace}
  2. Verify that the extra catalog entities were extracted by inspecting the install-dynamic-plugins init container logs:

    $ oc logs -n {my-product-namespace} \
        <pod_name> \
        -c install-dynamic-plugins

    Replace <pod_name> with the name of your Red Hat Developer Hub pod. Look for log messages indicating successful extraction of extra catalog index images.

  3. Verify the subdirectory structure:

    $ oc exec -n {my-product-namespace} <pod_name> -- ls -l /extensions/extra/

    You should see subdirectories corresponding to the names used in your EXTRA_CATALOG_INDEX_IMAGES configuration (community, partner).

  4. Verify that plugins from the extra catalogs appear in the Extensions UI:

    1. Navigate to your Red Hat Developer Hub instance in a web browser.
    2. Open the Extensions UI.
    3. Look for plugins organized under subdirectories matching your extra catalog names.

Troubleshooting

If catalog extraction fails:

  1. Verify that the RELATED_IMAGE_extra_catalog_index_<name> variable names match the subdirectory names in EXTRA_CATALOG_INDEX_IMAGES.
  2. Check that the mirrored images are accessible from the Red Hat Developer Hub pod’s network.
  3. Inspect the install-dynamic-plugins init container logs for error messages related to image pull failures or name mismatches.

1.7. Configure extra catalog index images with Red Hat Developer Hub Local

Add extra catalog index images to your Red Hat Developer Hub Local deployment to make plugins from community, partner, and internal custom catalogs discoverable in the Extensions UI during local development and testing.

Prerequisites

  • You have installed Red Hat Developer Hub Local.
  • You have access to the catalog index image registries you want to configure.
  • You understand the distinction between primary and extra catalog index images.

Procedure

  1. Locate the Red Hat Developer Hub Local .env file. By default, this file is in the Red Hat Developer Hub Local installation directory.
  2. Open the .env file for editing.
  3. Add or edit the EXTRA_CATALOG_INDEX_IMAGES environment variable with a comma-separated list of catalog index images:

    EXTRA_CATALOG_INDEX_IMAGES="community=quay.io/community/rhdh-plugin-catalog:v1.10.0,quay.io/partner/plugin-catalog:v1.0.0,internal=localhost:5000/custom-plugins:latest"

    In this example:

  4. The first entry uses the name=image_ref format with an explicit subdirectory name (community).
  5. The second entry uses the plain image_ref format, so Red Hat Developer Hub Local auto-derives the subdirectory name from the image reference: quay.io_partner_plugin-catalog_v1.0.0.
  6. The third entry references a locally-hosted registry on localhost:5000 with the explicit name internal.
  7. Save the .env file.
  8. Restart Red Hat Developer Hub Local to apply the configuration:

    $ rhdh-local restart

    Or, if you use Podman Compose directly:

    $ podman-compose down
    $ podman-compose up -d

Verification

  1. Wait for the Red Hat Developer Hub Local containers to start and reach a healthy state:

    $ podman ps
  2. Verify that the extra catalog entities were extracted by checking the /extensions/extra/ directory structure:

    $ podman exec <container_name> ls -l /extensions/extra/

    Replace <container_name> with the name of your Red Hat Developer Hub Local container. You should see subdirectories corresponding to the explicit names or auto-derived names from your EXTRA_CATALOG_INDEX_IMAGES configuration.

  3. Verify that plugins from the extra catalogs appear in the Extensions UI:

    1. Navigate to your local Red Hat Developer Hub instance in a web browser (typically http://localhost:7007).
    2. Open the Extensions UI.
    3. Look for plugins organized under subdirectories matching your extra catalog names.

1.8. EXTRA_CATALOG_INDEX_IMAGES environment variable reference

The EXTRA_CATALOG_INDEX_IMAGES environment variable configures additional catalog index images for plugin discovery in the Extensions UI.

1.8.1. Variable name

EXTRA_CATALOG_INDEX_IMAGES

1.8.2. Purpose

Configures additional catalog index images that Red Hat Developer Hub extracts to populate the Extensions UI with plugins from community, partner, and internal custom catalogs. Plugins from extra catalog index images appear in the Extensions UI but do not install automatically.

1.8.3. Format

Comma-separated list of catalog index image references. Each entry supports two formats:

Explicit name format

<name>=<registry>/<repository>:<tag>

Example: community=quay.io/community/rhdh-plugin-catalog:v1.10.0

Plain image reference format

<registry>/<repository>:<tag>

Example: quay.io/community/rhdh-plugin-catalog:v1.10.0

You can mix both formats in the same comma-separated list.

1.8.4. Behavior

When you configure EXTRA_CATALOG_INDEX_IMAGES, the install-dynamic-plugins init container:

  1. Parses the comma-separated list of catalog index images.
  2. Extracts each catalog index image to /extensions/extra/<subdirectory>/catalog-entities/.
  3. Determines the subdirectory name based on:

    • The explicit <name> if you use the name=image_ref format.
    • An auto-derived name created by replacing /, :, and @ characters with underscores (_) if you use the plain image_ref format.
  4. Extracts only the catalog-entities directory (or marketplace/ or extensions/ as fallbacks) from each catalog index image. The dynamic-plugins.default.yaml file is not extracted from extra catalog index images.
  5. Logs a warning message if multiple entries use the same subdirectory name. The last entry in the list overwrites earlier entries with the same name.

1.8.5. Subdirectory naming examples

The following table shows how Red Hat Developer Hub determines subdirectory names:

EXTRA_CATALOG_INDEX_IMAGES valueResulting subdirectory name

community=quay.io/community/plugins:v1.10

community

quay.io/community/plugins:v1.10

quay.io_community_plugins_v1.10

internal=registry.example.com/custom:latest

internal

registry.example.com/custom:latest

registry.example.com_custom_latest

partner=quay.io/partner/catalog@sha256:abc123

partner

quay.io/partner/catalog@sha256:abc123

quay.io_partner_catalog_sha256_abc123

1.8.6. Relationship to CATALOG_INDEX_IMAGE

CATALOG_INDEX_IMAGE configures the primary catalog index image, which provides:

  • Catalog entities for the Extensions UI
  • The dynamic-plugins.default.yaml file with default plugin configurations

EXTRA_CATALOG_INDEX_IMAGES configures additional catalog index images, which provide:

  • Catalog entities for the Extensions UI
  • No dynamic-plugins.default.yaml file

Only the primary catalog index image provides default plugin configurations. Extra catalog index images provide plugin discovery without automatic installation.

1.8.7. Duplicate handling

If multiple entries in EXTRA_CATALOG_INDEX_IMAGES result in the same subdirectory name, the install-dynamic-plugins init container logs a warning message and applies last-write-wins behavior. The catalog entities from the last entry overwrite earlier entries.

Example with duplicate names:

EXTRA_CATALOG_INDEX_IMAGES="internal=registry.example.com/plugins:v1,internal=registry.example.com/plugins:v2"

In this example:

  • Both entries use the subdirectory name internal.
  • The second entry (plugins:v2) overwrites the first entry (plugins:v1).
  • The /extensions/extra/internal/catalog-entities/ directory contains only the catalog entities from plugins:v2.

You can use this behavior intentionally to override a catalog entry by placing the override later in the comma-separated list.

1.8.8. Supported deployment methods

EXTRA_CATALOG_INDEX_IMAGES is supported in:

  • Helm chart deployments (configured via global.catalogIndex.extraImages)
  • Operator deployments (configured via extraEnvs targeting the install-dynamic-plugins container)
  • Red Hat Developer Hub Local deployments (configured in the .env file)

1.8.9. Disconnected environments

In disconnected or air-gapped environments using the Operator, you must configure matching RELATED_IMAGE_extra_catalog_index_<name> environment variables on the Operator controller. The <name> portion of the RELATED_IMAGE variable must match the subdirectory name used in EXTRA_CATALOG_INDEX_IMAGES.

Example:

# Operator deployment
env:
  - name: RELATED_IMAGE_extra_catalog_index_community
    value: internal-registry.example.com/community/catalog:v1.10

# {product-custom-resource-type} CR
extraEnvs:
  envs:
    - name: EXTRA_CATALOG_INDEX_IMAGES
      value: "community=internal-registry.example.com/community/catalog:v1.10"
  container: install-dynamic-plugins

The subdirectory name community must match in both configurations.

1.9. Extra catalog index directory structure reference

Red Hat Developer Hub extracts catalog index images into a structured directory tree under /extensions/. Understanding this structure helps you verify and troubleshoot catalog extraction and configuration issues.

1.9.1. Primary catalog directory structure

The primary catalog index image (configured via CATALOG_INDEX_IMAGE) is extracted to /extensions/:

/extensions/
├── catalog-entities/          # Plugin metadata for Extensions UI
└── dynamic-plugins.default.yaml  # Default plugin configurations

The catalog-entities/ directory contains Backstage software catalog descriptor files in YAML or JSON format. The Extensions UI reads these files to display available plugins.

The dynamic-plugins.default.yaml file contains default plugin configurations. Red Hat Developer Hub applies these configurations automatically during installation.

1.9.2. Extra catalog directory structure

Each extra catalog index image (configured via EXTRA_CATALOG_INDEX_IMAGES) is extracted to /extensions/extra/<subdirectory>/:

/extensions/
├── catalog-entities/          # From CATALOG_INDEX_IMAGE
├── dynamic-plugins.default.yaml  # From CATALOG_INDEX_IMAGE
└── extra/
    ├── community/
    │   └── catalog-entities/  # From extra catalog "community"
    ├── partner/
    │   └── catalog-entities/  # From extra catalog "partner"
    └── internal/
        └── catalog-entities/  # From extra catalog "internal"

In this example:

  • The community/ subdirectory contains catalog entities from an extra catalog configured with the name community.
  • The partner/ subdirectory contains catalog entities from an extra catalog configured with the name partner.
  • The internal/ subdirectory contains catalog entities from an extra catalog configured with the name internal.

Each subdirectory contains only catalog-entities/. Extra catalog index images do not provide dynamic-plugins.default.yaml.

1.9.3. Subdirectory naming rules

The subdirectory name under /extensions/extra/ is determined by:

Explicit name

When you configure an extra catalog using the name=image_ref format, the subdirectory name is the <name> portion.

Example: community=quay.io/community/plugins:v1.10 creates /extensions/extra/community/.

Auto-derived name

When you configure an extra catalog using the plain image_ref format, Red Hat Developer Hub derives the subdirectory name from the image reference by replacing /, :, and @ characters with underscores (_).

Example: quay.io/community/plugins:v1.10 creates /extensions/extra/quay.io_community_plugins_v1.10/.

1.9.4. Directory structure examples

Single extra catalog with explicit name:

Configuration: EXTRA_CATALOG_INDEX_IMAGES="community=quay.io/community/rhdh-plugin-catalog:v1.10.0"

Resulting directory structure:

/extensions/
├── catalog-entities/
├── dynamic-plugins.default.yaml
└── extra/
    └── community/
        └── catalog-entities/
            ├── plugin-a.yaml
            ├── plugin-b.yaml
            └── plugin-c.yaml

Multiple extra catalogs with mixed naming:

Configuration: EXTRA_CATALOG_INDEX_IMAGES="community=quay.io/community/plugins:v1.10,quay.io/partner/catalog:latest,internal=registry.example.com/custom:v2.0"

Resulting directory structure:

/extensions/
├── catalog-entities/
├── dynamic-plugins.default.yaml
└── extra/
    ├── community/
    │   └── catalog-entities/
    ├── quay.io_partner_catalog_latest/
    │   └── catalog-entities/
    └── internal/
        └── catalog-entities/

In this example:

  • community and internal use explicit names.
  • quay.io_partner_catalog_latest is auto-derived from the image reference quay.io/partner/catalog:latest.

Auto-derived names with complex image references:

Configuration: EXTRA_CATALOG_INDEX_IMAGES="registry.example.com/team/plugins:v1.10.0,quay.io/org/catalog@sha256:abc123"

Resulting directory structure:

/extensions/
├── catalog-entities/
├── dynamic-plugins.default.yaml
└── extra/
    ├── registry.example.com_team_plugins_v1.10.0/
    │   └── catalog-entities/
    └── quay.io_org_catalog_sha256_abc123/
        └── catalog-entities/

Auto-derived names can become unwieldy with complex image references. For production deployments, explicit naming is recommended.

1.9.5. Fallback directory locations

If a catalog index image does not contain a catalog-entities/ directory at the root level, Red Hat Developer Hub checks the following fallback locations in order:

  1. marketplace/
  2. extensions/

If none of these directories exist, no catalog entities are extracted from that catalog index image, and a warning message is logged.

1.9.6. Verifying directory structure

To verify that extra catalog index images were extracted correctly:

  1. Execute a shell in the Red Hat Developer Hub container:

    $ oc exec -n {my-product-namespace} <pod_name> -- ls -lR /extensions/extra/

    Replace <pod_name> with the name of your Red Hat Developer Hub pod.

  2. Check the output for subdirectories matching your configured extra catalog names.
  3. Verify that each subdirectory contains a catalog-entities/ directory with YAML or JSON files.

1.10. Helm chart global.catalogIndex.extraImages parameter reference

The global.catalogIndex.extraImages parameter configures additional catalog index images for plugin discovery in Helm chart deployments.

1.10.1. Parameter path

global.catalogIndex.extraImages

1.10.2. Parameter type

List of objects

1.10.3. Default value

[] (empty list)

1.10.4. Purpose

Configures additional catalog index images that Red Hat Developer Hub extracts to populate the Extensions UI with plugins from community, partner, and internal custom catalogs. The Helm chart converts this parameter into the EXTRA_CATALOG_INDEX_IMAGES environment variable for the install-dynamic-plugins init container.

1.10.5. Sub-fields

Each entry in the extraImages list is an object with the following fields:

Table 1.1. global.catalogIndex.extraImages sub-fields

FieldTypeRequiredDescription

name

String

No

The subdirectory name under /extensions/extra/ where catalog entities are extracted. If omitted, Red Hat Developer Hub auto-derives the name from the image reference by replacing /, :, and @ characters with underscores (_).

registry

String

Yes

The container registry hostname (for example, quay.io, registry.example.com, docker.io).

repository

String

Yes

The repository path within the registry (for example, community/rhdh-plugin-catalog, team/custom-plugins).

tag

String

Yes

The image tag (for example, v1.10.0, latest, sha256:abc123).

1.10.6. Behavior

When you configure global.catalogIndex.extraImages, the Helm chart:

  1. Constructs an EXTRA_CATALOG_INDEX_IMAGES environment variable from the extraImages list.
  2. For each entry:

    • If name is provided, uses the name=registry/repository:tag format.
    • If name is omitted, uses the plain registry/repository:tag format.
  3. Injects the EXTRA_CATALOG_INDEX_IMAGES environment variable into the install-dynamic-plugins init container.
  4. The install-dynamic-plugins init container extracts each catalog index image to /extensions/extra/<subdirectory>/catalog-entities/.

1.10.7. Configuration examples

Single extra catalog with explicit name:

global:
  catalogIndex:
    extraImages:
      - name: community
        registry: quay.io
        repository: community/rhdh-plugin-catalog
        tag: v1.10.0

This configuration creates the environment variable EXTRA_CATALOG_INDEX_IMAGES="community=quay.io/community/rhdh-plugin-catalog:v1.10.0" and extracts catalog entities to /extensions/extra/community/catalog-entities/.

Multiple extra catalogs with mixed naming:

global:
  catalogIndex:
    extraImages:
      - name: community
        registry: quay.io
        repository: community/rhdh-plugin-catalog
        tag: v1.10.0
      - registry: registry.example.com
        repository: partner/plugin-catalog
        tag: latest
      - name: internal
        registry: registry.example.com
        repository: custom/plugins
        tag: v2.0.0

This configuration creates the environment variable:

EXTRA_CATALOG_INDEX_IMAGES="community=quay.io/community/rhdh-plugin-catalog:v1.10.0,registry.example.com/partner/plugin-catalog:latest,internal=registry.example.com/custom/plugins:v2.0.0"

Catalog entities are extracted to /extensions/extra/community/catalog-entities/, /extensions/extra/registry.example.com_partner_plugin-catalog_latest/catalog-entities/, and /extensions/extra/internal/catalog-entities/.

Extra catalog without explicit name:

global:
  catalogIndex:
    extraImages:
      - registry: quay.io
        repository: community/rhdh-plugin-catalog
        tag: v1.10.0

This configuration creates the environment variable:

EXTRA_CATALOG_INDEX_IMAGES="quay.io/community/rhdh-plugin-catalog:v1.10.0"

Catalog entities are extracted to /extensions/extra/quay.io_community_rhdh-plugin-catalog_v1.10.0/catalog-entities/.

1.10.8. Duplicate handling

If multiple entries in extraImages use the same name value (or result in the same auto-derived name), the install-dynamic-plugins init container logs a warning message and applies last-write-wins behavior. The last entry in the list overwrites earlier entries with the same name.

Example with duplicate names:

global:
  catalogIndex:
    extraImages:
      - name: internal
        registry: registry.example.com
        repository: plugins
        tag: v1
      - name: internal
        registry: registry.example.com
        repository: plugins
        tag: v2

In this example:

  • Both entries use the subdirectory name internal.
  • The second entry (plugins:v2) overwrites the first entry (plugins:v1).
  • The /extensions/extra/internal/catalog-entities/ directory contains only the catalog entities from plugins:v2.

1.10.9. Relationship to CATALOG_INDEX_IMAGE

The primary catalog index image is configured using a separate parameter (not shown in this reference). The primary catalog provides both catalog entities and the dynamic-plugins.default.yaml file with default plugin configurations.

The global.catalogIndex.extraImages parameter configures additional catalogs that provide only catalog entities for plugin discovery. Extra catalogs do not provide default plugin configurations.

1.11. Additional resources

Chapter 2. Installing Ansible plugins for Red Hat Developer Hub

Access Ansible-specific portal experience with curated learning paths, push-button content creation, and integrated development tools.

Ansible plugins for Red Hat Developer Hub deliver an Ansible-specific portal experience with curated learning paths, push-button content creation, integrated development tools, and other opinionated resources.

Chapter 3. Install and configure Argo CD

You can use the Argo CD plugin to visualize the Continuous Delivery (CD) workflows in OpenShift GitOps.

3.1. Enable the Argo CD plugin

The Argo CD plugin provides a visual overview of the application's status, deployment details, commit message, author of the commit, container image promoted to environment and deployment history.

Procedure

  1. Add Argo CD instance information to your app-config.yaml configmap as shown in the following example:

    argocd:
      appLocatorMethods:
        - type: 'config'
          instances:
            - name: argoInstance1
              url: https://argoInstance1.com
              username: ${ARGOCD_USERNAME}
              password: ${ARGOCD_PASSWORD}
            - name: argoInstance2
              url: https://argoInstance2.com
              username: ${ARGOCD_USERNAME}
              password: ${ARGOCD_PASSWORD}
    Note

    Avoid using a trailing slash in the url, as it might cause unexpected behavior.

  2. Add the following annotation to the entity's catalog-info.yaml file to identify the Argo CD applications.

    annotations:
      ...
      # The label that Argo CD uses to fetch all the applications. The format to be used is label.key=label.value. For example, rht-gitops.com/janus-argocd=quarkus-app.
    
      argocd/app-selector: '${ARGOCD_LABEL_SELECTOR}'
  3. (Optional) Add the following annotation to the entity's catalog-info.yaml file to switch between Argo CD instances as shown in the following example:

     annotations:
       ...
        # The Argo CD instance name used in `app-config.yaml`.
    
        argocd/instance-name: '${ARGOCD_INSTANCE}'
    Note

    If you do not set this annotation, the Argo CD plugin defaults to the first Argo CD instance configured in app-config.yaml.

  4. To enable the Argo CD plugin, set the disabled property to false in your dynamic-plugins.yaml file as follows:

    Important

    Argo CD contains multiple plugin options you can choose from for your Argo CD configuration:

    • Community Argo CD:

      • @backstage-community/plugin-argocd
      • @backstage-community/plugin-argocd-backend
    • Roadie Argo CD:

      • @roadiehq/backstage-plugin-argo-cd
      • @roadiehq/backstage-plugin-argo-cd-backend

    Community and Roadie plugins are comparable in functionality but have different features. For example, both versions feature scaffolder actions, however, their implementation is different: the Community version contains scaffolder actions by default, the Roadie version requires an additional plugin.

    The recommended combination is to use @backstage-community/plugin-argocd together with @backstage-community/plugin-argocd-backend.

    However, you can also combine @roadiehq/backstage-plugin-argo-cd together with @roadiehq/backstage-plugin-argo-cd-backend.

    Mixing Community and Roadie plugins is not recommended.

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-backstage-plugin-argo-cd-backend:<tag>
        disabled: false
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-argocd:<tag>
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

3.2. Enable Argo CD Rollouts

Enable advanced deployment strategies such as blue-green and canary deployments by integrating Argo CD Rollouts with the Red Hat Developer Hub Kubernetes plugin.

The optional Argo CD Rollouts feature enhances Kubernetes by providing advanced deployment strategies, such as blue-green and canary deployments, for your applications. When integrated into the backstage Kubernetes plugin, it allows developers and operations teams to visualize and manage Argo CD Rollouts seamlessly within the Developer Hub interface.

Prerequisites

  • The Developer Hub Kubernetes plugin (@backstage/plugin-kubernetes) is installed and configured.

  • You have access to the Kubernetes cluster with the necessary permissions to create and manage custom resources and ClusterRoles.
  • The Kubernetes cluster has the argoproj.io group resources (for example, Rollouts and Analysis Runs) installed.

Procedure

  1. In the app-config.yaml file in your Developer Hub instance, add the following customResources component under the kubernetes configuration to enable Argo Rollouts and Analysis Runs:

    kubernetes:
      ...
      customResources:
        - group: 'argoproj.io'
          apiVersion: 'v1alpha1'
          plural: 'Rollouts'
        - group: 'argoproj.io'
          apiVersion: 'v1alpha1'
          plural: 'analysisruns'
  2. Grant ClusterRole permissions for custom resources.

    Note
    1. If the Developer Hub Kubernetes plugin is already configured, the ClusterRole permissions for Rollouts and AnalysisRuns might already be granted.
    2. Use the prepared manifest to give read-only ClusterRole access to both the Kubernetes and ArgoCD plugins.
    1. If the ClusterRole permission is not granted, use the following YAML manifest to create the ClusterRole:
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: backstage-read-only
    rules:
      - apiGroups:
          - argoproj.io
        resources:
          - rollouts
          - analysisruns
        verbs:
          - get
          - list
    1. Apply the manifest to the cluster using kubectl:

      $ kubectl apply -f <your_cluster_role_file>.yaml
    2. Ensure the ServiceAccount accessing the cluster has this ClusterRole assigned.
  3. Add annotations to catalog-info.yaml to identify Kubernetes resources for Backstage.

    1. For identifying resources by entity ID:

      annotations:
        ...
        backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
    2. (Optional) For identifying resources by namespace:

      annotations:
        ...
        backstage.io/kubernetes-namespace: <RESOURCE_NAMESPACE>
    3. For using custom label selectors, which override resource identification by entity ID or namespace:

      annotations:
        ...
        backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
      Note

      Ensure you specify the labels declared in backstage.io/kubernetes-label-selector on your Kubernetes resources. This annotation overrides entity-based or namespace-based identification annotations, such as backstage.io/kubernetes-id and backstage.io/kubernetes-namespace.

  4. Add label to Kubernetes resources to enable Developer Hub to find the appropriate Kubernetes resources.

    1. Developer Hub Kubernetes plugin label: Add this label to map resources to specific Developer Hub entities.

      labels:
        ...
        backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
    2. GitOps application mapping: Add this label to map Argo CD Rollouts to a specific GitOps application

      labels:
        ...
        app.kubernetes.io/instance: <GITOPS_APPLICATION_NAME>
    Note

    If using the label selector annotation (backstage.io/kubernetes-label-selector), ensure the specified labels are present on the resources. The label selector will override other annotations such as kubernetes-id or kubernetes-namespace.

Verification

  1. Push the updated configuration to your GitOps repository to trigger a rollout.
  2. Open Red Hat Developer Hub interface and navigate to the entity you configured.
  3. Select the CD tab and then select the GitOps application. The side panel opens.
  4. In the Resources table of the side panel, verify that the following resources are displayed:

    • Rollouts
    • Analysis Runs (optional)
  5. Expand a rollout resource and review the following details:

    • The Revisions row displays traffic distribution details for different rollout versions.
    • The Analysis Runs row displays the status of analysis tasks that evaluate rollout success.

Chapter 4. Enable and configure the JFrog plugin

Enable and configure the JFrog Artifactory plugin to display container images from your repository in Red Hat Developer Hub.

4.1. Enable the JFrog Artifactory plugin

To enable the JFrog Artifactory plugin, set the disabled property to false.

Procedure

  • To enable the JFrog Artifactory plugin, set the disabled property to false in your dynamic-plugins.yaml file as follows:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-jfrog-artifactory:<tag>
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

4.2. Configure the JFrog Artifactory plugin

Configure proxy settings and annotations to display container images stored in your JFrog Artifactory repository.

Procedure

  1. Set the proxy to the required JFrog Artifactory server in the app-config.yaml file as follows:

    proxy:
      endpoints:
        '/jfrog-artifactory/api':
          target: http://<hostname>:8082 # or https://<customer>.jfrog.io
          headers:
          # Authorization: 'Bearer <YOUR TOKEN>'
          # Change to "false" in case of using a self-hosted Artifactory instance with a self-signed certificate
          secure: true
  2. Add the following annotation to the entity’s catalog-info.yaml file to enable the JFrog Artifactory plugin features in RHDH components:

    metadata:
        annotations:
          'jfrog-artifactory/image-name': '<IMAGE-NAME>'

Chapter 5. Enable and configure the Keycloak plugin

Integrate Keycloak into Red Hat Developer Hub to synchronize users and groups from your Red Hat Build of Keycloak (RHBK) realm. The supported RHBK version is 26.0.

5.1. Enable the Keycloak plugin

Enable the Keycloak plugin to synchronize users and groups from your Red Hat Build of Keycloak realm into Red Hat Developer Hub.

Prerequisites

  • To enable the Keycloak plugin, you must set the following environment variables:

    • KEYCLOAK_BASE_URL
    • KEYCLOAK_LOGIN_REALM
    • KEYCLOAK_REALM
    • KEYCLOAK_CLIENT_ID
    • KEYCLOAK_CLIENT_SECRET

Procedure

  • The Keycloak plugin is pre-loaded in Developer Hub with basic configuration properties. To enable it, set the disabled property to false in your dynamic-plugins.yaml file as follows:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-catalog-backend-module-keycloak:<tag>
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

5.2. Configure the Keycloak plugin

Configure schedule frequency, query parameters, and authentication methods for synchronizing Keycloak users and groups.

Procedure

  1. To configure the Keycloak plugin, add the following in your app-config.yaml file:

    schedule

    Configure the schedule frequency, timeout, and initial delay. The fields support cron, ISO duration, "human duration" as used in code.

         catalog:
           providers:
             keycloakOrg:
               default:
                 schedule:
                   frequency: { minutes: 1 }
                   timeout: { minutes: 1 }
                   initialDelay: { seconds: 15 }
    userQuerySize and groupQuerySize

    Optionally, configure the Keycloak query parameters to define the number of users and groups to query at a time. Default values are 100 for both fields.

       catalog:
         providers:
           keycloakOrg:
             default:
               userQuerySize: 100
               groupQuerySize: 100
    Authentication

    Communication between Developer Hub and Keycloak is enabled by using the Keycloak API. Username and password, or client credentials are supported authentication methods.

    The following table describes the parameters that you can configure to enable the plugin under catalog.providers.keycloakOrg.<ENVIRONMENT_NAME> object in the app-config.yaml file:

    NameDescriptionDefault ValueRequired

    baseUrl

    Location of the Keycloak server, such as https://localhost:8443/auth.

    ""

    Yes

    realm

    Realm to synchronize

    master

    No

    loginRealm

    Realm used to authenticate

    master

    No

    username

    Username to authenticate

    ""

    Yes if using password based authentication

    password

    Password to authenticate

    ""

    Yes if using password based authentication

    clientId

    Client ID to authenticate

    ""

    Yes if using client credentials based authentication

    clientSecret

    Client Secret to authenticate

    ""

    Yes if using client credentials based authentication

    userQuerySize

    Number of users to query at a time

    100

    No

    groupQuerySize

    Number of groups to query at a time

    100

    No

  2. When using client credentials

    1. Set the access type to confidential.
    2. Enable service accounts.
    3. Add the following roles from the realm-management client role:
  3. query-groups
  4. query-users
  5. view-users
  6. Optionally, if you have self-signed or corporate certificate issues, you can set the following environment variable before starting Developer Hub:

    NODE_TLS_REJECT_UNAUTHORIZED=0
    Warning

    Setting the environment variable is not recommended.

5.3. Keycloak plugin metrics

Monitor Keycloak fetch operations and diagnose issues by using OpenTelemetry metrics with Prometheus or Grafana.

The Keycloak backend plugin supports OpenTelemetry metrics that you can use to monitor fetch operations and diagnose potential issues.

5.3.1. Available Counters

Keycloak metrics:

Metric NameDescription

backend_keycloak_fetch_task_failure_count_total

Counts fetch task failures where no data was returned due to an error.

backend_keycloak_fetch_data_batch_failure_count_total

Counts partial data batch failures. Even if some batches fail, the plugin continues fetching others.

5.3.2. Labels

All counters include the taskInstanceId label, which uniquely identifies each scheduled fetch task. You can use this label to trace failures back to individual task executions.

Users can enter queries in the Prometheus UI or Grafana to explore and manipulate metric data.

In the following examples, a Prometheus Query Language (PromQL) expression returns the number of backend failures.

To get the number of backend failures associated with a taskInstanceId:

backend_keycloak_fetch_data_batch_failure_count_total{taskInstanceId="df040f82-2e80-44bd-83b0-06a984ca05ba"} 1

To get the number of backend failures during the last hour:

sum(backend_keycloak_fetch_data_batch_failure_count_total) - sum(backend_keycloak_fetch_data_batch_failure_count_total offset 1h)
Note

PromQL supports arithmetic operations, comparison operators, logical/set operations, aggregation, and various functions. Users can combine these features to analyze time-series data effectively.

Additionally, the results can be visualized using Grafana.

5.3.3. Export metrics

You can export metrics by using any OpenTelemetry-compatible backend, such as Prometheus.

Chapter 6. Enable and configure the Nexus Repository Manager plugin

Use the Nexus Repository Manager plugin to view build artifacts in your Developer Hub application. You can find this community-sourced plugin in the Community plugins migration table.

6.1. Enable the Nexus Repository Manager plugin

Enable the Nexus Repository Manager plugin and configure its frontend mount point to view build artifact details on entity pages in Developer Hub.

Prerequisites

  • You have a running Nexus Repository Manager instance.

Procedure

  • Add the following configuration to your dynamic-plugins.yaml file to enable the plugin and configure its frontend mount point:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-nexus-repository-manager:<tag>
        disabled: false
        pluginConfig:
          dynamicPlugins:
            frontend:
              backstage-community.plugin-nexus-repository-manager:
                mountPoints:
                  - mountPoint: entity.page.image-registry/cards
                    importName: NexusRepositoryManagerPage
                    config:
                      layout:
                        gridColumn: 1 / -1
                      if:
                        anyOf:
                          - isNexusRepositoryManagerAvailable

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

      where:

    pluginConfig
    Configures how the frontend component renders in Developer Hub.
    mountPoint: entity.page.image-registry/cards
    Mounts the artifact view on the Image Registry tab of the entity page.
    importName: NexusRepositoryManagerPage
    The frontend component that displays artifact information.
    isNexusRepositoryManagerAvailable
    A condition that renders the component only for entities that have Nexus Repository Manager annotations.

6.2. Configure the Nexus Repository Manager plugin

Configure the Nexus Repository Manager plugin to display artifact information from your Nexus Repository Manager instance.

Procedure

  1. Set the proxy to the required Nexus Repository Manager server in the app-config.yaml file as follows:

    proxy:
        '/nexus-repository-manager':
        target: 'https://<NEXUS_REPOSITORY_MANAGER_URL>'
        headers:
            X-Requested-With: 'XMLHttpRequest'
            # Uncomment the following line to access a private Nexus Repository Manager using a token
            # Authorization: 'Bearer <YOUR TOKEN>'
        changeOrigin: true
        # Change to "false" in case of using self hosted Nexus Repository Manager instance with a self-signed certificate
        secure: true
  2. Optional: Change the base URL of Nexus Repository Manager proxy as follows:

    nexusRepositoryManager:
        # default path is `/nexus-repository-manager`
        proxyPath: /custom-path
  3. Optional: Enable the following experimental annotations:

    nexusRepositoryManager:
        experimentalAnnotations: true
  4. Annotate your entity using the following annotations:

    metadata:
        annotations:
        # insert the chosen annotations here
        # example
        nexus-repository-manager/docker.image-name: `<ORGANIZATION>/<REPOSITORY>`,

Chapter 7. Monitor continuous integration pipelines with Tekton

The Tekton plugin enables you to monitor CI/CD pipeline results across your Kubernetes or OpenShift clusters. It provides a high-level overview of all associated tasks, allowing you to track the real-time status of your application pipelines.

Prerequisites

  • You have installed and configured the @backstage/plugin-kubernetes and @backstage/plugin-kubernetes-backend dynamic plugins.
  • You have configured the Kubernetes plugin to connect to the cluster using a ServiceAccount.
  • The ClusterRole must be granted for custom resources (PipelineRuns and TaskRuns) to the ServiceAccount accessing the cluster.

    Note

    If you have the RHDH Kubernetes plugin configured, then the ClusterRole is already granted.

  • To view the pod logs, you have granted permissions for pods/log.
  • You can use the following code to grant the ClusterRole for custom resources and pod logs:

    kubernetes:
       ...
       customResources:
         - group: 'tekton.dev'
           apiVersion: 'v1'
           plural: 'pipelineruns'
         - group: 'tekton.dev'
           apiVersion: 'v1'
    
    
     ...
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: backstage-read-only
      rules:
        - apiGroups:
            - ""
          resources:
            - pods/log
          verbs:
            - get
            - list
            - watch
        ...
        - apiGroups:
            - tekton.dev
          resources:
            - pipelineruns
            - taskruns
          verbs:
            - get
            - list

    You can use the prepared manifest for a read-only ClusterRole, which provides access for both Kubernetes plugin and Tekton plugin.

  • Add the following annotation to the entity’s catalog-info.yaml file to identify whether an entity contains the Kubernetes resources:

    annotations:
      ...
    
      backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
  • You can also add the backstage.io/kubernetes-namespace annotation to identify the Kubernetes resources using the defined namespace.

    annotations:
      ...
    
      backstage.io/kubernetes-namespace: <RESOURCE_NS>
  • Add the following annotation to the catalog-info.yaml file of the entity to enable the Tekton related features in RHDH. The value of the annotation identifies the name of the RHDH entity:

    annotations:
      ...
    
      janus-idp.io/tekton : <BACKSTAGE_ENTITY_NAME>
  • Add a custom label selector, which RHDH uses to find the Kubernetes resources. The label selector takes precedence over the ID annotations.

    annotations:
      ...
    
      backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
  • Add the following label to the resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:

    labels:
      ...
    
      backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
    Note

    When you use the label selector, the mentioned labels must be present on the resource.

Procedure

  • To enable the Tekton plugin, set the disabled property to false in your dynamic-plugins.yaml file as follows:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-tekton:<tag>
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

Chapter 8. Enable the Topology plugin

Install and configure the Topology plugin to visualize Kubernetes workloads and manage labels and annotations.

8.1. Install the Topology plugin

Visualize Kubernetes workloads like Deployments, Pods, and Virtual Machines by enabling the Topology plugin.

The Topology plugin enables you to visualize the workloads such as Deployment, Job, Daemonset, Statefulset, CronJob, Pods and Virtual Machines powering any service on your Kubernetes cluster.

Prerequisites

  • You have installed and configured the @backstage/plugin-kubernetes-backend dynamic plugins.
  • You have configured the Kubernetes plugin to connect to the cluster using a ServiceAccount.
  • The ClusterRole must be granted to ServiceAccount accessing the cluster.

    Note

    If you have the Developer Hub Kubernetes plugin configured, then the ClusterRole is already granted.

Procedure

  • The Topology plugin is pre-loaded in Developer Hub with basic configuration properties. To enable it, set the disabled property to false as follows:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-topology:__<tag>__
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

8.2. Configure the Topology plugin

Configure the Topology plugin to view OpenShift routes, pod logs, Tekton PipelineRuns, and virtual machines.

8.2.1. Configure the plugin

Grant read access to routes resource in ClusterRole to view OpenShift routes in the Topology plugin.

Procedure

  1. To view OpenShift routes, grant read access to the routes resource in the ClusterRole:

      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: backstage-read-only
      rules:
        ...
        - apiGroups:
            - route.openshift.io
          resources:
            - routes
          verbs:
            - get
            - list
  2. Also add the following in kubernetes.customResources property in your app-config.yaml file:

    kubernetes:
        ...
        customResources:
          - group: 'route.openshift.io'
            apiVersion: 'v1'
            	  plural: 'routes'

8.2.2. View pod logs

Grant ClusterRole permissions to pods and pods/log resources to view pod logs in the Topology plugin.

Procedure

  • To view pod logs, you must grant the following permission to the ClusterRole:

     apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: backstage-read-only
      rules:
        ...
        - apiGroups:
            - ''
          resources:
            - pods
            - pods/log
          verbs:
            - get
            - list
            - watch

8.2.3. View Tekton PipelineRuns

Grant ClusterRole access to Tekton resources to view PipelineRuns status in the Topology plugin.

Procedure

  1. To view the Tekton PipelineRuns, grant read access to the pipelines, pipelineruns, and taskruns resources in the ClusterRole:

     ...
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: backstage-read-only
      rules:
        ...
        - apiGroups:
            - tekton.dev
          resources:
            - pipelines
            - pipelineruns
            - taskruns
          verbs:
            - get
            - list
  2. To view the Tekton PipelineRuns list in the side panel and the latest PipelineRuns status in the Topology node decorator, add the following code to the kubernetes.customResources property in your app-config.yaml file:

    kubernetes:
        ...
        customResources:
          - group: 'tekton.dev'
            apiVersion: 'v1'
            plural: 'pipelines'
          - group: 'tekton.dev'
            apiVersion: 'v1'
            plural: 'pipelineruns'
          - group: 'tekton.dev'
            apiVersion: 'v1'
            plural: 'taskruns'

8.2.4. View virtual machines

Grant ClusterRole access to VirtualMachines resources to view virtual machine nodes in the Topology plugin.

Prerequisites

  • The OpenShift Virtualization operator is installed and configured on a Kubernetes cluster.

Procedure

  1. Grant read access to the VirtualMachines resource in the ClusterRole:

     ...
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: backstage-read-only
      rules:
        ...
        - apiGroups:
            - kubevirt.io
          resources:
            - virtualmachines
            - virtualmachineinstances
          verbs:
            - get
            - list
  2. To view the virtual machine nodes on the topology plugin, add the following code to the kubernetes.customResources property in the app-config.yaml file:

    kubernetes:
        ...
        customResources:
          - group: 'kubevirt.io'
            apiVersion: 'v1'
            plural: 'virtualmachines'
          - group: 'kubevirt.io'
            apiVersion: 'v1'
            plural: 'virtualmachineinstances'

8.2.5. Enable the source code editor

Enable the source code editor to allow developers to open source code directly from RHDH.

Procedure

  1. Grant read access to the CheClusters resource in the ClusterRole:

     ...
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: backstage-read-only
      rules:
        ...
        - apiGroups:
            - org.eclipse.che
          resources:
            - checlusters
          verbs:
            - get
            - list
  2. Add the following configuration to the kubernetes.customResources property in your app-config.yaml file:

     kubernetes:
        ...
        customResources:
          - group: 'org.eclipse.che'
            apiVersion: 'v2'
            plural: 'checlusters'

8.3. Manage labels and annotations for Topology plugins

Configure labels and annotations to customize Kubernetes resource identification and visualization in the Topology plugin.

8.3.2. Add entity annotations and labels for the Kubernetes plugin

Add annotations and labels to enable RHDH to detect that an entity has Kubernetes components.

Procedure

  1. Add the following annotation to the catalog-info.yaml file of the entity:

    annotations:
      backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
  2. Add the following label to the resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:

    labels:
      backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
    Note

    When using the label selector, the mentioned labels must be present on the resource.

8.3.3. Namespace annotation

Identify Kubernetes resources by namespace using the backstage.io/kubernetes-namespace annotation.

Procedure

  • To identify the Kubernetes resources using the defined namespace, add the backstage.io/kubernetes-namespace annotation:

    annotations:
      backstage.io/kubernetes-namespace: <RESOURCE_NS>

    The Red Hat OpenShift Dev Spaces instance is not accessible using the source code editor if the backstage.io/kubernetes-namespace annotation is added to the catalog-info.yaml file.

    To retrieve the instance URL, you require the CheCluster custom resource (CR). As the CheCluster CR is created in the openshift-devspaces namespace, the instance URL is not retrieved if the namespace annotation value is not openshift-devspaces.

8.3.4. Add a label selector query annotation

Add a custom label selector annotation so that RHDH uses your custom labels to find Kubernetes resources.

Procedure

  1. Add the backstage.io/kubernetes-label-selector annotation to the catalog-info.yaml file of the entity. The label selector takes precedence over the ID annotations:

    annotations:
      backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
  2. Optional: If you have many entities while Red Hat Dev Spaces is configured and want multmanyities to support the edit code decorator that redirects to the Red Hat Dev Spaces instance, add the backstage.io/kubernetes-label-selector annotation to the catalog-info.yaml file for each entity:

    annotations:
      backstage.io/kubernetes-label-selector: 'component in (<BACKSTAGE_ENTITY_NAME>,che)'
  3. If you are using the previous label selector, add the following labels to your resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:

    labels:
      component: che # add this label to your che cluster instance
    labels:
      component: <BACKSTAGE_ENTITY_NAME> # add this label to the other resources associated with your entity

    You can also write your own custom query for the label selector with unique labels to differentiate your entities. However, you need to ensure that you add those labels to the resources associated with your entities including your CheCluster instance.

8.3.5. Display a runtime icon in the topology node

Add a label to workload resources to display a runtime icon in the topology nodes.

Procedure

  • Add the following label to workload resources, such as Deployments:

    labels:
      app.openshift.io/runtime: <RUNTIME_NAME>

    Alternatively, you can include the following label to display the runtime icon:

    labels:
      app.kubernetes.io/name: <RUNTIME_NAME>

    Supported values of <RUNTIME_NAME> include django, dotnet, drupal, go-gopher, golang, grails, jboss, jruby, js, nginx, nodejs, openjdk, perl, phalcon, php, python, quarkus, rails, redis, rh-spring-boot, rust, java, rh-openjdk, ruby, spring, and spring-boot. Other values result in icons not being rendered for the node.

8.3.6. Group applications in the topology view

Add a label to workload resources to display them in a visual group in the topology view.

Procedure

  • Add the following label to workload resources, such as deployments or pods, to display them in a visual group:

    labels:
      app.kubernetes.io/part-of: <GROUP_NAME>

8.3.7. Node connector

Display visual connectors between workload resources like deployments and pods using annotations.

Procedure

  • To display the workload resources such as deployments or pods with a visual connector, add the following annotation:

    annotations:
      app.openshift.io/connects-to: '[{"apiVersion": <RESOURCE_APIVERSION>,"kind": <RESOURCE_KIND>,"name": <RESOURCE_NAME>}]'

8.3.8. Additional resources

Chapter 9. Bulk importing in Red Hat Developer Hub

Automate onboarding of GitHub repositories and GitLab projects to Red Hat Developer Hub catalog, and monitor import status by using bulk import capabilities.

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.

9.1. Repository visibility in Bulk Import

View and bulk-import only the repositories you have permission to access and have not yet added to your catalog.

9.1.1. User-scoped repository access

When you use Bulk Import, Red Hat Developer Hub retrieves the list of available repositories using your authenticated user credentials through OAuth. Repository and organization listing API calls use your OAuth token for each configured source code management (SCM) host, ensuring that results match your personal access permissions rather than server-wide integration credentials.

This approach provides several benefits:

User-scoped access
You see only repositories you can access in GitHub or GitLab, matching your experience in those platforms.
Enhanced security
Import operations use your personal access token, maintaining audit trails tied to your user account.
Permission alignment
Repository visibility respects your organizational access policies and role-based permissions.

This differs from catalog discovery providers, which use service account credentials to automatically discover and import repositories containing catalog-info.yaml files across an entire organization.

9.1.2. Technical implementation

Bulk Import requires user authentication for all repository and organization listing operations. The following API endpoints require a valid OAuth token:

  • GET /repositories - List all accessible repositories
  • GET /organizations/{org}/repositories - List repositories in a specific organization

These endpoints use the X-SCM-Tokens header to pass user OAuth tokens for GitHub and GitLab hosts. There is no fallback to server-wide integration credentials (GitHub App, PAT, or GitLab token) for these listing operations. Requests without valid user OAuth tokens are rejected with HTTP 401 Unauthorized.

Important

Deployments that previously relied on integration-only listing must configure SCM authentication providers for user authentication. See the Bulk Import plugin documentation for configuration details.

9.1.3. Automatic filtering of imported repositories

The Bulk Import interface automatically excludes repositories that are already present in your Developer Hub catalog, showing only repositories that have not yet been imported. This filtering helps you:

  • Avoid duplicate catalog entries.
  • Focus on new repositories that need onboarding.
  • Identify which repositories remain to be imported from your Git provider.
Note

If a repository is removed from the catalog, it will reappear in the Bulk Import repository list and can be imported again.

9.1.4. Prerequisites for repository visibility

User authentication with OAuth is a mandatory requirement for the Bulk Import feature. To view and import repositories through Bulk Import, you must:

  • Configure GitHub or GitLab authentication using one of the following approaches:

    • As your primary authentication provider for Developer Hub.
    • As an auxiliary authentication provider if you use another primary provider, for example, OIDC or Red Hat build of Keycloak.
  • Configure SCM authentication providers with OAuth support for your Git hosts
  • Have the bulk.import permission configured in RBAC policies.
  • Maintain an active OAuth session with your Git provider.
Warning

Repository and organization listing operations require user OAuth tokens. There is no fallback to server-wide integration credentials. Deployments without user authentication configured will receive HTTP 401 errors when accessing Bulk Import.

9.1.5. Troubleshooting repository visibility

If you cannot see expected repositories in the Bulk Import interface, verify the following:

User access
Your user account has access to those repositories in GitHub or GitLab
Catalog status
The repositories are not already imported into the Developer Hub catalog
Session validity
Your Developer Hub OAuth session has not expired
Authentication configuration
GitHub or GitLab authentication provider is correctly configured
ScmAuthApi registration
The ScmAuthApi is properly registered for your SCM hosts

If you receive HTTP 401 Unauthorized errors when accessing the Bulk Import page, this indicates that user OAuth tokens are not available. Verify that:

  • You have authenticated to Developer Hub using GitHub or GitLab as your authentication provider
  • Your authentication provider includes OAuth scopes required for repository access
  • The SCM authentication provider is configured and registered in your Developer Hub deployment

9.2. Enable and authorize Bulk Import capabilities in Red Hat Developer Hub

Enable Bulk Import plugins and configure RBAC permissions to allow users to import multiple GitHub repositories and GitLab projects into the catalog.

Prerequisites

Important

Bulk Import requires user OAuth tokens for all repository and organization listing operations. Deployments without user authentication configured will receive HTTP 401 Unauthorized errors when accessing the Bulk Import feature.

Procedure

  1. The Bulk Import plugins are installed but disabled by default. To enable the ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic and ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import plugins, edit your dynamic-plugins.yaml with the following content:

    plugins:
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic
        disabled: false
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
        disabled: false

    See Installing and viewing plugins in Red Hat Developer Hub.

  2. Configure the required bulk.import RBAC permission for the users who are not administrators as shown in the following code:

    rbac-policy.csv fragment

    p, role:default/bulk-import, bulk.import, use, allow
    g, user:default/<your_user>, role:default/bulk-import

    Note that only Developer Hub administrators or users with the bulk.import permission can use the Bulk Import feature. See Permission policies in Red Hat Developer Hub.

Verification

  1. The sidebar displays a Bulk Import option.
  2. The Bulk Import page shows a list of added GitHub repositories and GitLab projects.

9.3. Import multiple GitHub repositories

Select and import multiple GitHub repositories that you can access into the Red Hat Developer Hub catalog, automatically creating pull requests with required catalog-info.yaml files.

Note

The Bulk Import feature displays only repositories that your GitHub user account can access and that are not already imported into the Developer Hub catalog. Repository visibility is determined by your GitHub permissions, not the Developer Hub GitHub App configuration.

Procedure

  1. Click Bulk Import in the Developer Hub left sidebar.
  2. If your RHDH instance has multiple source control tools configured, select GitHub from the Source control tool list.

    The interface displays GitHub repositories that your authenticated user account can access, excluding repositories already present in the catalog.

  3. Select the repositories to import, and click Add.

    Developer Hub creates a pull request in each selected repository to add the required catalog-info.yaml file using your GitHub credentials.

  4. For each repository to import, click PR to review and merge the changes in GitHub.

Verification

  1. Click Bulk Import in the Developer Hub left sidebar.
  2. Verify that each imported GitHub repository in the Selected repositories list has the status Waiting for approval or Imported.
  3. For each Waiting for approval repository, click the pull request link to review and merge the catalog-info.yaml file in the corresponding repository.

    The pull request is created using your GitHub user account, ensuring proper attribution in the repository history.

9.4. Import multiple GitLab repositories

Select and import multiple GitLab projects that you can access into the Red Hat Developer Hub catalog, automatically creating merge requests with required catalog-info.yaml files.

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.

Prerequisites

Note

The Bulk Import feature displays only projects that your GitLab user account can access and that are not already imported into the Developer Hub catalog. Project visibility is determined by your GitLab permissions, not the Developer Hub GitLab integration token configuration.

Procedure

  1. In the Developer Hub left sidebar, click Bulk Import.
  2. If your RHDH instance has multiple source control tools configured, select GitLab from the Source control tool list.

    The interface displays GitLab projects that your authenticated user account can access, excluding projects already present in the catalog.

  3. Select the projects to import, and click Add.

    Developer Hub creates a merge request in each selected project to add the required catalog-info.yaml file using your GitLab credentials.

  4. For each project to import, click MR to review and merge the changes in GitLab.

Verification

  1. Click Bulk Import in the Developer Hub left sidebar.
  2. Verify that each imported GitLab project in the Selected projects list has the status Waiting for approval or Imported.
  3. For projects with the Waiting for approval status, click the merge request link to review and add the catalog-info.yaml file to the project repository.

    The merge request is created using your GitLab user account, ensuring proper attribution in the project history.

9.5. Monitor Bulk Import actions using audit logs

Review Bulk Import backend plugin audit log events to monitor repository import operations, track API requests, and troubleshoot import issues.

Procedure

  1. Access your Developer Hub backend logs where audit log events are recorded.
  2. Review the following Bulk Import audit log events to monitor repository operations:

    BulkImportUnknownEndpoint
    Tracks requests to unknown endpoints.
    BulkImportPing
    Tracks GET requests to the /ping endpoint, which allows us to make sure the bulk import backend is up and running.
    BulkImportFindAllOrganizations
    Tracks GET requests to the /organizations endpoint, which returns the list of organizations accessible from all configured GitHub Integrations.
    BulkImportFindRepositoriesByOrganization
    Tracks GET requests to the /organizations/:orgName/repositories endpoint, which returns the list of repositories for the specified organization (accessible from any of the configured GitHub Integrations).
    BulkImportFindAllRepositories
    Tracks GET requests to the /repositories endpoint, which returns the list of repositories accessible from all configured GitHub Integrations.
    BulkImportFindAllImports
    Tracks GET requests to the /imports endpoint, which returns the list of existing import jobs along with their statuses.
    BulkImportCreateImportJobs
    Tracks POST requests to the /imports endpoint, which allows to submit requests to bulk-import one or many repositories into the Developer Hub catalog, by eventually creating import pull requests in the target repositories.
    BulkImportFindImportStatusByRepo
    Tracks GET requests to the /import/by-repo endpoint, which fetches details about the import job for the specified repository.
    BulkImportDeleteImportByRepo

    Tracks DELETE requests to the /import/by-repo endpoint, which deletes any existing import job for the specified repository, by closing any open import pull request that could have been created.

    Example audit log output:

    {
      "actor": {
        "actorId": "user:default/myuser",
        "hostname": "localhost",
        "ip": "::1",
        "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
      },
      "eventName": "BulkImportFindAllOrganizations",
      "isAuditLog": true,
      "level": "info",
      "message": "'get /organizations' endpoint hit by user:default/myuser",
      "meta": {},
      "plugin": "bulk-import",
      "request": {
        "body": {},
        "method": "GET",
        "params": {},
        "query": {
          "pagePerIntegration": "1",
          "sizePerIntegration": "5"
        },
        "url": "/api/bulk-import/organizations?pagePerIntegration=1&sizePerIntegration=5"
      },
      "response": {
        "status": 200
      },
      "service": "backstage",
      "stage": "completion",
      "status": "succeeded",
      "timestamp": "2024-08-26 16:41:02"
    }

9.6. Input parameters for Bulk Import Scaffolder template

Define Scaffolder template parameters such as repository URL, name, organization, and branch details to customize bulk import automation workflows for your repositories.

As an administrator, you can use the Bulk Import plugin to run a Scaffolder template task with specified parameters, which you must define within the template.

The Bulk Import plugin analyzes Git repository information and provides the following parameters for the Scaffolder template task:

repoUrl

Normalized repository URL in the following format:

  ${gitProviderHost}?owner=${owner}&repo=${repository-name}
name
The repository name.
organization
The repository owner, which can be a user nickname or organization name.
branchName
The proposed repository branch. By default, the proposed repository branch is bulk-import-catalog-entity.
targetBranchName
The default branch of the Git repository.
gitProviderHost
The Git provider host parsed from the repository URL. You can use this parameter to write Git-provider-agnostic templates.

Example of a Scaffolder template:

parameters:
  - title: Repository details
    required:
      - repoUrl
      - branchName
      - targetBranchName
      - name
      - organization
    properties:
      repoUrl:
        type: string
        title: Repository URL ({product-short} format)
        description: github.com?owner=Org&repo=repoName
      organization:
        type: string
        title: Owner of the repository
      name:
        type: string
        title: Name of the repository
      branchName:
        type: string
        title: Branch to add the catalog entity to
      targetBranchName:
        type: string
        title: Branch to target the PR/MR to
      gitProviderHost:
        type: string
        title: Git provider host

9.7. Set up a custom Scaffolder workflow for Bulk Import

Create custom Scaffolder templates aligned with your organization’s repository conventions to automate bulk import tasks such as entity imports, pull request creation, and webhook integration.

As an administrator, you can create a custom Scaffolder template inline with the repository conventions of your organization and add the template into the Red Hat Developer Hub catalog for use by the Bulk Import plugin on many selected repositories.

You can define various custom tasks, including, but not limited to the following:

  • Importing existing catalog entities from a repository
  • Creating pull requests for cleanup
  • Calling webhooks for external system integration

Prerequisites

  • You created a custom Scaffolder template for the Bulk Import plugin.
  • You have run your RHDH instance with the following environment variable enabled to allow the use of the Scaffolder functionality:

    export NODE_OPTIONS=--no-node-snapshot

Procedure

  • Configure your app-config.yaml configuration to instruct the Bulk Import plugin to use your custom template as shown in the following example:

    bulkImport:
      importTemplate: <your_template_entity_reference_or_template_name>
      importAPI: `open-pull-requests` | `scaffolder`;

    where:

    importTemplate:
    Enter your Scaffolder template entity reference.
    importAPI
    Set the API to 'scaffolder' to trigger the defined workflow for high-fidelity automation. This field defines the import workflow and currently supports two following options:
    open-pull-requests
    This is the default import workflow, which includes the logic for creating pull requests for every selected repository.
    scaffolder

    This workflow uses an import scenario defined in the Scaffolder template to create import jobs. Select this option to use the custom import scenario defined in your Scaffolder template.

    Optional: You can direct the Bulk Import plugin to hand off the entire list of selected repositories to a custom Orchestrator workflow.

    Important

    The Scaffolder template must be generic and not specific to a single repository if you want your custom Scaffolder template to run successfully for every repository in the bulk list.

Verification

  • The Bulk Import plugin runs the custom Scaffolder template for the list of repositories using the /task-imports API endpoint.

9.8. Run Orchestrator workflows for bulk imports

Configure Bulk Import to use Orchestrator workflows for advanced bulk operations across multiple repositories, enabling automated pull request creation and configuration publishing at scale.

As a platform engineer, you can configure the Bulk Import plugin to run Orchestrator workflows for bulk import operations. This mode uses the Orchestrator engine to provide advanced capabilities, such as creating pull requests or publishing configurations across multiple repositories.

Prerequisites

Procedure

  1. Configure the Bulk Import plugin by editing your app-config.yaml file to enable Orchestrator mode.

    bulkImport:
      orchestratorWorkflow: your_workflow_id
      importAPI: 'orchestrator'

    where:

    orchestratorWorkflow
    The ID of the workflow to run for each repository.
    importAPI
    The execution mode for the workflow. Enter orchestrator to enable workflow execution.
  2. Verify that the Orchestrator workflow receives the following input:

    {
      "inputData": {
        "owner": "redhat-developer",
        "repo": "rhdh-plugins",
        "baseBranch": "main",
        "targetBranch": "bulk-import-orchestrator"
      },
      "authTokens": [
        {
          "token": "<github_token>",
          "provider": "github"
        }
      ]
    }

    where:

    owner
    Specifies the repository owner (organization or user name).
    repo
    Specifies the repository name.
    baseBranch
    Specifies the default branch of the Git repository (for example, main).
    targetBranch
    Specifies the target branch for the import operation. By default, this is set to bulk-import-orchestrator.
    authTokens
    Specifies the authentication tokens for the Git provider:
  3. For GitHub: { token: <github_token>, provider: github }
  4. For GitLab: { token: <gitlab_token>, provider: gitlab }
  5. Navigate to the Bulk Import page in the sidebar and complete the following steps:

    1. Select your Git provider (for example, GitHub or GitLab).
    2. Select the projects you want to import.
  6. Click import to run the workflow.

Verification

  • Locate your repository and confirm status is COMPLETED.

9.9. Data handoff and custom workflow design

Design Scaffolder templates to receive repository data as parameters and automate repository-specific tasks when using Scaffolder mode for bulk imports.

When you configure the Bulk Import plugin by setting the importAPI field to scaffolder, the Bulk Import Backend passes all necessary context directly to the Scaffolder API.

As an administrator, you can define the Scaffolder template workflow and structure the workflow to do the following:

Define template parameters to consume input
Structure the Scaffolder template to receive the repository data as template parameters for the current workflow run. The template must be generic, and not specific to a single repository, so that it can successfully run for every repository in the bulk list.
Automate processing for each repository
Implement the custom logic needed for a single repository within the template. The Orchestrator iterates through the repository list, launching the template once for each repository and passes only the data for that single repository to the template run. This allows you to automate tasks such as creating the catalog-info.yaml, running compliance checks, or registering the entity with the catalog.

Chapter 10. ServiceNow custom actions in Red Hat Developer Hub

Integrate ServiceNow with Red Hat Developer Hub to manage ServiceNow records by using Scaffolder actions and view ServiceNow data on entity pages.

In Red Hat Developer Hub, you can use ServiceNow custom actions to fetch and register resources within the catalog.

The custom actions in Developer Hub help you automate the management of records. By using the custom actions, you can:

  • Create, update, or delete a record
  • Retrieve information about a single record or many records

The ServiceNow custom actions plugin is community-sourced.

10.1. ServiceNow entity linking methods

To view and manage ServiceNow incidents directly in Red Hat Developer Hub (RHDH), you must link an entity to your ServiceNow records. Linking ensures that incident data is accurately synchronized and visible within the relevant component or system.

Red Hat Developer Hub provides two methods for linking these entities. You can choose the method that best fits your organization’s security requirements and your ability to modify the ServiceNow schema.

10.1.1. Direct mapping (Backstage Entity ID column)

The default method requires adding a custom column named backstage_entity_id to your ServiceNow incident table. You then manually or programmatically assign the specific RHDH entity reference (for example, component:default/my-service) to this column in ServiceNow.

  • Advantages:

    • Highly secure and precise
    • Ensures data is only exposed to the intended entity
  • Limitations:

    • Requires a schema change in ServiceNow
    • Requires manual data entry for each incident

10.1.2. Flexible mapping (Custom column mapping)

The flexible mapping approach is an opt-in feature that allows you to use any existing column in your ServiceNow incident table to link to RHDH entities. Instead of creating a new column, you configure the ServiceNow plugin to look at an existing field (such as short_description, cmdb_ci, or a custom organizational ID) to match the entity.

  • Advantages:

    • Does not require ServiceNow schema changes
    • Faster to implement for organizations with strict ServiceNow governance
  • Limitations:

    • Requires careful configuration to ensure that the search criteria in the chosen column are unique enough to prevent displaying unrelated incidents

10.1.3. Comparison of linking methods

FeatureDirect mappingFlexible mapping

ServiceNow schema change

Required

Not required

Security level

High (strict matching)

Medium (dependent on column data)

Configuration complexity

Low (plugin side)

Medium (requires YAML mapping)

Ideal use case

New ServiceNow instances or high-security environments

Existing ServiceNow instances where schema changes are restricted

10.1.4. Configure the ServiceNow plugin in the ConfigMap

Update the Red Hat Developer Hub ConfigMap to enable the ServiceNow backend, frontend, and Scaffolder actions. This configuration defines the connection parameters and UI components required to integrate ServiceNow with your software catalog.

Prerequisites

  • You have provisioned a custom configuration by following the steps in Provisioning and using your custom Developer Hub configuration, including the section on authoring a custom dynamic-plugins.yaml file.
  • You have administrator access to an Red Hat OpenShift Container Platform cluster.
  • Red Hat Developer Hub is installed on the cluster.

Procedure

  1. Open your Red Hat Developer Hub ConfigMap for editing.
  2. Add the ServiceNow backend and frontend plugin packages to the dynamic-plugins.yaml section, including the connection and UI configuration:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: rhdh-plugin-config
    data:
      dynamic-plugins.yaml: |
        includes:
          - dynamic-plugins.default.yaml
        plugins:
          # -----------------------------------------------------------------
          # ... Your pre-existing custom dynamic plugins would be listed here
          # -----------------------------------------------------------------
    
          # ServiceNow Backend Plugin
          - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-servicenow-backend:<tag>'
            disabled: false
            pluginConfig:
              servicenow:
                instanceUrl: ${SERVICENOW_BASE_URL}
                basicAuth:
                  username: ${SERVICENOW_USERNAME}
                  password: ${SERVICENOW_PASSWORD}
    
          # ServiceNow Scaffolder Module / Actions
          - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-scaffolder-backend-module-servicenow:<tag>'
            disabled: false
            pluginConfig:
              servicenow:
                baseUrl: ${SERVICENOW_BASE_URL}
                username: ${SERVICENOW_USERNAME}
                password: ${SERVICENOW_PASSWORD}
    
          # ServiceNow Frontend Plugin
          - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-servicenow:<tag>'
            disabled: false

    where:

    <tag>
    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:
  3. Find your Backstage version in the RHDH release notes preface.
  4. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

    Tip

    To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

  5. Save the changes to the ConfigMap.
  6. Wait for the RHDH Operator to redeploy the pods. The plugins are available once the pods are in a Running state.

10.1.6. Use ServiceNow scaffolder actions in software templates

Add ServiceNow actions to your software templates to automate the creation, retrieval, and modification of ServiceNow records during the software scaffolding process.

Prerequisites

  • You have configured the ServiceNow instance parameters in the Red Hat Developer HubConfigMap or app-config.yaml file.
  • You have the required permissions to edit Software Templates in the source repository.
  • You have registered the Software Template in the Red Hat Developer Hub catalog.

Procedure

  1. Open your software template YAML file.
  2. In the spec.steps section, add the ServiceNow action that corresponds to your goal.
  3. Define the tableName and the requestBody containing the fields to populate or modify. The following example demonstrates how to use the servicenow:now:table:createRecord action to generate an incident ticket:

    steps:
      - id: create-incident
        name: Create ServiceNow Incident
        action: servicenow:now:table:createRecord
        input:
          tableName: incident
          requestBody:
            short_description: "Printer is offline"
            description: "The office printer is not accessible via the network"
            severity: "3"
  4. Optional: To perform other operations, use the appropriate action ID and parameters:

    GoalAction IDKey Input Parameters

    Delete a record

    servicenow:now:table:deleteRecord

    tableName, sysId

    Modify a record

    servicenow:now:table:modifyRecord

    tableName, sysId, requestBody

    Retrieve a record

    servicenow:now:table:retrieveRecord

    tableName, sysId

    Update a record

    servicenow:now:table:updateRecord

    tableName, sysId, requestBody

    Tip

    To view the full schema and all available ServiceNow actions for your specific installation, navigate to Create > Installed Actions in the Red Hat Developer Hub interface.

10.1.7. ServiceNow configuration parameters

The ServiceNow integration requires specific parameters in your configuration files to establish a connection between Red Hat Developer Hub and your ServiceNow instances. Use these parameters to define authentication methods, instance URLs, and UI layouts.

10.1.7.1. ServiceNow backend and frontend configuration

Define the following parameters in the app-config.yaml file or the dynamic-plugins.yaml section of the Red Hat Developer Hub ConfigMap to enable the backend and frontend plugins.

ParameterDescriptionRequirement

instanceUrl

The base URL of your ServiceNow instance. For example, https://dev12345.service-now.com.

Required

basicAuth.username

The service account username for Basic authentication.

Optional

basicAuth.password

The service account password for Basic authentication.

Optional

oauth.grantType

The OAuth 2.0 grant type. Supports client_credentials or password.

Optional

oauth.clientId

The client ID for OAuth authentication.

Optional

oauth.clientSecret

The client secret for OAuth authentication.

Optional

10.1.7.2. ServiceNow scaffolder configuration

The ServiceNow Scaffolder module requires a separate configuration block. Note that this module uses baseUrl instead of instanceUrl.

ParameterDescriptionRequirement

baseUrl

The base URL of your ServiceNow instance.

Required

username

The service account username.

Required for Basic authentication

password

The service account password.

Required for Basic authentication

10.1.7.3. Authentication examples

The following examples demonstrate how to structure different authentication methods in your configuration.

10.1.7.4. Basic authentication example

servicenow:
  baseUrl: ${SERVICENOW_PROD_URL}
  username: ${SERVICENOW_USER}
  password: ${SERVICENOW_PASS}

10.1.7.5. OAuth with Client Credentials

servicenow:
  instanceUrl: ${SERVICENOW_INSTANCE_URL}
  oauth:
    grantType: client_credentials
    clientId: ${SERVICENOW_CLIENT_ID}
    clientSecret: ${SERVICENOW_CLIENT_SECRET}

10.1.7.6. OAuth with Password Grant

servicenow:
  instanceUrl: ${SERVICENOW_INSTANCE_URL}
  oauth:
    grantType: password
    clientId: ${SERVICENOW_CLIENT_ID}
    clientSecret: ${SERVICENOW_CLIENT_SECRET}
    username: ${SERVICENOW_USER}
    password: ${SERVICENOW_PASS}

10.1.7.7. Frontend UI configuration

The frontend plugin configuration defines how ServiceNow data appears on component entity pages.

dynamicPlugins:
  frontend:
    backstage-community.plugin-servicenow:
      entityTabs:
        - path: /servicenow
          title: ServiceNow
          mountPoint: entity.page.servicenow
      mountPoints:
        - mountPoint: entity.page.servicenow/cards
          importName: ServicenowPage
          config:
            layout:
              gridColumn: 1 / -1
              height: 75vh

10.2. Enable ServiceNow custom actions plugin in Red Hat Developer Hub

To use ServiceNow custom actions, you must first activate the plugin.

Prerequisites

  • Red Hat Developer Hub is installed and running.
  • You have created a project in the Developer Hub.

Procedure

  1. Add a package with plugin name and update the disabled field in your dynamic-plugins.yaml file as follows:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-scaffolder-backend-module-servicenow:<tag>
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

    Note

    The default configuration for a plugin is extracted from the dynamic-plugins.default.yaml file, however, you can use a pluginConfig entry to override the default configuration.

  2. Set the following variables in your app-config.yaml file to access the custom actions:

    servicenow:
      # The base url of the ServiceNow instance.
      baseUrl: ${SERVICENOW_BASE_URL}
      # The username to use for authentication.
      username: ${SERVICENOW_USERNAME}
      # The password to use for authentication.
      password: ${SERVICENOW_PASSWORD}

10.3. Supported ServiceNow custom actions in Red Hat Developer Hub

The ServiceNow custom actions enable you to manage records in the Red Hat Developer Hub.

The custom actions support the following HTTP methods for API requests:

  • GET: Retrieves specified information from a specified resource endpoint
  • POST: Creates or updates a resource
  • PUT: Modify a resource
  • PATCH: Updates a resource
  • DELETE: Deletes a resource

    [GET] servicenow:now:table:retrieveRecord

    Retrieves information of a specified record from a table in the Developer Hub.

    The following table describes the input parameters:

    NameTypeRequirementDescription

    tableName

    string

    Required

    Name of the table to retrieve the record from

    sysId

    string

    Required

    Unique identifier of the record to retrieve

    sysparmDisplayValue

    enum("true", "false", "all")

    Optional

    Returns field display values such as true, actual values as false, or both. The default value is false.

    sysparmExcludeReferenceLink

    boolean

    Optional

    Set as true to exclude Table API links for reference fields. The default value is false.

    sysparmFields

    string[]

    Optional

    Array of fields to return in the response

    sysparmView

    string

    Optional

    Renders the response according to the specified UI view. You can override this parameter using sysparm_fields.

    sysparmQueryNoDomain

    boolean

    Optional

    Set as true to access data across domains if authorized. The default value is false.

    The following table describes the output parameters:

    NameTypeDescription

    result

    Record<PropertyKey, unknown>

    The response body of the request

    [GET] servicenow:now:table:retrieveRecords

    Retrieves information about multiple records from a table in the Developer Hub.

    The following table describes the input parameters:

    NameTypeRequirementDescription

    tableName

    string

    Required

    Name of the table to retrieve the records from

    sysparamQuery

    string

    Optional

    Encoded query string used to filter the results

    sysparmDisplayValue

    enum("true", "false", "all")

    Optional

    Returns field display values such as true, actual values as false, or both. The default value is false.

    sysparmExcludeReferenceLink

    boolean

    Optional

    Set as true to exclude Table API links for reference fields. The default value is false.

    sysparmSuppressPaginationHeader

    boolean

    Optional

    Set as true to suppress pagination header. The default value is false.

    sysparmFields

    string[]

    Optional

    Array of fields to return in the response

    sysparmLimit

    int

    Optional

    Maximum number of results returned per page. The default value is 10,000.

    sysparmView

    string

    Optional

    Renders the response according to the specified UI view. You can override this parameter using sysparm_fields.

    sysparmQueryCategory

    string

    Optional

    Name of the query category to use for queries

    sysparmQueryNoDomain

    boolean

    Optional

    Set as true to access data across domains if authorized. The default value is false.

    sysparmNoCount

    boolean

    Optional

    Does not run a select count(*) on the table. The default value is false.

    The following table describes the output parameters:

    NameTypeDescription

    result

    Record<PropertyKey, unknown>

    The response body of the request

    [POST] servicenow:now:table:createRecord

    Creates a record in a table in the Developer Hub.

    The following table describes the input parameters:

    NameTypeRequirementDescription

    tableName

    string

    Required

    Name of the table to save the record in

    requestBody

    Record<PropertyKey, unknown>

    Optional

    Field name and associated value for each parameter to define in the specified record

    sysparmDisplayValue

    enum("true", "false", "all")

    Optional

    Returns field display values such as true, actual values as false, or both. The default value is false.

    sysparmExcludeReferenceLink

    boolean

    Optional

    Set as true to exclude Table API links for reference fields. The default value is false.

    sysparmFields

    string[]

    Optional

    Array of fields to return in the response

    sysparmInputDisplayValue

    boolean

    Optional

    Set field values using their display value such as true or actual value as false. The default value is false.

    sysparmSuppressAutoSysField

    boolean

    Optional

    Set as true to suppress auto-generation of system fields. The default value is false.

    sysparmView

    string

    Optional

    Renders the response according to the specified UI view. You can override this parameter using sysparm_fields.

    The following table describes the output parameters:

    NameTypeDescription

    result

    Record<PropertyKey, unknown>

    The response body of the request

    [PUT] servicenow:now:table:modifyRecord

    Modifies a record in a table in the Developer Hub.

    The following table describes the input parameters:

    NameTypeRequirementDescription

    tableName

    string

    Required

    Name of the table to change the record from

    sysId

    string

    Required

    Unique identifier of the record to change

    requestBody

    Record<PropertyKey, unknown>

    Optional

    Field name and associated value for each parameter to define in the specified record

    sysparmDisplayValue

    enum("true", "false", "all")

    Optional

    Returns field display values such as true, actual values as false, or both. The default value is false.

    sysparmExcludeReferenceLink

    boolean

    Optional

    Set as true to exclude Table API links for reference fields. The default value is false.

    sysparmFields

    string[]

    Optional

    Array of fields to return in the response

    sysparmInputDisplayValue

    boolean

    Optional

    Set field values using their display value such as true or actual value as false. The default value is false.

    sysparmSuppressAutoSysField

    boolean

    Optional

    Set as true to suppress auto-generation of system fields. The default value is false.

    sysparmView

    string

    Optional

    Renders the response according to the specified UI view. You can override this parameter using sysparm_fields.

    sysparmQueryNoDomain

    boolean

    Optional

    Set as true to access data across domains if authorized. The default value is false.

    The following table describes the output parameters:

    NameTypeDescription

    result

    Record<PropertyKey, unknown>

    The response body of the request

    [PATCH] servicenow:now:table:updateRecord

    Updates a record in a table in the Developer Hub.

    The following table describes the input parameters:

    NameTypeRequirementDescription

    tableName

    string

    Required

    Name of the table to update the record in

    sysId

    string

    Required

    Unique identifier of the record to update

    requestBody

    Record<PropertyKey, unknown>

    Optional

    Field name and associated value for each parameter to define in the specified record

    sysparmDisplayValue

    enum("true", "false", "all")

    Optional

    Returns field display values such as true, actual values as false, or both. The default value is false.

    sysparmExcludeReferenceLink

    boolean

    Optional

    Set as true to exclude Table API links for reference fields. The default value is false.

    sysparmFields

    string[]

    Optional

    Array of fields to return in the response

    sysparmInputDisplayValue

    boolean

    Optional

    Set field values using their display value such as true or actual value as false. The default value is false.

    sysparmSuppressAutoSysField

    boolean

    Optional

    Set as true to suppress auto-generation of system fields. The default value is false.

    sysparmView

    string

    Optional

    Renders the response according to the specified UI view. You can override this parameter using sysparm_fields.

    sysparmQueryNoDomain

    boolean

    Optional

    Set as true to access data across domains if authorized. The default value is false.

    The following table describes the output parameters:

    NameTypeDescription

    result

    Record<PropertyKey, unknown>

    The response body of the request

    [DELETE] servicenow:now:table:deleteRecord

    Deletes a record from a table in the Developer Hub.

    The following table describes the input parameters:

    NameTypeRequirementDescription

    tableName

    string

    Required

    Name of the table to delete the record from

    sysId

    string

    Required

    Unique identifier of the record to delete

    sysparmQueryNoDomain

    boolean

    Optional

    Set as true to access data across domains if authorized. The default value is false.

Chapter 11. Kubernetes custom actions in Red Hat Developer Hub

You can create and manage Kubernetes resources by using custom scaffolder actions in Red Hat Developer Hub templates. The Kubernetes custom actions plugin is preinstalled in a disabled state.

11.1. Enable Kubernetes custom actions plugin in Red Hat Developer Hub

Enable the preinstalled Kubernetes custom actions plugin by updating the dynamic plugins configuration.

In Red Hat Developer Hub, the Kubernetes custom actions are provided as a preinstalled plugin, which is disabled by default. You can enable the Kubernetes custom actions plugin by updating the disabled key value in your dynamic-plugins.yaml file.

Procedure

  • Add a package with the Kubernetes custom action plugin name and update the disabled field in your dynamic-plugins.yaml file to enable the plugin. For example:

    plugins:
      - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-scaffolder-backend-module-kubernetes:<tag>
        disabled: false

    where:

    <tag>

    Enter your RHDH version of Backstage and the plugin version, in the format bs_<backstage-version>__<plugin-version> (note the double underscore delimiter). To find these versions, complete the following steps:

    1. Find your Backstage version in the RHDH release notes preface.
    2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.9 based on Backstage 1.45.3, use the format bs_1.45.3__<plugin-version>.

      Tip

      To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

    Note

    The default configuration for a plugin is extracted from the dynamic-plugins.default.yaml file, however, you can use a pluginConfig entry to override the default configuration.

11.2. Use Kubernetes custom actions plugin in Red Hat Developer Hub

Add Kubernetes actions to your custom templates to create namespaces and manage cluster resources.

In Red Hat Developer Hub, the Kubernetes custom actions enable you to run template actions for Kubernetes.

Procedure

  • To use a Kubernetes custom action in your custom template, add the following Kubernetes actions to your template:

    action: kubernetes:create-namespace
    id: create-kubernetes-namespace
    name: Create kubernetes namespace
    input:
      namespace: my-rhdh-project
      clusterRef: bar
      token: TOKEN
      skipTLSVerify: false
      caData: Zm9v
      labels: app.io/type=ns; app.io/managed-by=org;

Additional resources

11.3. Create a template using Kubernetes custom actions in Red Hat Developer Hub

Define a Template object with Kubernetes actions to automate namespace creation and resource management.

Procedure

  • To create a template, define a Template object as a YAML file.

    The Template object describes the template and its metadata. It also contains required input variables and a list of actions that are executed by the scaffolding service.

    apiVersion: scaffolder.backstage.io/v1beta3
    kind: Template
    metadata:
      name: create-kubernetes-namespace
      title: Create a kubernetes namespace
      description: Create a kubernetes namespace
    spec:
      type: service
      parameters:
        - title: Information
          required: [namespace, token]
          properties:
            namespace:
              title: Namespace name
              type: string
              description: Name of the namespace to be created
            clusterRef:
              title: Cluster reference
              type: string
              description: Cluster resource entity reference from the catalog
              ui:field: EntityPicker
              ui:options:
                catalogFilter:
                  kind: Resource
            url:
              title: Url
              type: string
              description: Url of the kubernetes API, will be used if clusterRef is not provided
            token:
              title: Token
              type: string
              ui:field: Secret
              description: Bearer token to authenticate with
            skipTLSVerify:
              title: Skip TLS verification
              type: boolean
              description: Skip TLS certificate verification, not recommended to use in production environment, default to false
            caData:
              title: CA data
              type: string
              ui:field: Secret
              description: Certificate Authority base64 encoded certificate
            labels:
              title: Labels
              type: string
              description: Labels to be applied to the namespace
              ui:widget: textarea
              ui:options:
                rows: 3
              ui:help: 'Hint: Separate multiple labels with a semicolon!'
              ui:placeholder: 'kubernetes.io/type=namespace; app.io/managed-by=org'
      steps:
        - id: create-kubernetes-namespace
          name: Create kubernetes namespace
          action: kubernetes:create-namespace
          input:
            namespace: ${ parameters.namespace }
            clusterRef: ${ parameters.clusterRef }
            url: ${ parameters.url }
            token: ${ secrets.token }
            skipTLSVerify: ${ parameters.skipTLSVerify }
            caData: ${ secrets.caData }
            labels: ${ parameters.labels }

11.4. Supported Kubernetes custom actions in Red Hat Developer Hub

Access parameter specifications and requirements for the kubernetes:create-namespace scaffolder action.

In Red Hat Developer Hub, you can use custom Kubernetes actions in Scaffolder templates.

Action: kubernetes:create-namespace
Creates a namespace for the Kubernetes cluster in the Developer Hub.
Parameter nameTypeRequirementDescriptionExample

namespace

string

Required

Name of the Kubernetes namespace

my-rhdh-project

clusterRef

string

Required only if url is not defined. You cannot specify both url and clusterRef.

Cluster resource entity reference from the catalog

bar

url

string

Required only if clusterRef is not defined. You cannot specify both url and clusterRef.

API url of the Kubernetes cluster

https://api.example.com:6443

token

String

Required

Kubernetes API bearer token used for authentication

 

skipTLSVerify

boolean

Optional

If true, certificate verification is skipped

false

caData

string

Optional

Base64 encoded certificate data

 

label

string

Optional

Labels applied to the namespace

app.io/type=ns; app.io/managed-by=org;

Chapter 12. Configure Red Hat Developer Hub events module

You can enable real-time updates for GitHub entities by configuring the Events Module with webhooks together with scheduled updates.

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.

12.1. Configure the GitHub Events Module plugin

Configure GitHub webhooks to trigger real-time updates for GitHub Discovery and organizational data.

Learn how to configure Events Module for use with the RHDH GitHub Discovery feature and GitHub organization data.

Prerequisites

  • You have added your GitHub integration credentials in the app-config.yaml file.
  • You have defined the schedule.frequency in the app-config.yaml file as longer time period, such as 24 hours.
  • For GitHub Discovery only: You have enabled GitHub Discovery.
  • For GitHub Organizational Data only: You have enabled Github Authentication with user ingestion.

Procedure

  1. Add the GitHub Events Module to your dynamic-plugins.yaml configuration file as follows:

    data:
    dynamic-plugins.yaml: |
    includes:
    - dynamic-plugins.default.yaml
    plugins:
    - package: oci://registry.access.redhat.com/rhdh/backstage-plugin-events-backend-module-github:<tag>
    disabled: false

    where:

    <tag>
    Enter your RHDH version and the plugin version, in the format <rhdh-version>--<plugin-version>. To find these versions, complete the following steps:
  2. Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.10, use the format 1.10--<plugin-version>.

    Tip

    To ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.

  3. To create HTTP endpoints to receive events for the github, add the following to your app-config.yaml file:

    events:
      http:
       topics:
        - github
      modules:
        github:
          webhookSecret: ${GITHUB_WEBHOOK_SECRET}
    Important

    Secure your workflow by adding a webhook secret token to validate webhook deliveries.

  4. Create a GitHub webhook with the following specifications:

    • For GitHub Discovery Events: push, repository
    • For GitHub Organizational Data Events: organization, team and membership
    • Content Type: application/json
    • Payload URL: https://<my_developer_hub_domain>/api/events/http/github

      Note

      Payload URL is the URL exposed after configuring the HTTP endpoint.

Verification

  • Check the log for an entry that confirms that http endpoint was set up successfully to receive events from the GitHub webhook.

    Example of a log of successfully set up http endpoint
    {"level":"\u001b[32minfo\u001b[39m","message":"Registered /api/events/http/github to receive events","plugin":"events","service":"backstage","timestamp":"2025-11-03 02:19:12"}
  • For GitHub Discovery only:

    • Trigger a GitHub push event by adding, modifying or deleting the catalog-info.yaml file in the repository where you set up your webhook. A record of this event should appear in the pod logs of your RHDH instance.

      Example of a log with changes to catalog-info.yaml file
      {"level":"\u001b[32minfo\u001b[39m","message":"Processed Github push event: added 0 - removed 0 - modified 1","plugin":"catalog","service":"backstage","span_id":"47534b96c4afc654","target":"github-provider:providerId","timestamp":"2025-06-15 21:33:14","trace_flags":"01","trace_id":"ecc782deb86aed2027da0ae6b1999e5c"}
  • For GitHub Organizational Data only:

    • Newly added users and teams appear in the RHDH catalog.

Chapter 13. Override Core Backend Service Configuration

Customize core backend services by installing them as BackendFeatures using dynamic plugin functionality.

The Red Hat Developer Hub (RHDH) backend platform consists of several core services that are well encapsulated. The RHDH backend installs these default core services statically during initialization.

Customize a core service by installing it as a BackendFeature by using the dynamic plugin functionality.

Procedure

  1. Configure Developer Hub to allow a core service override, by setting the corresponding core service ID environment variable to true in the Developer Hub app-config.yaml configuration file.

    The following table describes the environment variables and their corresponding core service IDs:

    VariableOverrides the related service

    ENABLE_CORE_AUTH_OVERRIDE

    core.auth

    ENABLE_CORE_CACHE_OVERRIDE

    core.cache

    ENABLE_CORE_ROOTCONFIG_OVERRIDE

    core.rootConfig

    ENABLE_CORE_DATABASE_OVERRIDE

    core.database

    ENABLE_CORE_DISCOVERY_OVERRIDE

    core.discovery

    ENABLE_CORE_HTTPAUTH_OVERRIDE

    core.httpAuth

    ENABLE_CORE_HTTPROUTER_OVERRIDE

    core.httpRouter

    ENABLE_CORE_LIFECYCLE_OVERRIDE

    core.lifecycle

    ENABLE_CORE_LOGGER_OVERRIDE

    core.logger

    ENABLE_CORE_PERMISSIONS_OVERRIDE

    core.permissions

    ENABLE_CORE_ROOTHEALTH_OVERRIDE

    core.rootHealth

    ENABLE_CORE_ROOTHTTPROUTER_OVERRIDE

    core.rootHttpRouter

    ENABLE_CORE_ROOTLIFECYCLE_OVERRIDE

    core.rootLifecycle

    ENABLE_CORE_SCHEDULER_OVERRIDE

    core.scheduler

    ENABLE_CORE_USERINFO_OVERRIDE

    core.userInfo

    ENABLE_CORE_URLREADER_OVERRIDE

    core.urlReader

    ENABLE_EVENTS_SERVICE_OVERRIDE

    events.service

  2. Install your custom core service as a BackendFeature as shown in the following example:

    // Create the BackendFeature
    $ export const customRootHttpServerFactory: BackendFeature =
      rootHttpRouterServiceFactory({
        configure: ({ app, routes, middleware, logger }) => {
          logger.info(
            'Using custom root HttpRouterServiceFactory configure function',
          );
          app.use(middleware.helmet());
          app.use(middleware.cors());
          app.use(middleware.compression());
          app.use(middleware.logging());
          // Add a the custom middleware function before all
          // of the route handlers
          app.use(addTestHeaderMiddleware({ logger }));
          app.use(routes);
          app.use(middleware.notFound());
          app.use(middleware.error());
        },
      });
    
    // Export the BackendFeature as the default entrypoint
    $ export default customRootHttpServerFactory;

    In the previous example, as the BackendFeature overrides the default implementation of the HTTP router service, you must set the ENABLE_CORE_ROOTHTTPROUTER_OVERRIDE environment variable to true so that the Developer Hub does not install the default implementation automatically.

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.