Red Hat Developer Hub 1.10

Red Hat Developer Hub documentation

Complete documentation for Red Hat Developer Hub.

Red Hat Customer Content Services

Abstract

The complete Red Hat Developer Hub documentation, organized by category.

Preface

The complete Red Hat Developer Hub documentation, organized by category.

Chapter 1. Discover

1.1. Discover

TODO: Replace this placeholder with an overview of Discover.

1.2. Evaluate RHDH capabilities

1.2.1. Evaluate RHDH capabilities

TODO: Replace this placeholder with an overview of Evaluate RHDH capabilities.

1.2.2. Developer Lightspeed AI virtual assistant capabilities

1.2.2.1. Developer Lightspeed AI virtual assistant capabilities

TODO: Replace this placeholder with an overview of Developer Lightspeed AI virtual assistant capabilities.

1.2.3. Platform integrations for toolchain connectivity

1.2.3.1. Platform integrations for toolchain connectivity

TODO: Replace this placeholder with an overview of Platform integrations for toolchain connectivity.

Chapter 2. Get started

2.1. Get started

TODO: Replace this placeholder with an overview of Get started.

2.2. Set up the first RHDH instance

2.2.1. Set up the first RHDH instance

TODO: Replace this placeholder with an overview of Set up the first RHDH instance.

2.2.2. Enable initial authentication to verify user access

2.2.2.1. Enable initial authentication to verify user access

TODO: Replace this placeholder with an overview of Enable initial authentication to verify user access.

Chapter 3. Plan

3.1. Plan

TODO: Replace this placeholder with an overview of Plan.

3.2. Plan your deployment architecture and scale

3.2.1. Plan your deployment architecture and scale

TODO: Replace this placeholder with an overview of Plan your deployment architecture and scale.

3.2.2. Sizing requirements for cluster resource provisioning

3.2.2.1. Sizing requirements for cluster resource provisioning

TODO: Replace this placeholder with an overview of Sizing requirements for cluster resource provisioning.

3.2.3. Scale your deployment using enterprise performance benchmarks

3.2.3.1. Scale your deployment using enterprise performance benchmarks

TODO: Replace this placeholder with an overview of Scale your deployment using enterprise performance benchmarks.

Chapter 4. Install

4.1. Install

TODO: Replace this placeholder with an overview of Install.

4.2. Install on OpenShift Container Platform to leverage existing Red Hat infrastructure

4.2.1. Install on OpenShift Container Platform to leverage existing Red Hat infrastructure

TODO: Replace this placeholder with an overview of Install on OpenShift Container Platform to leverage existing Red Hat infrastructure.

4.3. Install on managed hyperscaler environments to integrate with cloud resources

4.3.1. Install on managed hyperscaler environments to integrate with cloud resources

TODO: Replace this placeholder with an overview of Install on managed hyperscaler environments to integrate with cloud resources.

4.4. Install in an air-gapped environment

4.4.1. Install in an air-gapped environment

TODO: Replace this placeholder with an overview of Install in an air-gapped environment.

Chapter 5. Upgrade

5.1. Upgrade

TODO: Replace this placeholder with an overview of Upgrade.

5.2. Upgrade RHDH to apply the latest features and security patches

5.2.1. Upgrade RHDH to apply the latest features and security patches

TODO: Replace this placeholder with an overview of Upgrade RHDH to apply the latest features and security patches.

Chapter 6. Migrate

6.1. Migrate

TODO: Replace this placeholder with an overview of Migrate.

6.2. Migrate from a local database to an external PostgreSQL server

6.2.1. Migrate from a local database to an external PostgreSQL server

TODO: Replace this placeholder with an overview of Migrate from a local database to an external PostgreSQL server.

Chapter 7. Administer

7.1. Administer

TODO: Replace this placeholder with an overview of Administer.

7.2. Evaluate component compliance using Scorecards

7.2.1. Evaluate component compliance using Scorecards

TODO: Replace this placeholder with an overview of Evaluate component compliance using Scorecards.

7.2.2. Set up Scorecards

7.2.2.1. Set up Scorecards

TODO: Replace this placeholder with an overview of Set up Scorecards.

7.2.3. Install and configure Scorecards

7.2.3.1. Install and configure Scorecards

TODO: Replace this placeholder with an overview of Install and configure Scorecards.

7.2.4. Manage metric thresholds

7.2.4.1. Manage metric thresholds

TODO: Replace this placeholder with an overview of Manage metric thresholds.

7.3. Monitor portfolio health using aggregated Scorecard KPIs

7.3.1. Monitor portfolio health using aggregated Scorecard KPIs

TODO: Replace this placeholder with an overview of Monitor portfolio health using aggregated Scorecard KPIs.

7.3.2. Monitor collective health

7.3.2.1. Monitor collective health

TODO: Replace this placeholder with an overview of Monitor collective health.

7.3.3. Configure aggregated Scorecard KPIs

7.3.3.1. Configure aggregated Scorecard KPIs

TODO: Replace this placeholder with an overview of Configure aggregated Scorecard KPIs.

7.3.4. Identify services impacting team compliance KPIs

7.3.4.1. Identify services impacting team compliance KPIs

TODO: Replace this placeholder with an overview of Identify services impacting team compliance KPIs.

Chapter 8. Develop

8.1. Develop

TODO: Replace this placeholder with an overview of Develop.

8.2. Register and update software components to maintain a unified service inventory

8.2.1. Register and update software components to maintain a unified service inventory

TODO: Replace this placeholder with an overview of Register and update software components to maintain a unified service inventory.

8.2.2. Manage your software components

8.2.2.1. Manage your software components

TODO: Replace this placeholder with an overview of Manage your software components.

8.3. Project standardization with software templates

8.3.1. Project standardization with software templates

TODO: Replace this placeholder with an overview of Project standardization with software templates.

8.3.2. Create a basic software template

To automate the setup of standardized environments for your developers, you must create a template definition. This definition allows RHDH to automate the repetitive tasks of repository creation and initial configuration.

Prerequisites

Procedure

  1. Create a directory in your Git repository for the Software Template.
  2. Create a file named template.yaml in that directory.
  3. In the template.yaml file, define the apiVersion, kind, and metadata to identify the starter kit in the software catalog.
  4. Add a spec section to define the parameters that a developer must provide when they use the Software Template.
  5. Define the steps required to generate the project, which can include fetch:template to retrieve the skeleton and publish:github to create the new repository.

    Important

    You must include TechDocs in your Software Templates to ensure that documentation is automatically generated for every new project created from the Software Template.

Verification

  1. Inspect the template.yaml file to ensure the YAML syntax is valid.
  2. Confirm that the name and action fields are defined so the template is correctly recognized as a Scaffolder task.
  3. Check that the defined parameters match the variables used in your Software Template skeleton files.
  4. Navigate to the form playground at <instance_url>/create/template-form and test the Software Template configuration to confirm the fields and logic render as intended.

8.3.3. Default environment parameters and secrets

The scaffolder supports a defaultEnvironment configuration that provides default parameters and secrets to all templates. Use this configuration in your app-config.yaml file to reduce template complexity and improve security by centralizing common values.

Example of an app-config.yaml configured for default parameters and secrets
scaffolder:
  defaultEnvironment:
    parameters:
      githubOrg: my-org
      defaultOwner: platform-team
    secrets:
      GITHUB_TOKEN: ${GITHUB_TOKEN}
Note

Default parameters are isolated in their own context to avoid naming conflicts.

Default parameters are accessible via ${{ environment.parameters.* }} in templates.

Example of default parameters configuration for application deployment
spec:
  parameters:
    - title: Project details
      required:
        - name
      properties:
        name:
          title: Name
          type: string
          description: Unique name for the new repository.

  steps:
    - id: fetch-base
      name: Fetch skeleton
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }} # Resolves to frontend input value
          owner: ${{ environment.parameters.defaultOwner }} # Resolves to defaultEnvironment.parameters.defaultOwner

Default secrets are resolved from environment variables and accessible via ${{ environment.secrets.* }} in template actions.

Example of a default secret configuration
spec:
  parameters:
    - title: Project details
      required:
        - name
      properties:
        name:
          title: Name
          type: string
          description: Unique name for the new repository.

  steps:
    - id: publish
      name: Publish to GitHub
      action: publish:github
      input:
        allowedHosts: ['github.com']
        description: ${{ parameters.name }}
        repoUrl: github.com?owner=${{ environment.parameters.githubOrg }}&repo=${{ parameters.name }}
        token: ${{ environment.secrets.GITHUB_TOKEN }} # Resolves to defaultEnvironment.secrets.GITHUB_TOKEN
Important

Secrets are automatically masked in logs. They are only available to backend actions, never exposed to the frontend.

8.3.4. Share software templates with your organization

To allow developers to create new projects independently using your standards, you must publish the Software Template definition to the RHDH catalog. This registration makes the template a selectable option in the software creator interface.

Prerequisites

  • If RBAC is enabled, you have a role with the following permissions: catalog.entity.create, catalog.location.create.
  • You have a Git repository to store Software Template files.

Procedure

  1. Navigate to the Create page in the RHDH interface.
  2. Select Register Component.
  3. Enter the full URL to your template.yaml file in the Repository URL field.
  4. Click Analyze and then Import.

Verification

  1. Navigate to the Create page.
  2. Confirm that your new template is displayed in the list of available options.

8.3.5. Extending software templates for complex project requirements

Use advanced logic to create Software Templates that adapt to specific project requirements and user inputs. Advanced templating includes parameterization, conditional logic, and fetch-and-run capabilities.

FeatureDescription

Parameterization

Use variables to inject user-provided data into project files.

Conditional Logic

Perform specific automation steps only when certain conditions are met.

Fetch and Run

Retrieve remote files and run commands during the setup process.

8.3.6. Version Software Templates to track template updates and dependencies

8.3.6.1. Version Software Templates to track template updates and dependencies

Software Templates in Red Hat Developer Hub provide a streamlined way to create software components and publish them to different version control repositories such as Git. Platform engineers create and maintain Software Templates in Red Hat Developer Hub.

8.3.6.2. Version a Software Template in Red Hat Developer Hub

Version Software Templates by using the catalog:scaffolded-from and catalog:template:version custom actions to track template versions and the entities created from them.

Prerequisites

  • You have added a custom Developer Hub application configuration.
  • The following dynamic plugins are enabled in your Backstage or my-rhdh-app-config file:

    • backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic
    • backstage-plugin-notifications
    • backstage-plugin-notifications-backend-dynamic

Procedure

  1. Make sure the required plugins are enabled in your RHDH my-rhdh-app-config file or the Backstage custom resource (CR):

    global:
      dynamic:
        plugins:
          - package: ./dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic
            disabled: false
          - package: ./dynamic-plugins/dist/backstage-plugin-notifications
            disabled: false
          - package: ./dynamic-plugins/dist/backstage-plugin-notifications-backend-dynamic
            disabled: false
  2. Modify the Software Template that you want to update.
  3. Complete one or both of the following tasks:
  4. Include the annotation in your template: Add the backstage.io/template-version annotation in your template metadata. When this annotation is present, it is automatically used to annotate your catalog entity and display a default version value.
  5. Pass the annotation as input to the action: This method takes precedence over the annotation in the template itself and allows the user running the template to specify the version.

    # ...
    - id: version-templateRef
      name: Append the version of this template to the entityRef
      action: catalog:template:version
      input:
        annotations:
          backstage.io/template-version: ${{ parameters.version }}
    # ...

Verification

  1. Create a catalog component using the updated Software Template. This step creates a new component in Backstage and optionally, pushes files to an external repository (for example, GitHub, GitLab).
  2. Check the component in the Catalog UI.

    1. On the Catalog page, locate the newly created catalog component.
    2. Verify that the backstage.io/template-version annotation is present in the entity. You can use INSPECT ENTITY and select YAML Raw or JSON Raw view to find the annotation in the component definition.
  3. Only if you have published the catalog component: Check the component file in the repository.

    1. If VIEW SOURCE is present in your UI: Click VIEW SOURCE to open the stored component file in the repository.
    2. Locate the file manually and verify that the backstage.io/template-version annotation is present.

8.3.6.3. Enable Software Template version update notifications in Red Hat Developer Hub

Enable notification alerts for template version updates so that component owners are automatically notified when the Software Template used to generate their components is updated to a new version.

Prerequisites

  • You have installed and configured the RHDH notification plugins:

    • backend: @backstage/plugin-notifications-backend
    • front-end: @backstage/plugin-notifications

Procedure

  1. Open your RHDH app-config.yaml file.
  2. Add the following configuration to the scaffolder section to enable Software Template update notifications
  3. Optional: To customize the notification title and description, add the message block:

    scaffolder:
      notifications:
        templateUpdate:
          enabled: true
          message:
            title: 'Custom title for $ENTITY_DISPLAY_NAME'
            description: 'Custom description'

    where:

    enabled
    Set to true to enable the notification. Default value is false.
    message:title
    Enter the notification title.
    message:description

    Enter the notification description.

    Note

    The message:title and message:description fields support the $ENTITY_DISPLAY_NAME variable. The system replaces this variable with the title (or the name, if the title is missing) of the scaffolded entity.

Verification

  1. Log in to your Red Hat Developer Hub instance.
  2. In the left navigation menu, verify that the Notifications item is displayed.
  3. Update the version of a Software Template and verify that the owner of a component scaffolded from that template receives a notification.

8.3.7. Track component provenance to map dependencies back to source templates

8.3.7.1. Track component provenance to map dependencies back to source templates

Track the dependency link between a generated entity and its source template to simplify lifecycle management.

Platform engineers use custom actions within the Software Template scaffolding process to establish and track the dependency link between a generated entity (Component or Resource) and its source template. This relationship is called scaffolding provenance.

Platform administrators use custom actions such as catalog:scaffolded-from and catalog:template:version in the Scaffolder backend module to track the template version and the corresponding entity version, which simplifies lifecycle management.

8.3.7.2. Configure provenance and Software Template versioning Red Hat Developer Hub

Modify the Software Template YAML definition to add provenance information during the scaffolding process.

As a platform engineer, you must modify the Software Template YAML definition to ensure the required provenance information is added during the scaffolding process.

Procedure

  1. Locate the Software Template object YAML file where you want to add the provenance information and add a step that uses the catalog:scaffolded-from action. This action links the resulting catalog entity back to the source template.
  2. Optional: To track the template version (for example, v1.0 versus v1.5), include the catalog:template:version action in the steps section. The following code block is an example to adding versioning action to the steps section:

    steps:
      - id: create-provenance-annotation
        name: Append the entityRef of this template to the entityRef
        action: catalog:scaffolded-from
      - id: create-version-annotation
        name: Create Template Version Annotation
        action: catalog:template:version
        input:
          templateVersion: ${{ parameters.version }}
      - ... other steps ...

    where:

    steps:input:templateVersion

    Reads the version parameter

    Note

    The catalog:template:version action reads a version parameter defined in the template and applies it as an annotation to the resulting catalog entity.

  3. In your Red Hat Developer Hub app-config.yaml file, configure the catalog.locations section to point to the Software Template that you want to add. You might need to add Template to the global catalog.rules.allow list or add a granular rule to the location to allow for Software Templates ingestion, as shown in the following example:

    # ...
    catalog:
      locations:
        - type: url
          target: https://<repository_url>/example-template.yaml
          rules:
            - allow: [Template]
    # ...

    where:

    catalog.locations.type
    Enter the url type if you are importing templates from a repository, such as GitHub or GitLab.
    catalog.locations.target
    Enter the URL for the template.
    catalog.locations.rules.allow
    Enter the Template rule to allow new Software Templates to be added to the catalog.

Verification

After creating a component with the updated template, verify the provenance annotations in the resulting Catalog Entity YAML.

  1. In the Red Hat Developer Hub navigation menu, go to Catalog and locate the newly created catalog component.
  2. To view the underlying data that links the entity to the template, select the INSPECT ENTITY option.
  3. To verify provenance annotations, complete the following steps:

    1. Select the YAML Raw or JSON Raw view and verify the presence of the data item for the scaffoldedFrom link.
    2. Optional: If versioning was included, verify the presence of the backstage.io/template-version annotation.

      Note

      If you publish the catalog component to an external repository (such as Git), the component file in that repository must also contain the backstage.io/template-version annotation.

8.3.7.3. View Software Template dependencies

View all entities created from a specific Software Template to identify the complete dependency and impact map.

As a developer, you can track which entities were created from a specific Software Template. When a platform engineer configures provenance on a template, you can quickly identify the complete dependency and impact map of that template by viewing all linked components and resources in the Catalog.

Procedure

  1. In the Red Hat Developer Hub navigation menu, click Catalog, use the filters to find and select the Software Template you want to inspect.
  2. In the Software Template detail page, click the Dependencies tab. This view lists all catalog entities such as components, resources, and systems that reference this template, including any version information if configured.

8.3.8. Automate template lifecycle management

8.3.8.1. Automate template lifecycle management

Automatically apply template updates to all downstream repositories to maintain compliance without manual file comparisons.

When Software Templates receive security updates or configuration changes, you can apply those updates to all downstream repositories automatically so that your applications remain compliant without manual file comparisons.

Automated template lifecycle management maintains consistency by monitoring your source templates. When a template version changes, the scaffolder-relation-processor plugin identifies all entities provisioned from that template and creates a pull request (PR) or merge request (MR) containing the necessary file updates, additions, or deletions.

8.3.8.2. Enable automated template updates

Configure the scaffolder-relation-processor plugin to synchronize Software Template changes to downstream repositories.

To automate the synchronization of changes from Software Templates to your repositories, you must configure the plugin in your backend settings and ensure that your entities contain the required metadata.

Prerequisites

  • You have added a custom Developer Hub application configuration.
  • You have configured GitHub or GitLab integrations in your RHDH app-config.yaml file.
  • Your scaffolded entities include the spec.scaffoldedFrom field referencing the source template.
  • Your entities include the backstage.io/managed-by-location annotation pointing to a valid GitHub or GitLab URL.

Procedure

  1. Enable the template sync and notification plugins in your RHDH dynamic-plugins.yaml file:

    plugins:
    # Enables the core template synchronization logic
      - package: './dynamic-plugins/dist/backstage-community-plugin-scaffolder-backend-module-scaffolder-relation-processor'
        disabled: false
    # Required only if you want to receive notifications for new pull requests
      - package: './dynamic-plugins/dist/backstage-plugin-notifications'
        disabled: false
  2. Open your RHDH app-config.yaml file.
  3. Configure the pull request (PR) feature by adding the following configuration:

    scaffolder:
      pullRequests:
        templateUpdate:
          enabled: true
  4. Optional: Enable notifications to alert entity owners when a PR is created:

    scaffolder:
      notifications:
        templateUpdate:
          enabled: true
  5. Restart the Red Hat Developer Hub instance to apply the changes.

Verification

  1. Update the version of a source template in its repository.
  2. Navigate to a repository scaffolded from that template.
  3. Confirm that a new pull request named [component-name]/template-upgrade-v[version] exists.

8.3.8.3. Template sync considerations and limitations

Review reviewer assignment, variable resolution limitations, and other details to troubleshoot the synchronization process.

Review the following details to troubleshoot or refine the synchronization process.

Reviewer assignment

The plugin automatically assigns a reviewer if the entity owner is a User entity with a defined VCS login.

  • GitHub: Requires the github.com/user-login annotation.
  • GitLab: Requires the gitlab.com/user-login annotation.

    If the owner is a Group, the plugin creates the PR without an assigned reviewer.

Variable resolution limitations

The synchronization engine uses regex matching to resolve template variables such as ${{ values.name }}. You must manually review PRs because:

  • Variables that do not match keys in the scaffolded repository remain in raw template syntax.
  • Conditional Jinja2 blocks ({% if %}) are stripped, which might cause unexpected formatting.
  • Complex nested structures might not resolve correctly.
Error handling

If a PR fails to create due to credential issues or network errors, the plugin:

  • Logs the error in the backend.
  • Sends a failure notification to the entity owner (if notifications are enabled).
  • Skips the sync if no file differences are detected between the template and the repository.

8.3.8.4. Template synchronization and notification outcomes

Review the behavior for each combination of pull request creation and notification settings.

You can enable pull requests and notifications independently. The following table describes the behavior for each configuration combination:

PR CreationNotificationsOutcome

Disabled

Disabled

No action occurs when a template updates.

Disabled

Enabled

The plugin sends a notification to the entity owner with a link to the catalog.

Enabled

Disabled

The plugin creates a PR but sends no notification.

Enabled

Enabled

The plugin creates a PR and sends a notification to the owner with a link to the PR.

Note

If PR creation fails, the plugin sends a notification containing error details instead of the custom message.

8.3.9. Standardized project generation with software templates

8.3.9.1. Standardized project generation with software templates

Use Software Templates in Red Hat Developer Hub to provide standardized project starter kits that improve developer productivity and ensure that new projects follow organizational standards.

8.3.9.2. Software Templates in Red Hat Developer Hub

You can use Software Templates in RHDH to automate the project setup process to reduce manual configuration and errors for developers. These Software Templates are part of the Backstage Scaffolder system.

A Software Template consists of a YAML file with the following elements:

Metadata
Names and describes the template so developers can find the correct starter kit in the catalog.
Parameters
Define the specific information developers must provide, such as the project name or owner.
Steps
Sequence of steps that the system performs to build the project, which can include fetching a repository skeleton, injecting parameters, and publishing the code to a Git provider.

8.3.9.3. Sample software template

This sample Software Template defines project parameters and publishes the generated code to a GitHub repository.

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: basic-node-service
  title: Basic Node.js Service
  description: A starter kit for a standardized Node.js microservice.
  tags:
    - nodejs
    - recommended
spec:
  owner: platform-team
  type: service
  parameters:
    - title: ProjectDetails
      required:
        - name
        - owner
      properties:
        name:
          title: Name
          type: string
          description: Unique name for the new repository.
        owner:
          title: Owner
          type: string
          description: The group responsible for this component.
          ui:field: OwnerPicker
          ui:options:
            allowedKinds:
              - Group
  steps:
    - id: fetch-base
      name: Fetch Skeleton
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}
    - id: publish
      name: Publish to GitHub
      action: publish:github
      input:
        allowedHosts: ['github.com']
        description: This is ${{ parameters.name }}
        repoUrl: github.com?owner=my-org&repo=${{ parameters.name }}
  output:
    links:
      - title: Repository
        url: ${{ steps['publish'].output.remoteUrl }}

8.3.9.4. Share software templates with your organization

To allow developers to create new projects independently using your standards, you must publish the Software Template definition to the RHDH catalog. This registration makes the template a selectable option in the software creator interface.

Prerequisites

  • If RBAC is enabled, you have a role with the following permissions: catalog.entity.create, catalog.location.create.
  • You have a Git repository to store Software Template files.

Procedure

  1. Navigate to the Create page in the RHDH interface.
  2. Select Register Component.
  3. Enter the full URL to your template.yaml file in the Repository URL field.
  4. Click Analyze and then Import.

Verification

  1. Navigate to the Create page.
  2. Confirm that your new template is displayed in the list of available options.

8.4. Automate repository onboarding to the catalog

8.4.1. Automate repository onboarding to the catalog

TODO: Replace this placeholder with an overview of Automate repository onboarding to the catalog.

8.4.2. Import source code repositories in bulk

8.4.2.1. Import source code repositories in bulk

TODO: Replace this placeholder with an overview of Import source code repositories in bulk.

8.4.3. Configure bulk import capabilities

8.4.3.1. Configure bulk import capabilities

TODO: Replace this placeholder with an overview of Configure bulk import capabilities.

8.5. Orchestrate infrastructure tasks using workflows

8.5.1. Orchestrate infrastructure tasks using workflows

TODO: Replace this placeholder with an overview of Orchestrate infrastructure tasks using workflows.

8.5.2. Build serverless workflows

8.5.2.1. Build serverless workflows

TODO: Replace this placeholder with an overview of Build serverless workflows.

8.5.3. Automate workflow deployments

8.5.3.1. Automate workflow deployments

TODO: Replace this placeholder with an overview of Automate workflow deployments.

8.5.3.2. Install Orchestrator in an air-gapped environment

8.5.3.2.1. Install Orchestrator in an air-gapped environment

TODO: Replace this placeholder with an overview of Install Orchestrator in an air-gapped environment.

8.6. Write and publish documentation as code to keep knowledge synchronized

8.6.1. Write and publish documentation as code to keep knowledge synchronized

TODO: Replace this placeholder with an overview of Write and publish documentation as code to keep knowledge synchronized.

8.6.2. Configure TechDocs storage and CI/CD pipelines

8.6.2.1. Configure TechDocs storage and CI/CD pipelines

TODO: Replace this placeholder with an overview of Configure TechDocs storage and CI/CD pipelines.

8.6.3. Install TechDocs add-ons

8.6.3.1. Install TechDocs add-ons

TODO: Replace this placeholder with an overview of Install TechDocs add-ons.

Chapter 9. Configure

9.1. Configure

TODO: Replace this placeholder with an overview of Configure.

9.2. Configure core parameters to meet infrastructure requirements

9.2.1. Configure core parameters to meet infrastructure requirements

TODO: Replace this placeholder with an overview of Configure core parameters to meet infrastructure requirements.

9.2.2. Default configurations to establish a deployment foundation

9.2.2.1. Default configurations to establish a deployment foundation

Deploy a standard Red Hat Developer Hub instance, understand its structure, and tailor the instance to meet your needs.

9.2.2.2. Red Hat Developer Hub default configuration guide

The Operator creates Kubernetes resources with default configuration that you can customize using the Backstage Custom Resource.

The Operator stores the default configuration in a ConfigMap named rhdh-default-config in the rhdh-operator namespace on OpenShift. This ConfigMap has the YAML manifests that define the foundational structure of the RHDH instance.

You can create a basic RHDH instance by applying an empty Backstage Custom Resource as follows:

apiVersion: backstage.redhat.com/v1alpha4
kind: Backstage
metadata:
name: my-rhdh-instance
namespace: rhdh

The Operator automatically creates the following resources in the specified RHDH namespace by default based on the default configuration:

File NameResource Group/Version/Kind (GVK)Resource NameDescription

deployment.yaml

apps/v1/Deployment

backstage-{cr-name}

(Mandatory) The main Backstage application deployment.

service.yaml

v1/Service

backstage-{cr-name}

(Mandatory) The Backstage application service.

db-statefulset.yaml

apps/v1/StatefulSet

backstage-psql-{cr-name}

The PostgreSQL database stateful set. Needed if spec.enabledDb=true.

db-service.yaml

v1/Service

backstage-psql-{cr-name}

The PostgreSQL database service. Needed if spec.enabledDb=true.

db-secret.yaml

v1/Secret

backstage-psql-{cr-name}

The PostgreSQL database credentials secret. Needed if spec.enabledDb=true.

route.yaml

route.openshift.io/v1

backstage-{cr-name}

The OpenShift Route to expose Backstage externally. (Optional) Applied to OpenShift only.

app-config.yaml

v1/ConfigMap

backstage-config-{cr-name}

(Optional) Specifies one or more Backstage app-config.yaml files.

configmap-files.yaml

v1/ConfigMap

backstage-files-{cr-name}

(Optional) Specifies additional ConfigMaps to mount as files into the Backstage Pod.

configmap-envs.yaml

v1/ConfigMap

backstage-envs-{cr-name}

(Optional) Specifies additional ConfigMaps to expose as environment variables in the Backstage Pod.

secret-files.yaml

v1/Secret or list of v1/Secret

backstage-files-{cr-name}-{secret-name}

(Optional) Specifies additional Secrets to mount as files into the Backstage Pod.

secret-envs.yaml

v1/Secret or list of v1/Secret

backstage-envs-{cr-name}

(Optional) Specifies additional Secrets to expose as environment variables in the Backstage Pod.

dynamic-plugins.yaml

v1/ConfigMap

backstage-dynamic-plugins-{cr-name}

(Optional) Specifies the dynamic plugins that the Operator installs into the Backstage instance.

pvcs.yaml

list of v1/PersistentVolumeClaim

backstage-{cr-name}-{pvc-name}

(Optional) The Persistent Volume Claim for PostgreSQL database.

Note

{cr-name} is the name of the Backstage Custom Resource, for example 'my-rhdh-instance' in the above example.

9.2.2.3. Automated Operator features

Use the Operator to automate key configuration processes for your Backstage application.

9.2.2.3.1. Metadata generation

The Operator automatically generates metadata values for default resources at runtime to ensure proper application function.

For all the default resources, the Operator generates metadata.name according to the rules defined in the Default Configuration files, particularly the Resource name column. For example, a Backstage Custom Resource (CR) named mybackstage creates a Kubernetes Deployment resource called backstage-mybackstage.

The Operator generates the following metadata for each resource:

  • deployment.yaml

    • spec.selector.matchLabels[rhdh.redhat.com/app] = backstage-{cr-name}
    • spec.template.metadata.labels[rhdh.redhat.com/app] = backstage-{cr-name}
  • service.yaml

    • spec.selector[rhdh.redhat.com/app] = backstage-{cr-name}
  • db-statefulset.yaml

    • spec.selector.matchLabels[rhdh.redhat.com/app] = backstage-psql-{cr-name}
    • spec.template.metadata.labels[rhdh.redhat.com/app] = backstage-psql-{cr-name}
  • db-service.yaml

    • spec.selector[rhdh.redhat.com/app] = backstage-psql-{cr-name}
9.2.2.3.2. Many resources

Define and create many resources of the same type in a single YAML file by using the --- delimiter to separate resource definitions.

For example, adding the following code snip to pvcs.yaml creates two PersistentVolumeClaims (PVCs) called backstage-{cr-name}-myclaim1 and backstage-{cr-name}-myclaim2 and mounts them to the Backstage container.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim1
...
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim2
...
9.2.2.3.3. Default base URLs

The Operator automatically sets base URLs for your application based on route parameters and OpenShift cluster ingress domain.

The Operator follows these rules to set the base URLs for your application:

  • If the cluster is not OpenShift, the Operator makes no changes.
  • If you explicitly set the spec.application.route.enabled field in your Custom Resource (CR) to false, the Operator makes no changes.
  • If you define spec.application.route.host in the Backstage CR, the Operator sets the base URLs to https&#58;//<spec.application.route.host>.
  • If you specify the spec.application.route.subdomain in the Backstage CR, the Operator sets the base URLs to https&#58;//<spec.application.route.subdomain>.<cluster_ingress_domain>.
  • If you do not set a custom host or subdomain, the Operator sets the base URLs to https&#58;//backstage-<cr_name>-<namespace>.<cluster_ingress_domain>, which is the default domain for the created Route resource.

The Operator updates the following base URLs in the default app-config config map:

  • app.baseUrl
  • backend.baseUrl
  • backend.cors.origin
Note

You can perform these actions on a best-effort basis and only on OpenShift. During an error or on non-OpenShift clusters, you can still override these defaults by providing a custom app-config config map.

9.2.2.4. Time syntax in Red Hat Developer Hub

Use supported time duration formats in Red Hat Developer Hub, including human-readable strings, duration objects, ISO 8601 strings, and cron expressions.

Format

Description

Example

Compound values

Human-readable strings

Simple strings compatible with the ms library.

30m

No

Duration objects

A structured object specifying time units. Matches the HumanDuration TypeScript interface.

  timeout:
    minutes: 30

Yes

ISO 8601 duration strings

Standard ISO 8601 duration strings.

PT30M

Yes

Format

Description

Example

Cron

An object containing a cron key with a crontab-style string. Used primarily by Scheduler services for tasks such as frequency).

  frequency:
    cron: '*/30 * * * *'
Warning

RHDH configuration reader readDurationFromConfig explicitly disallows plain numbers to prevent ambiguity.

However, specific raw configuration fields, such as direct Node.js HTTP server settings, might strictly require numbers. Always check the specific documentation for the field you are configuring.

9.2.3. Provision custom config maps and secrets to define platform behavior

9.2.3.1. Provision custom config maps and secrets to define platform behavior

Configure Red Hat Developer Hub by using config maps to mount files and directories and secrets to inject environment variables into your Red Hat OpenShift Container Platform application.

9.2.3.2. Provision your custom Red Hat Developer Hub configuration

Provision custom config maps and secrets on Red Hat OpenShift Container Platform (RHOCP) to configure Red Hat Developer Hub before running the application.

Tip

On Red Hat OpenShift Container Platform, you can skip this step to run Developer Hub with the default config map and secret. Your changes on this configuration might get reverted on Developer Hub restart.

Prerequisites

  • By using the OpenShift CLI (oc), you have access, with developer permissions, to the OpenShift cluster aimed at containing your Developer Hub instance.

Procedure

  1. For security, store your secrets as environment variables values in an OpenShift Container Platform secret, rather than in plain text in your configuration files. Collect all your secrets in the secrets.txt file, with one secret per line in KEY=value form.

    Enter your authentication secrets.

  2. Author your custom app-config.yaml file. This is the main Developer Hub configuration file. You need a custom app-config.yaml file to avoid the Developer Hub installer to revert user edits during upgrades. When your custom app-config.yaml file is empty, Developer Hub is using default values.

    • To prepare a deployment with the Red Hat Developer Hub Operator on OpenShift Container Platform, you can start with an empty file.
    • To prepare a deployment with the Red Hat Developer Hub Helm chart, or on Kubernetes, enter the Developer Hub base URL in the relevant fields in your app-config.yaml file to ensure proper functionality of Developer Hub. The base URL is what a Developer Hub user sees in their browser when accessing Developer Hub. The relevant fields are baseUrl in the app and backend sections, and origin in the backend.cors subsection:

      Configuring the baseUrl in app-config.yaml:

      app:
        title: Red Hat Developer Hub
        baseUrl: https://<my_developer_hub_domain>
      
      backend:
        auth:
          externalAccess:
            - type: legacy
              options:
                subject: legacy-default-config
                secret: "${BACKEND_SECRET}"
        baseUrl: https://<my_developer_hub_domain>
        cors:
          origin: https://<my_developer_hub_domain>
    • Optionally, enter your configuration such as:

  3. Author your custom dynamic-plugins.yaml file to enable plugins. By default, Developer Hub enables a minimal plugin set, and disables plugins that require configuration or secrets, such as the GitHub repository discovery plugin and the Role-based access control (RBAC) plugin.

    Enable the GitHub repository discovery and the RBAC features:

    dynamic.plugins.yaml

    includes:
      - dynamic-plugins.default.yaml
    plugins:
      - package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github
        disabled: false
      - package: ./dynamic-plugins/dist/backstage-community-plugin-rbac
        disabled: false

  4. Provision your custom configuration files to your OpenShift Container Platform cluster.

    1. Create the <my-rhdh-project> project aimed at containing your Developer Hub instance.

      $ oc create namespace my-rhdh-project
    2. Create config maps for your app-config.yaml and dynamic-plugins.yaml files in the <my-rhdh-project> project.

      $ oc create configmap my-rhdh-app-config --from-file=app-config.yaml --namespace=my-rhdh-project
      $ oc create configmap dynamic-plugins-rhdh --from-file=dynamic-plugins.yaml --namespace=my-rhdh-project

      You can also create the config maps by using the web console.

    3. Provision your secrets.txt file to the my-rhdh-secrets secret in the <my-rhdh-project> project.

      $ oc create secret generic my-rhdh-secrets --from-file=secrets.txt --namespace=my-rhdh-project

      You can also create the secret by using the web console.

9.2.3.3. Use the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration

Use the Red Hat Developer Hub Operator to deploy Developer Hub with custom configuration by creating a custom resource that mounts config maps and injects secrets.

Prerequisites

  • By using the OpenShift CLI (oc), you have access, with developer permissions, to the OpenShift Container Platform cluster aimed at containing your Developer Hub instance.
  • Your administrator has installed the Red Hat Developer Hub Operator in the cluster.
  • You have provisioned your custom config maps and secrets in your <my-rhdh-project> project.
  • You have a working default storage class, such as the Elastic Block Store (EBS) storage add-on, configured in your EKS cluster.

Procedure

  1. Author your Backstage CR in a my-rhdh-custom-resource.yaml file to use your custom config maps and secrets.

    Minimal my-rhdh-custom-resource.yaml custom resource example:

    apiVersion: rhdh.redhat.com/v1alpha5
    kind: Backstage
    metadata:
      name: my-rhdh-custom-resource
    spec:
      application:
        appConfig:
          mountPath: /opt/app-root/src
          configMaps:
             - name: my-rhdh-app-config
        extraEnvs:
          secrets:
             - name: <my_product_secrets>
        extraFiles:
          mountPath: /opt/app-root/src
        route:
          enabled: true
      database:
        enableLocalDb: true

    my-rhdh-custom-resource.yaml custom resource example with dynamic plugins and RBAC policies config maps, and external PostgreSQL database secrets:

    apiVersion: rhdh.redhat.com/v1alpha5
    kind: Backstage
    metadata:
      name: <my-rhdh-custom-resource>
    spec:
      application:
        appConfig:
          mountPath: /opt/app-root/src
          configMaps:
             - name: my-rhdh-app-config
             - name: rbac-policies
        dynamicPluginsConfigMapName: dynamic-plugins-rhdh
        extraEnvs:
          secrets:
             - name: <my_product_secrets>
             - name: my-rhdh-database-secrets
        extraFiles:
          mountPath: /opt/app-root/src
          secrets:
            - name: my-rhdh-database-certificates-secrets
              key: postgres-crt.pem, postgres-ca.pem, postgres-key.key
        route:
          enabled: true
      database:
        enableLocalDb: false
    Mandatory fields
    No fields are mandatory. You can create an empty Backstage CR and run Developer Hub with the default configuration.
    Optional fields
    spec.application.appConfig.configMaps
    Enter your config map name list.

    Mount files in the my-rhdh-app-config config map:

    spec:
      application:
        appConfig:
          mountPath: /opt/app-root/src
          configMaps:
             - name: my-rhdh-app-config

    Mount files in the my-rhdh-app-config and rbac-policies config maps:

    spec:
      application:
        appConfig:
          mountPath: /opt/app-root/src
          configMaps:
             - name: my-rhdh-app-config
             - name: rbac-policies
    spec.application.extraEnvs.envs

    Optionally, enter your additional environment variables that are not secrets, such as your proxy environment variables.

    Inject your HTTP_PROXY, HTTPS_PROXY and NO_PROXY environment variables:

    spec:
      application:
        extraEnvs:
          envs:
            - name: HTTP_PROXY
              value: 'http://10.10.10.105:3128'
            - name: HTTPS_PROXY
              value: 'http://10.10.10.106:3128'
            - name: NO_PROXY
              value: 'localhost,example.org'
    spec.application.extraEnvs.secrets

    Enter your environment variables secret name list.

    Inject the environment variables in your Red Hat Developer Hub secret:

    spec:
      application:
        extraEnvs:
          secrets:
             - name: <my_product_secrets>

    Inject the environment variables in the Red Hat Developer Hub and my-rhdh-database-secrets secrets:

    spec:
      application:
        extraEnvs:
          secrets:
             - name: <my_product_secrets>
             - name: my-rhdh-database-secrets
    Note

    <my_product_secrets> is your preferred Developer Hub secret name, specifying the identifier for your secret configuration within Developer Hub.

    spec.application.extraFiles.secrets

    Enter your certificates files secret name and files list.

    Mount the postgres-crt.pem, postgres-ca.pem, and postgres-key.key files contained in the my-rhdh-database-certificates-secrets secret:

    spec:
      application:
        extraFiles:
          mountPath: /opt/app-root/src
          secrets:
            - name: my-rhdh-database-certificates-secrets
              key: postgres-crt.pem, postgres-ca.pem, postgres-key.key
    spec.database.enableLocalDb

    Enable or disable the local PostgreSQL database.

    Disable the local PostgreSQL database generation to use an external postgreSQL database:

    spec:
      database:
        enableLocalDb: false

    On a development environment, use the local PostgreSQL database:

    spec:
      database:
        enableLocalDb: true
    spec.deployment
    Optionally, enter your deployment configuration.
  2. Apply your Backstage CR to start or update your Developer Hub instance:

    $ oc apply --filename=my-rhdh-custom-resource.yaml --namespace=my-rhdh-project

9.2.3.4. Use the Red Hat Developer Hub Helm chart to run Developer Hub with your custom configuration

Use the Red Hat Developer Hub Helm chart to deploy Developer Hub with a custom application configuration file on OpenShift Container Platform.

Prerequisites

Procedure

  1. Configure Helm to use your custom configuration files in Developer Hub.

    1. Go to the Helm tab to see the list of Helm releases.
    2. Click the overflow menu on the Helm release that you want to use and select Upgrade.
    3. Use the YAML view to edit the Helm configuration.
    4. Set the value of the upstream.backstage.extraAppConfig.configMapRef and upstream.backstage.extraAppConfig.filename parameters as follows:

      upstream:
        backstage:
          extraAppConfig:
            - configMapRef: my-rhdh-app-config
              filename: app-config.yaml
    5. Click Upgrade.

Next steps

  • Install Developer Hub by using Helm.

9.2.4. Configure a route with an external TLS certificate by using the Operator

To secure application traffic with your own certificate, configure the Developer Hub route to use a TLS certificate stored in a Kubernetes secret.

Important

On Red Hat OpenShift Container Platform 4.18 and earlier, securing a route with an external certificate is a Technology Preview feature that requires enabling the RouteExternalCertificate Feature Gate. On Red Hat OpenShift Container Platform 4.19 and later, this feature is Generally Available and does not require a Feature Gate.

For more information, see Securing routes with external certificates in TLS secrets.

Prerequisites

  • An OpenShift Container Platform administrator has installed the Red Hat Developer Hub Operator.
  • You have a TLS certificate stored in a Kubernetes secret of type kubernetes.io/tls in the same namespace as your Developer Hub instance, and the certificate is valid for the route host configured in your Backstage custom resource, for example my-rhdh.apps.example.com.

Procedure

  1. Add the spec.application.route.tls.externalCertificateSecretName field to your Backstage custom resource, referencing the name of the secret that contains your TLS certificate:

    apiVersion: rhdh.redhat.com/v1alpha5
    kind: Backstage
    metadata:
      name: my-rhdh
    spec:
      application:
        route:
          enabled: true
          host: my-rhdh.apps.example.com
          tls:
            externalCertificateSecretName: my-rhdh-tls-cert
  2. Apply the updated custom resource:

    $ oc apply -f my-rhdh.yaml

Verification

  • Verify that the route uses your external certificate:

    $ oc get route backstage-$cr_name -o jsonpath='{.spec.tls}' | jq .

9.2.5. Red Hat Developer Hub secrets

Developer Hub uses Kubernetes secrets to store sensitive values such as authentication credentials, backend secrets, and database passwords. The app-config.yaml file references these values through ${VAR_NAME} environment variable substitution.

The following are common secrets used by Developer Hub:

my-rhdh-secrets
The main Developer Hub secrets containing authentication provider client IDs and secrets, the BACKEND_SECRET, and other sensitive credentials.
my-rhdh-database-certificates-secrets
Optional. Contains external PostgreSQL TLS certificates such as postgres-crt.pem, postgres-ca.pem, and postgres-key.key.

To create secrets, author the secret values in a local file (for example, my-rhdh-secrets.txt), then create a Kubernetes secret by running oc create secret generic.

You can provision secrets using either of the following methods:

  • With the Operator: Reference secrets in the Backstage custom resource by using the spec.application.extraEnvs.secrets field to inject secrets as environment variables, or the spec.application.extraFiles.secrets field to mount secrets as files, such as, TLS certificates.
  • With the Helm chart: Reference secrets by using the upstream.backstage.extraEnvVarsSecrets or upstream.backstage.extraEnvVars field with a secretKeyRef. You can also mount secrets as files by using both the upstream.backstage.extraVolumes and upstream.backstage.extraVolumeMounts values.

9.2.6. Inject extra files and environment variables into Backstage containers

Inject extra files and environment variables into Backstage containers by mounting ConfigMaps and Secrets by using the mountPath field.

  • If you do not specify key and mountPath: The system mounts each key or value as a filename or content with a subPath.
  • If you specify key with or without mountPath: The system mounts the specified key or value with a subPath.
  • If you specify only mountPath: The system mounts a directory containing all the keys or values without a subPath.
  • If you do not specify the containers field: The volume mounts only to the backstage-backend container. By default, files mount only to the backstage-backend container. You can also specify other targets, including a list of containers by name (such as dynamic-plugin-install or selectcustom sidecars) or select all containers in the Backstage Pod.

    Note
    • OpenShift Container Platform does not automatically update a volume mounted with subPath. By default, the RHDH Operator monitors these ConfigMaps or Secrets and refreshes the RHDH Pod when changes occur.
    • For security purposes, Red Hat Developer Hub does not give the Operator Service Account read access to Secrets. As a result, mounting files from Secrets without specifying both mountPath and key is not supported.

Procedure

  1. Apply the configuration to your Backstage custom resource (CR). The following code block is an example:

    spec:
      application:
        extraFiles:
          mountPath: _<default_mount_path>_
          configMaps:
            - name: _<configmap_name_all_entries>_
            - name: _<configmap_name_single_key>_
              key: _<specific_file_key>_
              containers:
                - "*"
            - name: _<configmap_name_custom_path>_
              mountPath: _<custom_cm_mount_path>_
              containers:
                - backstage-backend
                - install-dynamic-plugins
          secrets:
            - name: _<secret_name_single_key>_
              key: _<specific_secret_key>_
              containers:
                - install-dynamic-plugins
            - name: _<secret_name_custom_path>_
              mountPath: _<custom_secret_mount_path>_
          pvcs:
            - name: _<pvc_name_default_path>_
            - name: _<pvc_name_custom_path>_
              mountPath: _<custom_pvc_mount_path>_
        extraEnvs:
          configMaps:
            - name: _<configmap_name_env_var>_
              key: _<env_var_key>_
              containers:
                - "*"
          secrets:
            - name: _<secret_name_all_envs>_
          envs:
            - name: _<static_env_var_name>_
              value: "_<static_env_var_value>_"
              containers:
               - install-dynamic-plugins

    where:

    spec.application.extraFiles.mountPath
    Specifies the default base mount path for files if you do not set a specific mountPath for a resource (for example, /<default_mount_path>).
    spec.application.extraFiles.configMaps.name
    Mounts all entries from <configmap_name_all_entries> to the default mount path.
    spec.application.extraFiles.configMaps.key
    Mounts **only the specified key (for example, <specific_file_key>.txt) from the ConfigMap.
    spec.application.extraFiles.configMaps.containers
    Targets all containers ("*") for mounting.
    spec.application.extraFiles.configMaps.mountPath
    Overrides the default and mounts all ConfigMap entries as a directory at the specified path (for example, /<custom_cm_mount_path>).
    spec.application.extraFiles.secrets.key
    Mounts only a specific key from the Secret.
    spec.application.extraFiles.secrets.mountPath
    Overrides the default and mounts all Secret entries as a directory at the specified path (for example, /<custom_secret_mount_path>).
    spec.application.extraFiles.pvcs.name
    Mounts the PVC to the default mount path, appending the PVC name (for example, /<default_mount_path>/<pvc_name_default_path>).
    spec.application.extraFiles.pvcs.mountPath
    Overrides the default and mounts the PVC to the specified path (for example, /<custom_pvc_mount_path>).
    spec.application.extraEnvs.configMaps.containers
    Injects the specified ConfigMap key as an environment variable into all containers ("*").
    spec.application.extraEnvs.secrets.name
    Injects all keys from the Secret as environment variables into the default container.
    spec.application.envs.containers

    Targets only the listed container for the static environment variable injection.

    Note

    The following explicit options are supported:

    1. No or an empty field: Mounts only to the backstage-backend container.
    2. * (asterisk) as the first and only array element: Mounts to all containers.
    3. Explicit container names, for example, install-dynamic-plugins: Mounts only to the listed containers.

Verification

Verify the files mount with the following correct paths and container targets:

ResourceTarget typePath(s) or name(s)Container(s)

ConfigMap (<configmap_name_all_entries>)

File

/<default_mount_path>/<file_1_key>, /<default_mount_path>/<file_2_key>

backstage-backend

ConfigMap (<configmap_name_single_key>)

File

/<default_mount_path>/<specific_file_key>.txt

All

ConfigMap (<configmap_name_custom_path>)

Directory

/<custom_cm_mount_path>/

backstage-backend, install-dynamic-plugins

Secret (<secret_name_single_key>)

File

/<default_mount_path>/<specific_secret_key>.txt

install-dynamic-plugins

Secret (<secret_name_custom_path>)

Directory

/<custom_secret_mount_path>/

backstage-backend

PVC (<pvc_name_default_path>)

Directory

/<default_mount_path>/<pvc_name_default_path>

backstage-backend

ConfigMap (<configmap_name_env_var>)

Environment variable

<env_var_key>

All

Secret (<secret_name_all_envs>)

Environment variable

<secret_key_a>, <secret_key_b>

backstage-backend

Custom Resource Definition (CRD) (envs)

Environment variable

<static_env_var_name> = <static_env_var_value>

install-dynamic-plugins

9.2.7. Configure mount paths for default Secrets and Persistent Volume Claims (PVCs)

Configure custom mount paths for Secrets and PVCs by adding the rhdh.redhat.com/mount-path annotation to your resource.

Procedure

  1. To specify a PVC mount path, add the rhdh.redhat.com/mount-path annotation to your configuration file as shown in the following example:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: <my_claim>
      annotations:
        rhdh.redhat.com/mount-path: /mount/path/from/annotation

    Where:

    <my_claim>
    The PVC to mount.
    rhdh.redhat.com/mount-path
    The mount path for the PVC, in this case the /mount/path/from/annotation directory.
  2. To specify a Secret mount path, add the rhdh.redhat.com/mount-path annotation to your configuration file as shown in the following example:

    apiVersion: v1
    kind: Secret
    metadata:
      name: <my_secret>
      annotations:
        rhdh.redhat.com/mount-path: /mount/path/from/annotation

9.2.8. Mount secrets and PVCs to specific containers

Mount secrets and PVCs to specific containers by adding the rhdh.redhat.com/containers annotation to your configuration file.

Procedure

  1. To mount Secrets to all containers, set the rhdh.redhat.com/containers annotation to * in your configuration file:

    apiVersion: v1
    kind: Secret
    metadata:
      name: <my_secret>
      annotations:
        rhdh.redhat.com/containers: *
    Important

    Set rhdh.redhat.com/containers to * to mount it to all containers in the deployment.

  2. To mount to specific containers, separate the names with commas:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: <my_claim>
      annotations:
        rhdh.redhat.com/containers: "init-dynamic-plugins,backstage-backend"
    Note

    This configuration mounts the <my_claim> PVC to the init-dynamic-plugins and backstage-backend containers.

9.2.9. Configure Red Hat Developer Hub deployment when using the Operator

Configure Red Hat Developer Hub deployment by using the spec.deployment.patch field in the Red Hat Developer Hub Operator custom resource to control the Deployment resource.

Create a Backstage CR with the following fields:

apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
  name: developer-hub
spec:
  deployment:
    patch:
      spec:
        template:
labels

Add labels to the Developer Hub pod.

For example, to add the label my=true:

apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
  name: developer-hub
spec:
  deployment:
    patch:
      spec:
        template:
          metadata:
            labels:
              my: true
volumes

Add an additional volume named my-volume and mount it under /my/path in the Developer Hub application container.

apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
  name: developer-hub
spec:
  deployment:
    patch:
      spec:
        template:
          spec:
            containers:
              - name: backstage-backend
                volumeMounts:
                  - mountPath: /my/path
                    name: my-volume
            volumes:
              - ephemeral:
                  volumeClaimTemplate:
                    spec:
                      storageClassName: "special"
                name: my-volume

Replace the default dynamic-plugins-root volume with a persistent volume claim (PVC) named dynamic-plugins-root. Note the $patch: replace directive, otherwise the system adds a new volume.

apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
  name: developer-hub
spec:
  deployment:
    patch:
      spec:
        template:
          spec:
            volumes:
              - $patch: replace
                name: dynamic-plugins-root
                persistentVolumeClaim:
                  claimName: dynamic-plugins-root
cpu request

Set the CPU request for the Developer Hub application container to 250m.

apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
  name: developer-hub
spec:
  deployment:
    patch:
      spec:
        template:
          spec:
            containers:
              - name: backstage-backend
                resources:
                  requests:
                    cpu: 250m
my-sidecar container

Add a new my-sidecar sidecar container into the Developer Hub Pod.

apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
  name: developer-hub
spec:
  deployment:
    patch:
      spec:
        template:
          spec:
            containers:
              - name: my-sidecar
                image: quay.io/my-org/my-sidecar:latest

Additional resources

9.2.10. Configure an RHDH instance with a TLS connection in Kubernetes

Configure RHDH with a TLS connection in Kubernetes to ensure secure connections with third-party applications and external databases.

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

  • You have set up an Azure Red Hat OpenShift (ARO) cluster with a public CA-signed certificate. For more information about obtaining CA certificates, refer to your vendor documentation.
  • You have created a namespace and setup a service account with proper read permissions on resources.

    For example, you can use the following Kubernetes manifest for role-based access control:

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: backstage-read-only
    rules:
      - apiGroups:
          - '*'
        resources:
          - pods
          - configmaps
          - services
          - deployments
          - replicasets
          - horizontalpodautoscalers
          - ingresses
          - statefulsets
          - limitranges
          - resourcequotas
          - daemonsets
        verbs:
          - get
          - list
          - watch
    #...
  • You have obtained the secret and the service CA certificate associated with your service account.
  • You have created some resources and added annotations to them so the Kubernetes plugin can discover them. You can apply these Kubernetes annotations:

    • backstage.io/kubernetes-id to label components
    • backstage.io/kubernetes-namespace to label namespaces

Procedure

  1. Enable the Kubernetes plugins in the dynamic-plugins-rhdh.yaml file by setting disabled to false:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: dynamic-plugins-rhdh
    data:
      dynamic-plugins.yaml: |
        includes:
          - dynamic-plugins.default.yaml
        plugins:
          - package: ./dynamic-plugins/dist/backstage-plugin-kubernetes-backend-dynamic
            disabled: false
          - package: ./dynamic-plugins/dist/backstage-plugin-kubernetes
            disabled: false
            # ...
    Note

    The backstage-plugin-kubernetes plugin is currently in Technology Preview. As an alternative, you can use the ./dynamic-plugins/dist/backstage-plugin-topology-dynamic plugin, which is Generally Available (GA).

  2. Set the Kubernetes cluster details and configure the catalog sync options in the app-config.yaml configuration file:

    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: my-rhdh-app-config
    data:
      "app-config.yaml": |
      # ...
      catalog:
        rules:
          - allow: [Component, System, API, Resource, Location]
        providers:
          kubernetes:
            openshift:
              cluster: openshift
              processor:
                namespaceOverride: default
                defaultOwner: guests
              schedule:
                frequency:
                  seconds: 30
                timeout:
                  seconds: 5
      kubernetes:
        serviceLocatorMethod:
          type: 'multiTenant'
        clusterLocatorMethods:
          - type: 'config'
            clusters:
              - url: <target_cluster_api_server_url>
                name: openshift
                authProvider: 'serviceAccount'
                skipTLSVerify: false
                skipMetricsLookup: true
                dashboardUrl: <target_cluster_console_url>
                dashboardApp: openshift
                serviceAccountToken: ${K8S_SERVICE_ACCOUNT_TOKEN}
                caData: ${K8S_CONFIG_CA_DATA}
                # ...
    url
    The base URL to the Kubernetes control plane. You can run the kubectl cluster-info command to get the base URL.
    skipTLSVerify
    Set the value of this parameter to false to enable the verification of the TLS certificate.
    dashboardUrl
    (Optional) The link to the Kubernetes dashboard managing the ARO cluster.
    serviceAccountToken
    (Optional) Pass the service account token by using a K8S_SERVICE_ACCOUNT_TOKEN environment variable that you define in your <my_product_secrets> secret.
    caData
    Pass the CA data by using a K8S_CONFIG_CA_DATA environment variable that you define in your <my_product_secrets> secret.
  3. Save the configuration changes.

Verification

  1. Run the RHDH application to import your catalog:

    $ kubectl -n rhdh-operator get pods -w
  2. Verify that the pod log shows no errors for your configuration.
  3. Go to Catalog and check the component page in the Developer Hub instance to verify the cluster connection and the presence of your created resources.
Note

If you meet connection errors, such as certificate issues or permissions, check the message box in the component page or view the logs of the pod.

9.2.11. Configure corporate proxy settings to enable external network access

9.2.11.1. Configure corporate proxy settings to enable external network access

In a network restricted environment, configure Red Hat Developer Hub to use your proxy to access remote network resources.

You can run the Developer Hub application behind a corporate proxy by setting any of the following environment variables before starting the application:

HTTP_PROXY
Denotes the proxy to use for HTTP requests.
HTTPS_PROXY
Denotes the proxy to use for HTTPS requests.
NO_PROXY
Set the environment variable to bypass the proxy for certain domains. The variable value is a comma-separated list of hostnames or IP addresses that do not require the proxy, even if you specify one.

9.2.11.2. The NO_PROXY exclusion rules

Configure NO_PROXY to bypass the proxy for specific hostnames, IP addresses, and port numbers when using Developer Hub.

Note

The default value for NO_PROXY in RHDH is localhost,127.0.0.1. If you want to override it, include at least localhost or localhost:7007 in the list. Otherwise, the RHDH backend might fail.

Matching follows these rules:

  • NO_PROXY=* will bypass the proxy for all requests.
  • Space and commas might separate the entries in the NO_PROXY list. For example, NO_PROXY="localhost,example.com", or NO_PROXY="localhost example.com", or NO_PROXY="localhost, example.com" would have the same effect.
  • If NO_PROXY has no entries, configuring the HTTP(S)_PROXY settings makes the backend send all requests through the proxy.
  • The backend does not perform a DNS lookup to decide if a request should bypass the proxy or not. For example, if DNS resolves example.com to 1.2.3.4, setting NO_PROXY=1.2.3.4 has no effect on requests sent to example.com. Only requests sent to the IP address 1.2.3.4 bypass the proxy.
  • If you add a port after the hostname or IP address, the request must match both the host/IP and port to bypass the proxy. For example, NO_PROXY=example.com:1234 would bypass the proxy for requests to http(s)://example.com:1234, but not for requests on other ports, such as http(s)://example.com.
  • If you do not specify a port after the hostname or IP address, all requests to that host/IP address will bypass the proxy regardless of the port. For example, NO_PROXY=localhost would bypass the proxy for requests sent to URLs such as http(s)://localhost:7077 and http(s)://localhost:8888.
  • IP Address blocks in CIDR notation will not work. So setting NO_PROXY=10.11.0.0/16 will not have any effect, even if the backend sends a request to an IP address in that block.
  • Supports only IPv4 addresses. IPv6 addresses such as ::1 will not work.
  • Generally, the proxy is only bypassed if the hostname is an exact match for an entry in the NO_PROXY list. The only exceptions are entries that start with a dot (.) or with a wildcard (*). In such a case, bypass the proxy if the hostname ends with the entry.
Note

List the domain and the wildcard domain if you want to exclude a given domain and all its subdomains. For example, you would set NO_PROXY=example.com,.example.com to bypass the proxy for requests sent to http(s)://example.com and http(s)://subdomain.example.com.

9.2.11.3. Configure proxy information in Operator deployment

Configure proxy settings for Operator-based deployments by setting environment variables in the ConfigMap or custom resource file.

  • As a cluster administrator with access to the Operator namespace, you can configure the proxy variables in the Operator’s default ConfigMap file. This configuration applies the proxy settings to all the users of the Operator.
  • As a developer, you can configure the proxy variables in a custom resource (CR) file. This configuration applies the proxy settings to the RHDH application created from that CR.

Prerequisites

  • You have installed the Red Hat Developer Hub application.

Procedure

  1. Perform one of the following steps based on your role:
  2. As an administrator, set the proxy information in the Operator’s default ConfigMap file:

    1. Search for a ConfigMap file named backstage-default-config in the default namespace rhdh-operator and open it.
    2. Find the deployment.yaml key.
    3. Set the value of the HTTP_PROXY, HTTPS_PROXY, and NO_PROXY environment variables in the Deployment spec as shown in the following example:

      # ...
        deployment.yaml: |-
          apiVersion: apps/v1
          kind: Deployment
          spec:
            template:
              spec:
                # ...
                initContainers:
                  - name: install-dynamic-plugins
                    # ...
                    env:
                      - name: NPM_CONFIG_USERCONFIG
                        value: /opt/app-root/src/.npmrc.dynamic-plugins
                      - name: HTTP_PROXY
                        value: 'http://10.10.10.105:3128'
                      - name: HTTPS_PROXY
                        value: 'http://10.10.10.106:3128'
                      - name: NO_PROXY
                        value: 'localhost,example.org'
                    # ...
                containers:
                  - name: backstage-backend
                    # ...
                    env:
                      - name: APP_CONFIG_backend_listen_port
                        value: "7007"
                      - name: HTTP_PROXY
                        value: 'http://10.10.10.105:3128'
                      - name: HTTPS_PROXY
                        value: 'http://10.10.10.106:3128'
                      - name: NO_PROXY
                        value: 'localhost,example.org'
  3. As a developer, set the proxy information in your Backstage CR file as shown in the following example:

    spec:
      # ...
      application:
        extraEnvs:
          envs:
            - name: HTTP_PROXY
              value: 'http://10.10.10.105:3128'
            - name: HTTPS_PROXY
              value: 'http://10.10.10.106:3128'
            - name: NO_PROXY
              value: 'localhost,example.org'
  4. Save the configuration changes.

9.2.11.4. Configure proxy information in Helm deployment

Configure proxy settings for Helm-based deployments by setting environment variables in the Helm configuration file.

Prerequisites

  • You have installed the Red Hat Developer Hub application.

Procedure

  1. Set the proxy information in your Helm configuration file:

    upstream:
      backstage:
        extraEnvVars:
          - name: HTTP_PROXY
            value: '<http_proxy_url>'
          - name: HTTPS_PROXY
            value: '<https_proxy_url>'
          - name: NO_PROXY
            value: '<no_proxy_settings>'

    Where,

    <http_proxy_url>
    Denotes a variable that you must replace with the HTTP proxy URL.
    <https_proxy_url>
    Denotes a variable that you must replace with the HTTPS proxy URL.
    <no_proxy_settings>

    Denotes a variable that you must replace with comma-separated URLs, which you want to exclude from proxying, for example, <example1>.com,<example2>.com.

    For example:

    upstream:
      backstage:
        extraEnvVars:
          - name: HTTP_PROXY
            value: 'http://10.10.10.105:3128'
          - name: HTTPS_PROXY
            value: 'http://10.10.10.106:3128'
          - name: NO_PROXY
            value: 'localhost,example.org'
  2. Save the configuration changes.

9.3. Customize the user interface to reflect organizational branding

9.3.1. Customize the user interface to reflect organizational branding

TODO: Replace this placeholder with an overview of Customize the user interface to reflect organizational branding.

9.3.2. Customize Learning Paths to integrate tailored e-learning content

9.3.2.1. Customize Learning Paths to integrate tailored e-learning content

In Red Hat Developer Hub, you can configure Learning Paths by hosting the required data externally and by using the built-in proxy to deliver this data. You can provide Learning Paths data from a JSON file hosted on a web server or from a dedicated service that provides the data in JSON format by using an API.

9.3.2.2. About Learning Paths

The Learning Paths plugin in Red Hat Developer Hub integrates customized e-learning content into developer workflows to accelerate onboarding, address skill gaps, and ensure that teams stay updated with best practices.

9.3.2.3. Customize the Learning Paths by using a hosted JSON file

For ease of use and simplicity, you can configure the Learning Paths by using a hosted JSON file.

Procedure

  1. Publish the JSON file containing your Learning Paths data to a web server, such as GitHub or GitLab. You can find an example at https://raw.githubusercontent.com/redhat-developer/rhdh/release-1.10/packages/app/public/learning-paths/data.json.
  2. Configure the Developer Hub proxy to access the Learning Paths data from the hosted JSON file, by adding the following to the app-config.yaml file:

    proxy:
      endpoints:
        '/developer-hub':
          target: <target>
          pathRewrite:
            '^/api/proxy/developer-hub/learning-paths': '<learning_path.json>'
          changeOrigin: true
          secure: true
    <target>
    Enter the hosted JSON file base URL, such as https://raw.githubusercontent.com.
    <learning_path.json>

    Enter the hosted JSON file path without the base URL, such as '/redhat-developer/rhdh/main/packages/app/public/learning-paths/data.json'

    Tip

    When also configuring the home page, due to the use of overlapping pathRewrites for both the learning-path and homepage quick access proxies, create the learning-paths configuration (^api/proxy/developer-hub/learning-paths) before you create the homepage configuration (^/api/proxy/developer-hub). For example:

    proxy:
      endpoints:
        '/developer-hub':
          target: https://raw.githubusercontent.com/
          pathRewrite:
            '^/api/proxy/developer-hub/learning-paths': '/redhat-developer/rhdh/main/packages/app/public/learning-paths/data.json'
            '^/api/proxy/developer-hub': '/redhat-developer/rhdh/main/packages/app/public/homepage/data.json'
          changeOrigin: true
          secure: true

9.3.2.4. Customize the Learning Paths by using a customization service

For advanced scenarios, you can host your Red Hat Developer Hub customization service to provide data to all configurable Developer Hub pages, such as the Learning Paths. You can even use a different service for each page.

Procedure

  1. Deploy your Developer Hub customization service on the same OpenShift Container Platform cluster as your Developer Hub instance. You can find an example at red-hat-developer-hub-customization-provider, that provides the same data as default Developer Hub data. The customization service provides a Learning Paths data URL such as: http://<rhdh-customization-provider>/learning-paths.
  2. Configure the Developer Hub proxy to use your dedicated service to provide the Learning Path data, add the following to the app-config.yaml file:

    proxy:
      endpoints:
        '/developer-hub/learning-paths':
          target: <learning_path_data_url>
          changeOrigin: true
          qsecure: true # Change to "false" in case of using self hosted cluster with a self-signed certificate

9.3.2.5. Start and complete lessons in Learning Paths

As a developer, you can start a course and complete the lessons at your own pace.

Prerequisites

  • You can log in to developers.redhat.com
  • If RBAC is enabled, you have a role with the following permission: catalog.entity.read.

Procedure

  1. In your Red Hat Developer Hub navigation menu, click Learning Paths.
  2. Select the tile for the course you want to begin.

    Note

    This action redirects you to the main page of the course in the Red Hat Developers site.

9.3.3. Configure the global header for consistent top-level navigation

9.3.3.1. Configure the global header for consistent top-level navigation

As an administrator, you can configure the Red Hat Developer Hub global header to create a consistent and flexible navigation bar across your Developer Hub instance. By default, the Developer Hub global header includes the following components:

  • Self-service button provides quick access to a variety of templates, enabling users to efficiently set up services, backend and front-end plugins within Developer Hub
  • Support button that can link an internal or external support page
  • Notifications button displays alerts and updates from plugins and external services
  • Search input field allows users to find services, components, documentation, and other resources within Developer Hub
  • Plugin extension capabilities provide a preinstalled and enabled catalog of available plugins in Developer Hub
  • User profile drop-down menu provides access to profile settings, appearance customization, Developer Hub metadata, and a logout button

9.3.3.2. Customize your Red Hat Developer Hub global header

Extend the global header with additional buttons and customize the order and position of icons and features by using the red-hat-developer-hub.backstage-plugin-global-header dynamic plugin.

  - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
    disabled: false
    pluginConfig:
      app:
        sidebar:
          search: false
          settings: false
      dynamicPlugins:
        frontend:
          default.main-menu-items:
            menuItems:
              default.create:
                title: ''
          red-hat-developer-hub.backstage-plugin-global-header: # the default enabled dynamic header plugin
            mountPoints:
              - mountPoint: application/header
                importName: GlobalHeader
                config:
                  position: above-main-content 1
              - mountPoint: global.header/component
                importName: SearchComponent
                config:
                  priority: 100
              - mountPoint: global.header/component
                importName: Spacer
                config:
                  priority: 99
                  props:
                    growFactor: 0
              - mountPoint: global.header/component
                importName: HeaderIconButton
                config:
                  priority: 90
                  props:
                    title: Self-service
                    icon: add
                    to: create
              - mountPoint: global.header/component
                importName: SupportButton
                config:
                  priority: 80
              - mountPoint: global.header/component
                importName: NotificationButton
                config:
                  priority: 70
              - mountPoint: global.header/component
                importName: Divider
                config:
                  priority: 50
              - mountPoint: global.header/component
                importName: ProfileDropdown
                config:
                  priority: 10
              - mountPoint: global.header/profile
                importName: MenuItemLink
                config:
                  priority: 100
                  props:
                    title: Settings
                    link: /settings
                    icon: manageAccounts
              - mountPoint: global.header/profile
                importName: LogoutButton
                config:
                  priority: 10

where:

search
Enter false to hide the Search modal in the sidebar menu. Enter true to display the Search modal in the sidebar menu.
settings
Enter false to hides the Settings button in the sidebar menu. Enter true to display the Settings button in the sidebar menu.
default.main-menu-items
Enter this field to hide the Self-service button from the sidebar menu. Remove this field to display the Self-service button in the sidebar menu.
position
Enter above-main-content to position the header above the main content. Enter above-sidebar to position the header above the sidebar.

To extend the functionality of the default global header, include any of the following attributes in your global header entry:

mountPoint
Specifies the location of the header. Use application/header to specify it as a global header. You can configure several global headers at different positions by adding entries to the mountPoints field.
importName

Specifies the component exported by the global header plugin.

The red-hat-developer-hub.backstage-plugin-global-header package (enabled by default) offers the following header components as possible mount point values:

  • SearchComponent: Adds a search bar (enabled by default).
  • Spacer: Adds spacing in the header to position buttons at the end. Useful when you disable SearchComponent.
  • HeaderIconButton: Adds an icon button. By default, the Self-service icon button remains enabled.
  • SupportButton: Adds a Support icon button, allowing users to configure a link to an internal or external page. Enabled by default but requires additional configuration to display.
  • NotificationButton: Adds a Notifications icon button to display unread notifications in real time and navigate to the Notifications page. Enabled by default (requires the notifications plugin).
  • Divider: Adds a vertical divider. By default, a divider is displayed between the profile dropdown and other header components.
  • ProfileDropdown: Adds a profile dropdown showing the logged-in user’s name. By default, it contains two menu items.
  • MenuItemLink: Adds a link item in a dropdown menu. By default, the profile dropdown includes a link to the Settings page.
  • LogoutButton: Adds a logout button in the profile dropdown (enabled by default).
  • CreateDropdown: Adds a Self-service dropdown button (disabled by default). The menu items are configurable.
  • SoftwareTemplatesSection: Adds a list of software template links to the Self-service dropdown menu (disabled by default). You must enable CreateDropdown.
  • RegisterAComponentSection: Adds a link to the Register a Component page in the Self-service dropdown menu (disabled by default). You must enable CreateDropdown.
config.position
Specifies the position of the header. Supported values are above-main-content and above-sidebar.

Prerequisites

  • You must install the notifications plugin to display the Notifications button in the header.

Procedure

  1. Copy the default configuration and modify the field values to suit your needs. You can adjust the priority value of each header component to control its position. Additionally, you can enable or disable components by adding or removing them from the configuration. To ensure that the remaining header buttons align with the end of the header before the profile dropdown button, set config.props.growFactor to 1 in the Spacer mount point to enable the Spacer component. For example:

    - mountPoint: global.header/component
      importName: Spacer
      config:
        priority: 100
        props:
          growFactor: 1
  2. To use your custom header, you must install it as a dynamic plugin by adding your plugin configuration to your app-config-dynamic.yaml file. For example:

    - package: <npm_or_oci_package_reference>
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            <package_name>:
              mountPoints:
                - mountPoint: application/header
                  importName: <application_header_name>
                  config:
                    position: above-main-content
                - mountPoint: global.header/component
                  importName: <header_component_name>
                  config:
                    priority: 100
                - mountPoint: global.header/component
                  importName: <header_component_name>
                  config:
                    priority: 90

    where:

    <npm_or_oci_package_reference>
    Specifies the package name.
    <application_header_name>
    Specifies the name of the application header. For example: MyHeader
    <header_component_name>

    Specifies the name of the header component. For example: MyHeaderComponent

    Note

    importName is an optional name referencing the value returned by the scaffolder field extension API.

  3. Optional: To disable the global header, set the value of the disabled field to true in your dynamic-plugins.yaml file. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header
      disabled: true
  4. Optional: To display the Support button in the header, configure the app.support.url and app.support.items fields in your app-config.yaml file. For example:

    app:
      support:
        url: https://support.example.com
        items:
          - title: Support
            links:
              - url: https://support.example.com
                title: Open a support case

9.3.3.3. Mount points for dynamic plugin integration

You can customize the application header in Developer Hub using mount points for dynamic plugins. These mount points give flexibility in configuring the position of the header, its components, and dropdown menus.

application/header
Controls the header position. Use config.position to set placement as either above-main-content or above-sidebar.
global.header/component
Configures header components. Use config.priority to set the order of components, and pass properties (including CSS styles) via config.props.
Self-service button
- mountPoint: global.header/component
  importName: HeaderIconButton
  config:
    priority: 80
    props:
      title: Self-service
      icon: add
      to: create
Spacer element
- mountPoint: global.header/component
  importName: Spacer
  config:
    priority: 99
    props:
      growFactor: 0
Divider element
mountPoints:
  - mountPoint: global.header/component
    importName: Divider
    config:
      priority: 150
global.header/profile

Configures the profile dropdown list when the ProfileDropdown component is enabled.

  • To add a settings link to the profile dropdown, use the following code:

    - mountPoint: global.header/profile
      importName: MenuItemLink
      config:
        priority: 100
        props:
          title: Settings
          link: /settings
          icon: manageAccounts
global.header/create

Configures the create dropdown list when the CreateDropdown component is enabled.

  • To add a section for registering a component, use the following code:

    - mountPoint: global.header/create
      importName: RegisterAComponentSection
      config:
        props:
          growFactor: 0

9.3.3.4. Configure the logo in the global header

You can configure a company logo in the global header of the Red Hat Developer Hub (RHDH) to reflect your company’s branding. CompanyLogo is part of the global header by default and offers full control over the theming, navigation behavior, sizing, and fallback options.

When you define menu items or links in the global header, you must specify an icon identifier.

For the full list of available icon identifiers, see Common icons for customization.

This component supports the following props, which are provided through configuration:

  • logo: The base64 encoded logo image.
  • to: The redirect path for when users click the logo is '/catalog'.
  • width: The logo width is optional and defaults to 150px.
  • height: The logo height is optional and defaults to 40px.

Procedure

  1. To display a custom company logo in the global header, update the configuration with a mount point for CompanyLogo:

    # ...rest of the global header configuration
    red-hat-developer-hub.backstage-plugin-global-header:
      mountPoints:
        - mountPoint: application/header
          importName: GlobalHeader
          config:
            # Supported values: above-main-content | above-sidebar
            position: above-main-content
    
        - mountPoint: global.header/component
          importName: CompanyLogo
          config:
            priority: 200
            props:
              # Path to navigate when users click the logo:
              to: '/catalog'
              width: 300
              height: 200
              logo: <string> or <object> # Logo can be a base64 string or theme-specific object
                # Example 1: Single logo for all themes
                # logo: "<base64_encoded_images>"
    
                # Example 2: Theme-specific logos
                # logo:
                    dark: 'data:image/png;base64,...' # Used in dark theme
                    light: 'data:image/png;base64,...' # Used in light theme
  2. (Optional) If you do not provide logo props to the CompanyLogo component, the component instead uses values defined under app.branding in your app-config.yaml file. You can configure the CompanyLogo as shown in the following configuration:

    app:
      branding:
        fullLogoWidth: 220  # Fallback width
        fullLogo: <string> or <object> #fullLogo can be a base64 string or theme-specific object
    
        # Example 1: Single logo for all themes
        #fullLogo: "<base64_encoded_image>
        # Example 2: Theme-specific logos
        #fullLogo:
            dark: 'data:image/png;base64,...' # Used in dark theme
            light: 'data:image/png;base64,...' # Used in light theme

    CompanyLogo uses the following configuration elements to control fallback and sizing behavior:

    • Logo source priority

      • The component selects the logo source in the following order:

        First, CompanyLogo props (logo, logo.light, logo.dark), then, app.branding.fullLogo. If you do not provide a logo through either, the component displays the default Developer Hub theme-specific logo.

    • Logo width priority

      • The component applies the first available value from props.width, then app.branding.fullLogoWidth from app-config.yaml. If you do not specify the width using either, the component applies a default width (150px).

        Note

        CompanyLogo preserves the images aspect ratio and never crops or distorts it. If the configured width results in a height greater than the maximum allowed (default: 40px), the image is automatically scaled down. As a result, adjusting only the width might not visibly change the logo unless the height is also configured.

        Increasing the logo height increases the height of the global header. The component first applies the value from props.height. If you do not specify the height, the component applies a default height (40px).

Verification

  1. The logo is displayed correctly in the global header.
  2. Click the logo to confirm it redirects to the path you defined in props.to.
  3. Toggle between light and dark themes to ensure the correct logo loads in each.
  4. (Optional) Temporarily remove the CompanyLogo props to test the fallback to app.branding.fullLogo.

9.3.3.5. Enable logo in the sidebar

You can configure a logo in the sidebar of the Red Hat Developer Hub (RHDH).

Procedure

  1. To display the logo exclusively in the sidebar, set the value of the app.sidebar.logo parameter to true as shown in the following example:

    app:
      sidebar:
        logo: true
    Note

    To display the logo in only the sidebar, remove the CompanyLogo component from the configuration.

  2. To display the same logo in the sidebar for all themes, update the configuration as shown in the following configuration:

    app:
      sidebar:
        logo: true
      branding:
        fullLogoWidth: 220
        fullLogo: 'data:image/svg+xml;base64,...'
  3. For theme-specific logos, you can configure the sidebar logo as shown in the following configuration:

    app:
      sidebar:
        logo: true
      branding:
        fullLogoWidth: 220
        fullLogo:
          light: 'data:image/svg+xml;base64,...'
          dark: 'data:image/svg+xml;base64,...'

Verification

  1. The logo is displayed correctly in the sidebar.
  2. Toggle between light and dark themes to ensure the correct logo loads in each.

9.3.3.6. Display the preferred username in the profile dropdown

Display the preferred username in the global header profile drop-down list by configuring spec.profile.displayName in the user entity.

Procedure

  1. To configure spec.profile.displayName, use the following code:

    apiVersion: backstage.io/v1alpha1
    kind: User
    metadata:
      # Required unique username
      name: <my_display_name>
      # Optional preferred title
      title: <display_name_title>
    spec:
      profile:
        # Optional preferred display name (highest priority)
        displayName: <my_display_name>
      memberOf: [janus-authors]
  2. To configure metadata.title rather than spec.profile.displayname, use the following code:

    apiVersion: backstage.io/v1alpha1
    kind: User
    metadata:
      # Required unique username
      name: <my_display_name>
      # Optional preferred title
      title: <display_name_title>
    spec:
      memberOf: [janus-authors]
  3. To configure neither spec.profile.displayname or metadata.title, use the following code:

    apiVersion: backstage.io/v1alpha1
    kind: User
    metadata:
      # Required unique username
      name: <my_display_name>
    spec:
      memberOf: [janus-authors]
    Note

    The application falls back to metadata.name when you do not register the user entity.

9.3.4. Configure floating action buttons for quick access to workflows

9.3.4.1. Configure floating action buttons for quick access to workflows

Configure any action as a floating button in the Developer Hub instance by using the floating action button plugin.

Important

RHDH 1.10 disables the Global Floating Action Button plugin by default. For new deployments, use the Global Header plugin, which uses quick links and starred items to improve navigation.

Existing deployments that explicitly enable the Global Floating Action Button remain functional. However, as the plugin is deprecated, it will be removed in a future RHDH version, and you must eventually adjust your configuration.

9.3.4.1.1. Additional resources

9.3.4.2. Configure a floating action button as a dynamic plugin

You can configure the floating action button as a dynamic plugin to perform actions or open an internal or external link.

Procedure

  1. Specify the global.floatingactionbutton/config mount point in your app-config-dynamic.yaml file. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # Start of the floating action button configuration
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
              # End of the floating action button configuration
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    frontend:mountPoints:importName
    (Required) The import name with an associated component to the mount point.
    frontend:mountPoints:importName:icon
    Use the svg value to display a black BulkImportPage icon.
  2. To configure an action as a floating action button that opens an external link, specify the global.floatingactionbutton/config mount point in your dynamic-plugins.yaml file within the backstage-plugin-global-floating-action-button plugin. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-global-floating-action-button:
              mountPoints:
                  - mountPoint: application/listener
                    importName: DynamicGlobalFloatingActionButton
                  - mountPoint: global.floatingactionbutton/config
                    importName: NullComponent
                    config:
                      icon: '<svg viewBox="0 0 250 300" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M200.134 0l55.555 117.514-55.555 117.518h-47.295l55.555-117.518L152.84 0h47.295zM110.08 99.836l20.056-38.092-2.29-8.868L102.847 0H55.552l48.647 102.898 5.881-3.062zm17.766 74.433l-17.333-39.034-6.314-3.101-48.647 102.898h47.295l25-52.88v-7.883z" fill="#40B4E5"/><path d="M152.842 235.032L97.287 117.514 152.842 0h47.295l-55.555 117.514 55.555 117.518h-47.295zm-97.287 0L0 117.514 55.555 0h47.296L47.295 117.514l55.556 117.518H55.555z" fill="#003764"/></svg>'
                      label: 'Quay'
                      showLabel: true
                      toolTip: 'Quay'
                      to: 'https://quay.io'
                  - mountPoint: global.floatingactionbutton/config
                    importName: NullComponent
                    config:
                      icon: github
                      label: 'Git'
                      toolTip: 'Github'
                      to: https://github.com/redhat-developer/rhdh-plugins
    frontend:mountPoints:importName
    Enter the import name with an associated component to the mount point.
    frontend:mountPoints:importName:icon
    (Optional) Enter the icon in Scalable Vector Graphics (SVG) format to display the Quay icon.
  3. To configure a floating action button that contains a submenu, define the global.floatingactionbutton/config mount point in the same slot field in your dynamic-plugins.yaml file for multiple actions. The default slot is page-end when not specified. For example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # Start of fab config
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
              # end of fab config
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    
    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-global-floating-action-button:
              mountPoints:
                - mountPoint: application/listener
                  importName: DynamicGlobalFloatingActionButton
                - mountPoint: global.floatingactionbutton/config
                  importName: NullComponent
                  config:
                    icon: github
                    label: 'Git'
                    toolTip: 'Github'
                    to: https://github.com/redhat-developer/rhdh-plugins
                - mountPoint: global.floatingactionbutton/config
                  importName: NullComponent
                  config:
                    icon: '<svg viewBox="0 0 250 300" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M200.134 0l55.555 117.514-55.555 117.518h-47.295l55.555-117.518L152.84 0h47.295zM110.08 99.836l20.056-38.092-2.29-8.868L102.847 0H55.552l48.647 102.898 5.881-3.062zm17.766 74.433l-17.333-39.034-6.314-3.101-48.647 102.898h47.295l25-52.88v-7.883z" fill="#40B4E5"/><path d="M152.842 235.032L97.287 117.514 152.842 0h47.295l-55.555 117.514 55.555 117.518h-47.295zm-97.287 0L0 117.514 55.555 0h47.296L47.295 117.514l55.556 117.518H55.555z" fill="#003764"/></svg>'
                    label: 'Quay'
                    showLabel: true
                    toolTip: 'Quay'
                    to: 'https://quay.io'
    frontend:mountPoints:importName
    (Required) The import name with an associated component to the mount point.
  4. To configure a floating action button to display only on specific pages, configure the global.floatingactionbutton/config mount point in the backstage-plugin-global-floating-action-button plugin and set the visibleOnPaths property as shown in the following example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # start of fab config
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage 1
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
                    visibleOnPaths: ['/catalog', '/settings']
              # end of fab config
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    frontend:mountPoints:importName
    Enter the import name with an associated component to the mount point.
  5. To hide a floating action button on specific pages, configure the global.floatingactionbutton/config mount point in the backstage-plugin-global-floating-action-button plugin and set the excludeOnPaths property as shown in the following example:

    - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
      disabled: false
      pluginConfig:
        dynamicPlugins:
          frontend:
            red-hat-developer-hub.backstage-plugin-bulk-import:
              # start of fab config
              mountPoints:
                - mountPoint: global.floatingactionbutton/config
                  importName: BulkImportPage 1
                  config:
                    slot: 'page-end'
                    icon: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>
                    label: 'Bulk import'
                    toolTip: 'Register multiple repositories in bulk'
                    to: /bulk-import/repositories
                    excludeOnPaths: ['/bulk-import']
              # end of fab config
              appIcons:
                - name: bulkImportIcon
                  importName: BulkImportIcon
              dynamicRoutes:
                - path: /bulk-import/repositories
                  importName: BulkImportPage
                  menuItem:
                    icon: bulkImportIcon
                    text: Bulk import
    frontend:mountPoints:importName
    Enter the import name with an associated component to the mount point.
  6. To configure translation support for the floating action button, use translation keys instead of static text. The Global Floating Action Button plugin supports internationalization (i18n) through the labelKey and toolTipKey properties.

    Example for using translation keys in dynamic configuration:

- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
  disabled: false
  pluginConfig:
    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-global-floating-action-button:
          translationResources:
            - importName: globalFloatingActionButtonTranslations
              ref: globalFloatingActionButtonTranslationRef
          mountPoints:
            - mountPoint: application/listener
              importName: DynamicGlobalFloatingActionButton
            - mountPoint: global.floatingactionbutton/config
              importName: NullComponent
              config:
                icon: github
                label: 'GitHub' # Fallback text
                labelKey: 'fab.github.label' # Translation key
                toolTip: 'GitHub Repository' # Fallback text
                toolTipKey: 'fab.github.tooltip' # Translation key
                to: https://github.com/redhat-developer/rhdh-plugins
            - mountPoint: global.floatingactionbutton/config
              importName: NullComponent
              config:
                color: 'success'
                icon: search
                label: 'Create' # Fallback text
                labelKey: 'fab.create.label' # Translation key
                toolTip: 'Create entity' # Fallback text
                toolTipKey: 'fab.create.tooltip' # Translation key
                to: '/create'
                showLabel: true

9.3.4.3. Floating action button localization support

You can enable translation key support for floating action buttons, so that users can onboard in their preferred language. In Developer Hub, all existing and newly created floating action buttons support localization by using dedicated translation keys.

The Global Floating Action Button plugin supports internationalization (i18n) through translation keys. You can use labelKey and toolTipKey properties to provide translation keys instead of static text.

The plugin provides the following built-in translation keys organized under the fab namespace:

  • fab.create.label - "Create"
  • fab.create.tooltip - "Create entity"
  • fab.docs.label - "Docs"
  • fab.docs.tooltip - "Documentation"
  • fab.apis.label - "APIs"
  • fab.apis.tooltip - "API Documentation"
  • fab.github.label - "GitHub"
  • fab.github.tooltip - "GitHub Repository"
  • fab.bulkImport.label - "Bulk Import"
  • fab.bulkImport.tooltip - "Register multiple repositories in bulk"
  • fab.quay.label - "Quay"
  • fab.quay.tooltip - "Quay Container Registry"

The plugin includes translations for the following supported languages:

  • English (default)
  • French (fr)
  • German (de)
  • Italian (it)
  • Japanese (ja)
  • Spanish (es)

To ensure backward compatibility while providing translation support when available, the following order is used to resolve string translations:

  1. If the labelKey is provided, the plugin will attempt to resolve the translation key
  2. If the translation key is found, it will be used as the label
  3. If the translation key is not found, the plugin will fall back to the label property
Note

The same logic applies to toolTipKey and toolTip.

9.3.4.4. Internal translation implementation

The plugin uses a centralized translation system where:

  • The useTranslation() hook is called in components that render floating action buttons to ensure proper translation context initialization
  • The translation function (t) is passed down to child components that need to resolve translation keys
  • This internal architecture prevents infinite re-render loops and ensures stable component rendering
  • All components that use CustomFab must provide the translation function as a prop
Note

When extending or modifying the plugin components, ensure that the useTranslation() hook is called in parent components and the t prop is passed to CustomFab instances to maintain proper translation functionality and prevent rendering issues.

9.3.4.5. Floating action button parameters

The floating action button plugin supports various parameters for configuring label, icon, size, color, actions, tooltips, priority, and visibility.

NameDescriptionTypeDefault valueRequired

slot

Position of the floating action button. Valid values: PAGE_END, BOTTOM_LEFT

enum

PAGE_END

No

label

Name of the floating action button

String

Not applicable

Yes

labelKey

Translation key for the label. If provided, will be used instead of label when translations are available.

String

Not applicable

No

icon

Icon of the floating action button. Recommended to use filled icons from the Material Design library. You can also use an SVG icon. For example: <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#e8eaed"><g><rect fill="none" height="24" width="24"/></g><g><path d="M11,7L9.6,8.4l2.6,2.6H2v2h10.2l-2.6,2.6L11,17l5-5L11,7z M20,19h-8v2h8c1.1,0,2-0.9,2-2V5c0-1.1-0.9-2-2-2h-8v2h8V19z"/></g></svg>

String, React.ReactElement, SVG image icon, HTML image icon

Not applicable

No

showLabel

Display of the label next to your icon

Boolean

Not applicable

No

size

Size of the floating action button

small, medium, large

medium

No

color

Color of the component. It supports both default and custom theme colors, that are added from the Palette Getting started guide.

default, error, info, inherit, primary, secondary, success, warning

default

No

onClick

Performed action when selecting a floating action button

React.MouseEventHandler

Not applicable

No

to

Link that opens when selecting a floating action button

String

Not applicable

No

toolTip

Text that is displayed when hovering over a floating action button

String

Not applicable

No

toolTipKey

Translation key for the tooltip. If provided, will be used instead of toolTip when translations are available.

String

Not applicable

No

priority

Order of the floating action buttons displayed in the submenu. A larger value means higher priority.

number

Not applicable

No

visibleOnPaths

Display floating action button on the specified paths

string[]

Display floating action button on all paths

No

excludeOnPaths

Hide floating action button on the specified paths

string[]

Display floating action button on all paths

No

Note

If multiple floating button actions are assigned to the same slot value, the floating buttons are displayed as submenu options within the main floating action button.

9.3.5. Customize the Quick Start to guide user onboarding

9.3.5.1. Customize the Quick Start to guide user onboarding

The quick start plugin provides guided onboarding for Red Hat Developer Hub users through customizable, interactive steps that help users get familiar with the platform.

9.3.5.2. About quick starts

The quick start plugin provides guided onboarding for users of Red Hat Developer Hub. It displays a customizable drawer interface with interactive quick start steps that help users get familiar with the platform.

Note

If RBAC is not enabled, quick start is only accessible to users with administrator permissions.

The quick start plugin is enabled by default and includes the following components:

Set up authentication
Set up secure login credentials to protect your account from unauthorized access.
Configure RBAC
Assign roles and permissions to control who can view, create, or edit resources, ensuring secure and efficient collaboration.
Configure Git
Connect your Git providers, such as GitHub to manage code, automate workflows, and integrate with platform features.
Manage plugins
Browse and install extensions to add features, connect to external tools, and customize your experience.

9.3.5.3. Configure role-based access control for quick starts

You can control which users see specific quick start guides by configuring role-based access control (RBAC) for quick starts in your app-config.yaml file.

Prerequisites

  • You have configured RBAC in RHDH.

Procedure

  1. Enable RBAC in your app-config.yaml file:

    permission:
      enabled: true

    When RBAC is enabled, the system determines user roles based on permissions:

    • Users with policy.entity.create permission are assigned the admin role.
    • Users without this permission are assigned the developer role.

      Note

      If RBAC is disabled (permission.enabled: false) or not configured, users are assumed to be platform engineers setting up Red Hat Developer Hub (RHDH) and are assigned the admin role.

  2. Configure quick start items with role assignments in your app-config.yaml file:

    app:
      quickstart:
        - title: 'Platform Configuration'
          titleKey: steps.platformConfiguration.title
          roles: ['admin']
          # Only admins see this
        - title: 'Getting Started as Developer'
          titleKey: steps.gettingStarted.title
          roles: ['developer']
          # Only developers see this
        - title: 'Universal Welcome Guide'
          titleKey: steps.universalWelcome.title
          roles: ['admin', 'developer']
          # Both user roles see this

    The following roles are supported:

    admin
    Platform engineers, administrators, and users with elevated permissions
    developer

    Regular developers and users with standard permissions

    Note

    Quick start items without a roles property default to the admin role. Items can specify multiple roles, and users see quick start items that match their assigned role.

9.3.5.4. Customize your Red Hat Developer Hub quick start

As an administrator, you can configure the Red Hat Developer Hub quick start plugin to create customized onboarding for your Developer Hub users.

Procedure

  • Update your app-config.yaml with the following code:

    app:
      quickstart:
        - title: 'Welcome to Developer Hub'
          description: 'Learn the basics of navigating the Developer Hub interface'
          icon: 'home'
          roles: ['admin', 'developer'] # Show to both roles
          cta:
            text: 'Get Started'
            link: '/catalog'
        - title: 'Create Your First Component'
          description: 'Follow our guide to register your first software component'
          icon: 'code'
          roles: ['admin', 'developer'] # Show to both roles
          cta:
            text: 'Create Component'
            link: '/catalog-import'
        - title: 'Explore Templates'
          description: 'Discover available software templates to bootstrap new projects'
          icon: 'template'
          roles: ['admin', 'developer'] # Show to both roles
          cta:
            text: 'Browse Templates'
            link: '/create'

    where:

    title
    Enter the display title for the quick start step.
    description
    Enter the brief description of what the step covers.
    icon

    (Optional) Enter the icon identifier. You can use a full image URL, a valid SVG path, or one of the following common keys:

    For a list of supported icons you can use in your quick start definitions, see Common icons for customization.

9.3.5.5. Disable the quick start plugin

You can disable the quick start plugin if you do not want to use guided onboarding steps in your Developer Hub instance.

Procedure

  • To disable the quick start plugin, set the disabled property to true as shown in the following code:

    global:
      dynamic:
        includes:
          - dynamic-plugins.default.yaml
        plugins:
          - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-quickstart
            disabled: true

9.3.5.6. Use quick start onboarding steps

You can use the quick start onboarding steps to learn more about the administrator features of RHDH.

Prerequisites

  • (Optional) If RBAC is enabled, you must have administrator permissions to access to the quick start feature.

Procedure

  1. In your RHDH navigation menu, click the Help (?) icon.
  2. In the dropdown menu, click Quick start.
  3. Select the quick start step that you want to begin.
  4. To close the quick start drawer, click Hide.

    About quick starts
    Note

    Your overall progress is tracked and displayed as a progress bar and a progress percentage in the quick start footer.

9.3.5.7. Enable quick start localization in RHDH

Enable translation key support for quick start titles, descriptions, and CTAs so that users can onboard in their preferred language.

Note

If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the quick start configuration (title, description, text). If no translation key is defined at all, the original text is displayed.

Prerequisites

  • You have enabled localization in your RHDH application.

Procedure

  1. For all quick start steps (both existing and new) in your configuration file, you must define both the original text and the new localization keys. For example, in the quickstart section of your custom app-config.yaml file, add the titleKey, descriptionKey, and textKey values, as follows:

    app-config.yaml fragment

    app:
      quickstart:
        # Existing quick start steps should also be updated with keys
        - title: 'Setup Authentication'
          titleKey: steps.setupAuth.title
          description: 'Learn the basics of navigating the {product-short} interface'
          descriptionKey: steps.setupAuth.description
          icon: 'home'
          cta:
            text: 'Get Started'
            textKey: steps.setupAuth.ctaTitle
            link: '/catalog'
    # ...

    where:

    title
    (Mandatory) Fallback for the title.
    titleKey
    Key for the translated title.
    description
    (Mandatory) Fallback for the description.
    descriptionKey
    Key for the translated description.
    text
    (Mandatory) Fallback for the CTA text.
    textKey
    Key for the translated CTA text.
  2. In your dynamic-plugins.yaml file, add the translationResources section to your red-hat-developer-hub-backstage-plugin-quickstart configuration, as follows:

    app-config.yaml fragment

    plugins:
      - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-quickstart
          disabled: false
          pluginConfig:
            dynamicPlugins:
              frontend:
                red-hat-developer-hub.backstage-plugin-quickstart:
                  # translationResources definition is required for translations to work
                  translationResources:
                    - importName: quickstartTranslations
                      ref: quickstartTranslationRef
                  # ... other configurations like mountPoints ...

    where:

    importName
    Enter the name used to reference the import.
    ref
    Reference to the resource definition.
  3. In your translation file, map the keys from the first step to the localized strings for each supported language.

    allTranslations.json fragment

    "plugin.quickstart": {
      "en": {
        "steps.setupAuth.title": "Manage plugins EN",
        "steps.setupAuth.description": "EN Browse and install extensions to add features, connect with external tools, and customize your experience.",
        "steps.setupAuth.ctaTitle": "Start"
      },
      "fr": {
        "steps.setupAuth.title": "Gérer les plugins FR",
        "steps.setupAuth.description": "FR Parcourez et installez des extensions pour ajouter des fonctionnalités, vous connecter à des outils externes et personnaliser votre expérience.",
        "steps.setupAuth.ctaTitle": "Commencer"
      }
    }

9.3.6. Customize the Tech Radar page to visualize technology adoption

9.3.6.1. Customize the Tech Radar page to visualize technology adoption

In Red Hat Developer Hub, the Tech Radar page is provided by the tech-radar dynamic plugin, which is disabled by default. For information about enabling dynamic plugins in Red Hat Developer Hub see Configuring dynamic plugins.

In Red Hat Developer Hub, you can configure Learning Paths by passing the data into the app-config.yaml file as a proxy. The base Tech Radar URL must include the /developer-hub/tech-radar proxy.

Note

Due to the use of overlapping pathRewrites for both the tech-radar and homepage quick access proxies, you must create the tech-radar configuration (^api/proxy/developer-hub/tech-radar) before you create the homepage configuration (^/api/proxy/developer-hub).

You can provide data to the Tech Radar page from the following sources:

  • JSON files hosted on GitHub or GitLab.
  • A dedicated service that provides the Tech Radar data in JSON format using an API.

9.3.6.2. Customize the Tech Radar page by using a JSON file

For ease of use and simplicity, you can configure the Tech Radar page by using a hosted JSON file.

Prerequisites

  • You have specified the data sources for the Tech Radar plugin in the integrations section of the app-config.yaml file. For example, you have enabled Developer Hub integration with GitHub.
  • You have enabled the ./dynamic-plugins/dist/backstage-community-plugin-tech-radar and /dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamic plugins.

Procedure

  1. Publish the JSON file containing your Tech Radar data to a web server, such as GitHub or GitLab. You can find an example at https://raw.githubusercontent.com/backstage/community-plugins/main/workspaces/tech-radar/plugins/tech-radar-common/src/sampleTechRadarResponse.json.
  2. Configure Developer Hub to access the Tech Radar data from the hosted JSON files, by adding the following to the app-config.yaml file:

    techRadar:
      url: <tech_radar_data_url>
    <tech_radar_data_url>
    Enter the Tech Radar data hosted JSON URL.

9.3.6.3. Customize the Tech Radar page by using a customization service

For advanced scenarios, you can host your Red Hat Developer Hub customization service to offer data to all configurable Developer Hub pages, such as the Tech Radar page. You can even use a different service for each page.

Prerequisites

  • You have specified the data sources for the Tech Radar plugin in the integrations section of the app-config.yaml file. For example, you have enabled Developer Hub integration with GitHub.
  • You have enabled the ./dynamic-plugins/dist/backstage-community-plugin-tech-radar and /dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamic plugins.

Procedure

  1. Deploy your Developer Hub customization service on the same OpenShift Container Platform cluster as your Developer Hub instance. You can find an example at red-hat-developer-hub-customization-provider, that provides the same data as default Developer Hub data. The customization service provides a Tech Radar data URL such as: http://<rhdh-customization-provider>/tech-radar.
  2. Add the dedicated service as an allowed host by adding the following code to the app-config.yaml file:

    backend:
       reading:
            allow:
              - host: '<rhdh_customization_provider_base_url>'
    <rhdh_customization_provider_base_url>
    Enter the base URL of your Tech Radar data URL, such as: <rhdh-customization-provider>.
  3. Add the following to the app-config.yaml file:

    techRadar:
        url: <tech_radar_data_url>
    <tech_radar_data_url>
    Enter your Tech Radar data URL, such as: http://<rhdh-customization-provider>/tech-radar.

9.3.7. Customize themes and branding to align with corporate standards

9.3.7.1. Customize themes and branding to align with corporate standards

By modifying the visual aspects of the interface, organizations can align Red Hat Developer Hub with their branding guidelines and improve the overall user experience.

The following default theme configurations are available for Red Hat Developer Hub:

The Red Hat Developer Hub theme
Default theme configurations to make your developer portal look like a standard Red Hat Developer Hub instance.
The Backstage theme
Default theme configurations to make your developer portal look like a standard Backstage instance.

You can change or disable particular parameters in a default theme or create a fully customized theme by modifying the app-config.yaml file. From the app-config.yaml file, you can customize common theme components, including the following components:

  • Company name and logo
  • Font color, size, and style of text in paragraphs, headings, headers, and buttons
  • Header color, gradient, and shape
  • Button color
  • Navigation indicator color

You can also customize some components from the Developer Hub GUI, such as the theme mode (Light Theme, Dark Theme, or Auto).

9.3.7.2. Switch the theme mode for your Developer Hub instance

You can switch the RHDH interface between light, dark, or auto mode (which matches your system preference).

Note

In RHDH, theme configurations are used to change the look and feel of different UI components. So, you might notice changes in different UI components, such as buttons, tabs, sidebars, cards, and tables along with some changes in background color and font used on the RHDH pages.

Prerequisites

  • You are logged in to the RHDH web console.

Procedure

  1. From the Developer Hub web console, click Settings.
  2. From the Appearance panel, select Light, Dark, or Auto to change the theme mode.

    Theme mode selection in the Appearance panel

Verification

  • The interface immediately updates to reflect the selected theme.

9.3.7.3. Customize the branding logo of your Developer Hub instance

You can customize the branding logo of your Developer Hub instance by configuring the branding section in the app-config.yaml file.

Procedure

  • Customize the branding logo by configuring the branding section in the app-config.yaml file:

    app:
      branding:
        fullLogo: ${BASE64_EMBEDDED_FULL_LOGO}
        iconLogo: ${BASE64_EMBEDDED_ICON_LOGO}
    fullLogo
    Enter the logo on the expanded (pinned) sidebar as a base64 encoded image.
    iconLogo

    Enter the logo on the collapsed (unpinned) sidebar as a base64 encoded image.

    You can format the BASE64_EMBEDDED_FULL_LOGO environment variable as follows:

    BASE64_EMBEDDED_FULL_LOGO: "data:_<media_type>_;base64,<base64_data>"

    The following example demonstrates how to customize the BASE64_EMBEDDED_FULL_LOGO by using the data:_<media_type>_;base64,<base64_data> format:

    SVGLOGOBASE64=$(base64 -i logo.svg)
    BASE64_EMBEDDED_FULL_LOGO="data:image/svg+xml;base64,$SVGLOGOBASE64"

    Replace image/svg+xml with the correct media type for your image (for example, image/png and image/jpeg), and adjust the file extension accordingly. As a result, you can embed the logo directly without referencing an external file.

    You can also customize the width of the branding logo by setting a value for the fullLogoWidth field in the branding section, as shown in the following example:

    app:
      branding:
        fullLogoWidth: 110px
    # ...
    fullLogoWidth
    The default value for the logo width is 110px. The following units are supported: integer, px, em, rem, percentage.

9.3.7.4. Customize the theme mode color palettes for your Developer Hub instance

You can customize the color palettes of the light and dark theme modes in your Developer Hub instance by configuring the light.palette and dark.palette parameters in the branding.theme section of the app-config.yaml file.

Procedure

  • Configure the light.palette and dark.palette parameters in the branding.theme section of the app-config.yaml file:

    app:
      branding:
        theme:
          light:
            palette:
              primary:
                main: <light_primary_color>
              navigation:
                indicator: <light_indicator_color>
            pageTheme:
              default:
                backgroundColor: [<light_background_color_1>, <light_background_color_2>]
          dark:
            palette:
              primary:
                main: <dark_primary_color>
              navigation:
                indicator: <dark_indicator_color>
            pageTheme:
              default:
                backgroundColor: [<dark_background_color_1>, <dark_background_color_2>]
    # ...
    light|dark

    Enter the theme name: light or dark.

    palette.primary:main
    Enter the palette main primary color, such as #ffffff or white.
    palette.navigation:indicator
    Enter the palette navigation indicator color, which is a vertical bar that indicates the selected tab in the navigation panel, such as #FF0000 or red.
    pageTheme:default:backgroundColor
    Enter the default page theme background color, such as #ffffff or white.

9.3.7.5. Customize the page theme header for your Developer Hub instance

Customize the header color for the light and dark theme modes in your Developer Hub instance by modifying the branding.theme section of the app-config.yaml file.

Procedure

  • Modify the branding.theme section of the app-config.yaml file:

    app:
      branding:
        theme:
          light:
            palette: {}
            pageTheme:
              default:
                backgroundColor: "<default_light_background_color>"
                fontColor: "<default_light_font_color>"
                shape: none
              apis:
                backgroundColor: "<apis_light_background_color>"
                fontColor: "<apis_light_font_color>"
                shape: none
          dark:
            palette: {}
            pageTheme:
              default:
                backgroundColor: "<default_dark_background_color>"
                fontColor: "<default_dark_font_color>"
                shape: none
    # ...
    light
    Enter the theme mode, such as light or dark.
    default

    Enter the default page theme configuration

    backgroundColor
    Enter the page header background color, such as #ffffff or white.
    fontColor
    Enter the page header text color, such as #000000 or black.
    shape
    Enter the page header pattern, such as wave, round, or none. apis:: Enter the page id to configure, such as apis or home.

9.3.7.6. Customize the font for your Developer Hub instance

You can configure the typography section of the app-config.yaml file to change the default font family and size of the page text, as well as the font family and size of each heading level.

Procedure

  • Configure the typography section of the app-config.yaml file:

    app:
      branding:
        theme:
          light:
            typography:
              fontFamily: "Times New Roman"
              htmlFontSize: 11 # smaller is bigger
              h1:
                fontFamily: "Times New Roman"
                fontSize: 40
              h2:
                fontFamily: "Times New Roman"
                fontSize: 30
              h3:
                fontFamily: "Times New Roman"
                fontSize: 30
              h4:
                fontFamily: "Times New Roman"
                fontSize: 30
              h5:
                fontFamily: "Times New Roman"
                fontSize: 30
              h6:
                fontFamily: "Times New Roman"
                fontSize: 30
          dark:
            typography:
              fontFamily: "Times New Roman"
              htmlFontSize: 11 # smaller is bigger
              h1:
                fontFamily: "Times New Roman"
                fontSize: 40
              h2:
                fontFamily: "Times New Roman"
                fontSize: 30
              h3:
                fontFamily: "Times New Roman"
                fontSize: 30
              h4:
                fontFamily: "Times New Roman"
                fontSize: 30
              h5:
                fontFamily: "Times New Roman"
                fontSize: 30
              h6:
                fontFamily: "Times New Roman"
                fontSize: 30
    # ...

9.3.7.7. Load a custom Developer Hub theme by using a dynamic plugin

You can load a custom Developer Hub theme from a dynamic plugin.

Procedure

  1. Export a theme provider function in your dynamic plugin, for example:

    import { lightTheme } from './lightTheme'; // some custom theme
    import { UnifiedThemeProvider } from '@backstage/theme';
    export const lightThemeProvider = ({ children }: { children: ReactNode }) => (
      <UnifiedThemeProvider theme={lightTheme} children={children} />
    );

    For more information about creating a custom theme, see Backstage documentation - Creating a Custom Theme.

  2. Configure Developer Hub to load the theme in the UI by using the themes configuration field:

    dynamicPlugins:
      frontend:
        example.my-custom-theme-plugin:
          themes:
            - id: light
              title: Light
              variant: light
              icon: someIconReference
              importName: lightThemeProvider
    id
    Enter your theme ID, such as my_theme. Enter dark to override the default Developer Hub dark theme. Enter light to override the default Developer Hub light theme.

Verification

  • The theme is available in the Developer Hub Settings page.

9.3.7.8. Custom component options for your Developer Hub instance

You can use two component variants (Patternfly or MUI) to customize various components of your Developer Hub theme.

  • Patternfly
  • MUI

In addition to assigning a component variant to each parameter in the light or dark theme mode configurations, you can toggle the rippleEffect on or off.

The following code shows the options that you can use in the app-config.yaml file to configure the theme components for your Developer Hub instance:

app:
  branding:
    theme:
      light:
        options:
          rippleEffect: off / on
          paper: patternfly / mui
          buttons: patternfly / mui
          inputs: patternfly / mui
          accordions: patternfly / mui
          sidebars: patternfly / mui
          pages: patternfly / mui
          headers: patternfly / mui
          toolbars: patternfly / mui
          dialogs: patternfly / mui
          cards: patternfly / mui
          tables: patternfly / mui
          tabs: patternfly / mui
      dark:
        options:
          rippleEffect: off / on
          paper: patternfly / mui
          buttons: patternfly / mui
          inputs: patternfly / mui
          accordions: patternfly / mui
          sidebars: patternfly / mui
          pages: patternfly / mui
          headers: patternfly / mui
          toolbars: patternfly / mui
          dialogs: patternfly / mui
          cards: patternfly / mui
          tables: patternfly / mui
          tabs: patternfly / mui

9.3.8. Customize sidebar navigation and tabs to organize essential tools

9.3.8.1. Customize sidebar navigation and tabs to organize essential tools

You can customize navigation elements in Red Hat Developer Hub, including sidebar menu items, entity tab titles, and entity detail tab layouts.

9.3.8.3. Customize the sidebar menu items

9.3.8.3.1. Customize the sidebar menu items

TODO: Replace this placeholder with an overview of Customize the sidebar menu items.

9.3.8.3.2. Enable sidebar menu items localization in RHDH

You can add translation key support for sidebar menu items, so that users can onboard in their preferred language. In Developer Hub, all existing and newly created sidebar menu items support localization by using the titleKey translation key.

Note

If a translation key is present but the corresponding localized string is missing, the system defaults to the original text defined in the sidebar menu items configuration (title). If no translation key is defined at all, the original text is displayed.

Prerequisites

  • You have enabled localization in your RHDH application.

Procedure

  1. For sidebar menu items in your configuration file, you must define both the original text and the new localization keys. For example, in the dynamicPlugins.frontend.default.main-menu-items.menuItems.default.favorites section of your app-config.yaml file, add the titleKey, as follows:

    dynamicPlugins:
      frontend:
        default.main-menu-items:
            menuItems:
              default.favorites:
                title: Favorites
                titleKey: menuItem.favorites
                icon: favorite
                priority: 100
                enabled: true
  2. In your translation file, map the titleKey from the first step to the localized strings for each supported language.

    {
      "rhdh": {
        "en": {
          "menuItem.favorites": "Favorites"
        },
        "fr": {
          "menuItem.favorites": "Favoris"
        }
      }
    }
9.3.8.3.3. Configure a dynamic plugin menu item for your Developer Hub instance

You can configure dynamic plugin menu items to customize the sidebar navigation for your Developer Hub instance.

Procedure

  • In the app-config.yaml file, update the menuItems section of your <plugin_name> plugin. For example:

    dynamicPlugins:
      frontend:
        <plugin_name>:
          menuItems:
            <menu_item_name>:
              icon: # home | group | category | extension | school | <my_icon>
              title: <plugin_page_title>
              priority: 10
              parent: favorites
              enabled: true
    <plugin_name>
    Enter the plugin name. This name is the same as the scalprum.name key in the package.json file.
    <menu_item_name>
    Enter a unique name in the main sidebar navigation for either a standalone menu item or a parent menu item. If this field specifies a plugin menu item, the name of the menu item must match the name by using in the corresponding path in dynamicRoutes. For example, if dynamicRoutes defines path: /my-plugin, then menu_item_name must be defined as my-plugin.
    icon

    (Optional) Enter the icon name. You can use any of the following icons:

    • Default icons, such as home, group, category, extension, and school. To use default icons, set the icon as an (" ") empty string.
    • A custom icon, where <my_icon> specifies the name of your custom icon
    • An SVG icon, such as: icon: <svg width="20px" height="20px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" fill="#ffffff">…​</svg>
    • An HTML image, such as: icon: https://img.icons8.com/ios-glyphs/20/FFFFFF/shop.png
    title
    (Optional) Enter the menu item title. Omit it when the title is already specified in the dynamicRoutes configuration under menuItem.text. To hide the title from the sidebar, set the title as an (" ") empty string.
    priority
    (Optional) Enter an integer value to set the order in which menu items appear in the sidebar.
    parent
    (Optional) Enter the parent menu item under which the current item is nested. If this field is used, the parent menu item must be defined elsewhere in the menuItems configuration of any enabled plugin. You can define this field for each section.
    enabled
    (Optional) Enter false to hide the menu item from the sidebar. Enter true to display the menu item in the sidebar.
    dynamicPlugins:
      frontend:
        <package_name>:
          dynamicRoutes:
            - path: </my-plugin>
              module: CustomModule
              importName: <my_plugin>PluginPage
              menuItem:
                icon: # home | group | category | extension | school | <my_icon>
                text: <my-plugin label>
          menuItems:
            my-plugin:
              priority: 10
              parent: favorites
            favorites:
              icon: favorite
              title: Favorites
              priority: 100
    my-plugin
    Enter the value of the path field in dynamicRoutes.
    priority
    Enter an integer value to set the order in which plugins appear in the parent menu item.
    parent
    Enter the parent menu item id to nest this plugin under, such as favorites.
    favorites
    Configuration for the parent menu item.
    title
    Displays the title name for the parent menu item.
9.3.8.3.4. Modify or add a custom menu items for your Developer Hub instance

You can modify existing main menu items or add custom menu items to the sidebar navigation for your Developer Hub instance.

Procedure

  • In the app-config.yaml file, add a section to the default.main-menu-items > menuItems section. Use the default. prefix to identify the key as a main menu item.

    dynamicPlugins:
      frontend:
        default.main-menu-items:
          menuItems:
            default._<menu_group_parent_item_name>_:
              icon: # home | group | category | extension | school | _<my_icon>_
              title: _<menu_group_parent_title>_
              priority: 10
            default._<menu_item_name>_:
              parent: _<menu_group_parent_item_name>_
              icon:  # home | group | category | extension | school | _<my_icon>_
              title: _<my_menu_title>_
              to: _<path_to_the_menu_target_page>_
              priority: 100
              enabled: true
    default.<menu_group_parent_item_name>
    (Optional) Enter the menu group parent item name to configure static main menu items. If no default.<menu_item_name> has a parent value set, this field is not needed.
    icon
    Enter the menu icon. Required for parent menu items.
    title
    Enter the menu group title. Required for parent menu items.
    priority
    (Optional) Enter the order of this menu item within its menu level.
    default.<menu_item_name>
    Enter the menu item name for which you want to override the default value. Add the default. prefix to identify a main menu item.
    parent
    (Optional) Enter the parent menu item for this item. Required if <menu_item_name> is specified as the child of any menu items.
    icon
    (Optional) Enter the menu icon. To use the default icon, set the icon as an (" ") empty string.
    title
    (Optional) Enter the menu group title. Only required for adding a new custom main menu item. To hide a default main menu item title from the sidebar, set the title as an (" ") empty string.
    to
    (Optional) Enter the path that the menu item navigates to. If it is not set, it defaults to the home page.
    priority
    (Optional) Enter the order of this menu item within its menu level.
    enabled
    (Optional) If this field is used to display the menu item in the sidebar, set the value to true. To hide the menu item from the sidebar, set the value to false.
    default.main-menu-items:
          menuItems:
            default.catalog:
              icon: category
              title: My Catalog
              priority: 5
            default.learning-path:
              title: ''
            default.parentlist:
              title: Overview
              icon: bookmarks
            default.home:
              parent: default.parentlist
            default.references:
              title: References
              icon: school
              to: /references
              enabled: true
    icon
    (Optional) Enter the icon name, such as category, bookmarks`, school, and so on to change the default icon.
    title
    Enter an empty string '' to hide the learning path from the default sidebar.
    default.parentlist
    Enter the parent menu items.
    parent
    Enter the parent menu under which to nest the menu entry, such as default.parentlist.
    title
    Enter the menu entry name, such as My Catalog, Overview or References.
    to
    Enter the page to redirect to. For example, default.references redirects to the /references page.
    enabled
    (Optional) Enter true to display the menu item in the sidebar. Enter false to hide the menu item from the sidebar.

9.3.8.4. Configure entity tab titles

Red Hat Developer Hub provides a default opinionated tab set for catalog entity views. For consistency with your organization needs, you can rename, reorder, remove, and add tab titles.

Procedure

  • For each tab to modify, enter your required values in the entityTabs section in your app-config.yaml file:

    upstream:
      backstage:
        appConfig:
          dynamicPlugins:
            frontend:
             <plugin_name>:
                entityTabs:
                  - mountPoint: <mount_point>
                    path: <path>
                    title: <title>
                    priority: <priority>
    <plugin_name>
    Enter the plugin name, such as backstage-community.plugin-topology.
    mountPoint
    Enter the tab mount point, such as entity.page.topology.
    path
    Enter the tab path, such as /topology.
    title
    Enter the tab title, such as Topology.
    priority

    Optional.

    To reorder tabs, enter the tab priority, such as 42. Higher priority is displayed first.

    To remove a tab, enter a negative value, such as -1.

9.3.8.5. Configure entity detail tab layout

Each Red Hat Developer Hub entity detail tab has a default opinionated layout. For consistency with your organization needs, you can change the entity detail tab content when the plugin that contributes the tab content allows a configuration.

Prerequisites

  • The plugin that contributes the tab content can be configured to extend the default inherited configuration.

Procedure

  • Copy the plugin default configuration in your app-config.yaml file, and change the layout properties.

    global:
      dynamic:
        plugins:
          - package: <package_location>
            disabled: false
            pluginConfig:
              dynamicPlugins:
                frontend:
                  <plugin_name>:
                    mountPoints:
                      - mountPoint: <mount_point>
                        importName: <import_name>
                        config:
                          layout:
                            gridColumn:
                              lg: span 6
                              xs: span 12
    package
    Enter your package location, such as ./dynamic-plugins/dist/backstage-community-plugin-tekton.
    <plugin_name>
    Enter your plugin name, such as: backstage-community.plugin-tekton.
    mountPoint
    Copy the mount point defined in the plugin default configuration, such as: entity.page.ci/cards.
    importName
    Copy the import name defined in the plugin default configuration, such as: TektonCI.
    layout
    Enter your layout configuration. The tab content is displayed in a responsive grid that uses a 12 column-grid and supports different breakpoints (xs, sm, md, lg, xl) that can be specified for a CSS property, such as gridColumn. The example uses 6 of the 12 columns to show two Tekton CI cards side-by-side on large (lg) screens (span 6 columns) and shows them among themselves (xs and above span 12 columns).

9.3.9. Customize the Home page layout to optimize developer workflows

9.3.9.1. Customize the Home page layout to optimize developer workflows

Persona-specific homepage layouts allow you to deliver targeted content, such as role-appropriate templates and links, to distinct user groups in Red Hat Developer Hub.

9.3.9.2. Author default persona-based layouts to curate distinct starting experiences

Author default persona-based homepage layouts for different user roles to curate distinct starting experiences by selecting appropriate cards, templates, and resources that match each persona’s workflow needs.

Prerequisites

  • You have Red Hat Developer Hub 1.10 or later running.
  • You have enabled the homepage backend plugin.

    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.

    To enable the homepage backend plugin, add the following configuration to your dynamic-plugins.yaml file:

    plugins:
      - package: oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-homepage-backend:1.10!red-hat-developer-hub-backstage-plugin-homepage-backend
        disabled: false
  • You have administrative access to modify the app-config.yaml configuration file.

Procedure

  1. Identify your user personas and their workflow needs.

    Plan which types of content each persona requires on their homepage.

    Example persona planning:

    PersonaPrimary TasksNeeded Homepage Content

    Developer

    Write code, deploy services, review PRs

    Templates, catalog, quick access to repos

    Manager

    Monitor team progress, review metrics

    Dashboards, reports, team activity

    Data Scientist

    Run experiments, access data

    Notebooks, data sources, model registry

  2. Open your app-config.yaml configuration file.
  3. Define the homepage layout structure for each persona in the homepage.defaultWidgets section.

    For example, configure a developer persona homepage with cards appropriate for development workflows:

    homepage:
      defaultWidgets:
        # Developer persona layout
        - id: developer-onboarding
          ref: 'rhdh-onboarding-section'
          layout:
            xl: { w: 12, h: 6 }
            lg: { w: 12, h: 6 }
    
        - id: developer-quickaccess
          ref: quickaccess-card
          props:
            title: Developer Quick Access
          layout:
            xl: { w: 7, h: 8 }
            lg: { w: 7, h: 8 }
    
        - id: templates
          ref: rhdh-template-section
          layout:
            xl: { w: 12, h: 5 }
            lg: { w: 12, h: 5 }
    
        - id: starred-entities
          ref: catalog-starred-entities-card
          layout:
            xl: { w: 5, h: 4, x: 7 }
            lg: { w: 5, h: 4, x: 7 }

    The layout uses a 12-column grid system with properties:

    1. w (width): Number of columns (1-12)
    2. h (height): Number of grid rows
    3. x (x-position): Column offset (0-11)
    4. y (y-position): Row offset (optional)
  4. Configure a default homepage layout that all users can see.

    Create cards without visibility conditions so that all authenticated users see essential homepage content:

        # Default cards visible to all users
        - id: onboarding
          ref: 'rhdh-onboarding-section'
          layout:
            xl: { w: 12, h: 6 }
    
        - id: quickaccess-card
          ref: quickaccess-card
          layout:
            xl: { w: 6, h: 6 }
  5. Save the configuration file.

    Note

    The layouts you authored are not yet restricted to specific user groups. To control which personas see which layouts, proceed to attach these layouts to RBAC groups.

9.3.9.3. Attach homepages to groups to control access and automate layout assignment

Assign persona-specific homepage layouts to user groups to automate role-based content access.

Prerequisites

  • You have Red Hat Developer Hub 1.10 or later running.
  • You defined groups for each user persona (for example, group:default/developers, group:default/data-scientists, group:default/managers).
  • You authored persona-based homepage layouts in your app-config.yaml configuration file.
  • You have administrative access to modify the app-config.yaml configuration file.

Procedure

  1. Enable the homepage backend plugin.

    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.

    Add the following configuration to your dynamic-plugins.yaml file:

    plugins:
      - package: oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-homepage-backend:1.10!red-hat-developer-hub-backstage-plugin-homepage-backend
        disabled: false
  2. Identify your user personas and their corresponding groups.

    Important

    Replace the example group names below with your organization’s actual group names.

    PersonaGroup

    Developer

    group:default/developers

    Manager

    group:default/managers

    Data Scientist

    group:default/data-scientists

  3. Verify that you created the groups in your RHDH configuration.

    Check that the groups exist by using the RBAC web UI or by reviewing your RBAC configuration file. You must create all groups referenced in your persona mapping before configuring homepage visibility.

  4. Open your app-config.yaml configuration file.
  5. Attach persona-specific layouts to groups by adding the if.groups field to group cards under a shared visibility condition.

    For example, attach the developer persona layout to the developers group:

    homepage:
      defaultWidgets:
        # Attach developer layout to developers group
        - if:
            groups: [group:default/developers]
          children:
            - id: developer-onboarding
              ref: 'rhdh-onboarding-section'
              layout:
                xl: { w: 12, h: 6 }
                lg: { w: 12, h: 6 }
    
            - id: developer-quickaccess
              ref: quickaccess-card
              props:
                title: Developer Quick Access
              layout:
                xl: { w: 7, h: 8 }
                lg: { w: 7, h: 8 }
    
            - id: templates
              ref: rhdh-template-section
              layout:
                xl: { w: 12, h: 5 }
                lg: { w: 12, h: 5 }
    
            - id: starred-entities
              ref: catalog-starred-entities-card
              layout:
                xl: { w: 5, h: 4, x: 7 }
                lg: { w: 5, h: 4, x: 7 }

    The groups field accepts an array of group entity references. Users who belong to any of the listed groups see all child cards.

  6. Control visibility for multiple groups by adding additional if.groups configurations.

    Individual child cards can include their own if conditions to further restrict visibility beyond the parent group’s rules.

    Note

    The front-end positions cards according to layout coordinates (x, y, w, h), not array order. The configuration array order does not affect rendering position.

  7. Save the configuration file and restart Red Hat Developer Hub:

    $ kubectl rollout restart deployment/<rhdh-deployment-name>

    Replace <rhdh-deployment-name> with the name of your RHDH deployment.

    Important

    RHDH validates the homepage configuration at startup. If the configuration contains errors, RHDH will fail to start. Check the pod logs for configuration validation errors if the deployment does not become ready.

Verification

  1. Log in to Red Hat Developer Hub as a test user who belongs to one of the configured groups.

    The homepage displays only the cards configured for that user’s persona.

  2. Log in as a test user from a different group.

    The homepage displays a different set of cards based on the second user’s group membership.

  3. Log in as a test user who does not belong to any persona-specific group.

    The homepage displays only the default cards that have no if conditions.

9.3.9.4. Homepage backend configuration reference

Use these backend plugin configuration options, card structures, and API endpoints to customize and manage your homepage data.

9.3.9.4.1. Configuration options

The configuration fields available in the homepage section of your app-config.yaml file:

FieldTypeRequiredDescription

homepage.defaultWidgets

array

No

List of default homepage cards and groups with visibility rules and layout configuration. RHDH validates this configuration at startup. Configuration errors prevent RHDH from starting. Default: []

9.3.9.4.2. Card configuration

Each card in the homepage.defaultWidgets array supports the following fields:

FieldTypeRequiredDescription

id

string

Yes (for cards)

Unique identifier for the card. Each card must have a unique ID within the configuration.

ref

string

Yes (for cards)

Name of the widget component to render. Must match a registered mount point config.id in the dynamic home page plugin configuration.

layout

object

No

Responsive grid layouts for different screen breakpoints (xl, lg, md, sm, xs, xxs). Each layout specifies width (w), height (h), and optional x/y position.

props

object

No

Component-specific properties passed to the card. Properties vary by card type.

if

object

No

Visibility conditions that control which users can see this card. If not specified or all lists are empty, all users see the card.

9.3.9.4.3. Group configuration

Parent groups that contain multiple cards support the following fields:

Note

Groups must not include id or ref fields. Only individual cards require these fields.

FieldTypeRequiredDescription

children

array

Yes (for groups)

List of child cards that inherit the parent group’s visibility rules. Child cards can include their own if conditions to further restrict visibility.

if

object

No

Visibility conditions applied to all children. Child cards remain hidden if the parent fails its visibility check.

9.3.9.4.4. Configuration example

The following example shows a complete homepage backend configuration with persona-based visibility:

homepage:
  defaultWidgets:
    # Search bar - visible to all users
    - id: onboarding
      ref: 'rhdh-onboarding-section'
      layout:
        xl: { w: 12, h: 6 }
        lg: { w: 12, h: 6 }

    # Quick access card - visible to all users
    - id: quickaccess-card
      ref: quickaccess-card
      layout:
        xl: { w: 6, h: 8, x: 6 }

    # Group with shared visibility - visible only to admins
    - if:
        groups: [group:default/admins]
      children:
        - id: featured-docs
          ref: featured-docs-card
          layout:
            xl: { w: 12, h: 6 }

    # Templates - visible only to developers
    - id: templates
      ref: rhdh-template-section
      if:
        groups: [group:default/developers]
      layout:
        xl: { w: 12, h: 5 }
        lg: { w: 12, h: 5 }

9.3.9.5. Homepage visibility rule syntax

Review the visibility properties, access control parameters, and user group settings used to restrict or grant access to homepage cards.

9.3.9.5.1. Visibility condition fields

The if configuration section supports the following optional fields:

FieldTypeRequiredDescription

users

array of strings

No

User references that can see this card. Users whose reference matches any listed value can see the card. Example: user:default/jane

groups

array of strings

No

Groups whose members can see this card. Users who belong to any of the listed groups can see the card. RHDH verifies group membership through the catalog. Users who are not in the catalog cannot match group-based visibility conditions.

9.3.9.5.2. Logical operators

Visibility conditions use the following logical behavior:

  • Multiple values in one field (OR): When a field lists multiple values (for example, multiple groups), the user must match at least one value to see the card.
  • Multiple fields in one condition (OR): When an if block includes multiple fields (for example, both users and groups), the user must satisfy at least one condition from any field to see the card.
  • No visibility condition: When you omit the if section, or when all lists within if are empty, all authenticated users can see the card.
  • Parent group inheritance: When a parent group’s if condition fails, all child cards remain hidden, even if individual child cards have their own if conditions that would otherwise match.
9.3.9.5.3. Group-based visibility

The following example restricts card visibility to members of group:default/developers:

- id: templates
  ref: rhdh-template-section
  if:
    groups: [group:default/developers]
  layout:
    xl: { w: 12, h: 5 }
9.3.9.5.4. Multiple groups (OR logic)

The following example displays a card to members of either group:default/managers or group:default/team-leads:

- id: scorecard
  ref: scorecard-card
  if:
    groups: [group:default/managers, group:default/team-leads]
  layout:
    xl: { w: 6, h: 6 }
9.3.9.5.5. User-specific visibility

The following example restricts card visibility to a specific user by their user reference:

- id: admin-dashboard
  ref: admin-dashboard
  if:
    users: [user:default/admin]
  layout:
    xl: { w: 12, h: 6 }
9.3.9.5.6. Default visibility for all users

The following example makes a card visible to all authenticated users by omitting the if field:

- id: search-bar
  ref: searchbar
  layout:
    xl: { w: 10, h: 1, x: 1 }

Alternatively, an empty if object produces the same result:

- id: quickaccess-card
  ref: quickaccess-card
  if: {}
  layout:
    xl: { w: 6, h: 6 }
Note

Omitting if, using if: {}, or using if with all empty lists are functionally identical. All authenticated users can see the card.

9.3.9.5.7. Shared visibility for multiple cards

The following example applies a shared visibility condition to multiple cards using a parent with children:

- if:
    groups: [group:default/platform-team]
  children:
    - id: metrics-card
      ref: platform-metrics
      layout:
        xl: { w: 6, h: 8 }
    - id: logs-card
      ref: platform-logs
      layout:
        xl: { w: 6, h: 8 }

Both cards display only to members of group:default/platform-team. Only the individual child cards appear in the homepage, not the parent group configuration.

9.3.9.6. Available homepage cards

Integrate custom features from installed plugins into your Home page by using available cards. Configure card visibility by attaching cards to RBAC groups using visibility rules.

The following is a list of the available homepage cards:

  • Search bar
  • Quick access
  • Headline
  • Markdown
  • Placeholder
  • Catalog starred entities
  • Featured docs
Note

Each card can have a layouts definition, props that depend on the component you use, and optional visibilityRules to control which users can see the card.

9.3.9.7. Arrange homepage card layouts to optimize visual organization

Arrange and customize homepage card layouts to ensure your content scales correctly across different screen sizes.

The Home page layout uses a 12-column grid system. The grid uses the following layout properties:

  • w (width): Number of columns (1-12)
  • h (height): Number of grid rows (arbitrary units)
  • x (x-position): Column offset (0-11)
  • y (y-position): Row offset (optional, defaults to auto-placement)

You can define these layout properties for each card across multiple screen breakpoints:

  • Extra-large (xl)
  • Large (lg)
  • Medium (md)
  • Small (sm)
  • Extra-small (xs)
  • Extra-extra-small (xxs)

The default Home page is as shown in the following app-config.yaml file configuration:

dynamicPlugins:
  frontend:
    red-hat-developer-hub.backstage-plugin-dynamic-home-page:
      dynamicRoutes:
        - path: /
          importName: DynamicHomePage
      mountPoints:
        - mountPoint: home.page/cards
          importName: SearchBar
          config:
            layouts:
              xl: { w: 10, h: 1, x: 1 }
              lg: { w: 10, h: 1, x: 1 }
              md: { w: 10, h: 1, x: 1 }
              sm: { w: 10, h: 1, x: 1 }
              xs: { w: 12, h: 1 }
              xxs: { w: 12, h: 1 }
        - mountPoint: home.page/cards
          importName: QuickAccessCard
          config:
            layouts:
              xl: { w: 7, h: 8 }
              lg: { w: 7, h: 8 }
              md: { w: 7, h: 8 }
              sm: { w: 12, h: 8 }
              xs: { w: 12, h: 8 }
              xxs: { w: 12, h: 8 }
        - mountPoint: home.page/cards
          importName: CatalogStarredEntitiesCard
          config:
            layouts:
              xl: { w: 5, h: 4, x: 7 }
              lg: { w: 5, h: 4, x: 7 }
              md: { w: 5, h: 4, x: 7 }
              sm: { w: 12, h: 4 }
              xs: { w: 12, h: 4 }
              xxs: { w: 12, h: 4 }

Prerequisites

  • You have administrative access and can modify the app-config.yaml file for dynamic plugin configurations.

Procedure

  1. Optional: For persona-based homepage configuration with group-based visibility controls, enable the homepage backend plugin.

    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.

    Add the following configuration to your dynamic-plugins.yaml file:

    plugins:
      - package: oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-homepage-backend:1.10!red-hat-developer-hub-backstage-plugin-homepage-backend
        disabled: false
    Note

    The homepage backend plugin is only required for persona-based layouts with group-based visibility controls (the if.groups field). Basic homepage customization does not require the backend plugin.

  2. Configure different cards for your Home page in Red Hat Developer Hub as shown in the following code:

    Search

    You can use the SearchBar card to provide essential search functionality directly on the Home page.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: SearchBar
              config:
                layouts:
                  xl: { w: 10, h: 1, x: 1 }
                  lg: { w: 10, h: 1, x: 1 }
                  md: { w: 10, h: 1, x: 1 }
                  sm: { w: 10, h: 1, x: 1 }
                  xs: { w: 12, h: 1 }
                  xxs: { w: 12, h: 1 }
                props:
                  path: /search
                  queryParam: query
    PropDefaultDescription

    path

    /search

    Override the linked search path if needed

    queryParam

    query

    Override the search query parameter name if needed

    Quick access

    You can use the QuickAccessCard card to function as a customizable shortcut panel.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: QuickAccessCard
              config:
                layouts:
                  xl: { h: 8 }
                  lg: { h: 8 }
                  md: { h: 8 }
                  sm: { h: 8 }
                  xs: { h: 8 }
                  xxs: { h: 8 }
                props:
                  title: Quick Access
                  path: /quickaccess
    PropDefaultDescription

    title

    Quick Access

    Override the linked search path if needed

    path

    none

    Override the search query parameter name if needed

    Headline

    You can use the Headline card to display important information.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: Headline
              config:
                layouts:
                  xl: { h: 1 }
                  lg: { h: 1 }
                  md: { h: 1 }
                  sm: { h: 1 }
                  xs: { h: 1 }
                  xxs: { h: 1 }
                props:
                  title: Important info
    PropDefaultDescription

    title

    none

    Title

    Markdown

    You can use the Markdown card to display richly formatted content directly within the Home page layout. This card uses Markdown syntax to present structured information, such as lists and links (documentation and plugin repositories).

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: MarkdownCard
              config:
                layouts:
                  xl: { w: 6, h: 4 }
                  lg: { w: 6, h: 4 }
                  md: { w: 6, h: 4 }
                  sm: { w: 6, h: 4 }
                  xs: { w: 6, h: 4 }
                  xxs: { w: 6, h: 4 }
                props:
                  title: Company links
                  content: |
                    ### RHDH
                    * [Website](https://developers.redhat.com/rhdh/overview)
                    * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/)
                    * [Backstage Community Plugins](https://github.com/backstage/community-plugins)
                    * [RHDH Plugins](https://github.com/redhat-developer/rhdh-plugins)
                    * [RHDH Hub](https://github.com/redhat-developer/rhdh)
            - mountPoint: home.page/cards
              importName: Markdown
              config:
                layouts:
                  xl: { w: 6, h: 4, x: 6 }
                  lg: { w: 6, h: 4, x: 6 }
                  md: { w: 6, h: 4, x: 6 }
                  sm: { w: 6, h: 4, x: 6 }
                  xs: { w: 6, h: 4, x: 6 }
                  xxs: { w: 6, h: 4, x: 6 }
                props:
                  title: Important company links
                  content: |
                    ### RHDH
                    * [Website](https://developers.redhat.com/rhdh/overview)
                    * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/)
                    * [Documentation](https://docs.redhat.com/en/documentation/red_hat_developer_hub/)
                    * [Backstage Community Plugins](https://github.com/backstage/community-plugins)
                    * [RHDH Plugins](https://github.com/redhat-developer/rhdh-plugins)
                    * [RHDH Hub](https://github.com/redhat-developer/rhdh)
    Placeholder

    You can use the Placeholder card as a utility element for reserving space or for layout testing on the Home page.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: Placeholder
              config:
                layouts:
                  xl: { w: 1, h: 1 }
                  lg: { w: 1, h: 1 }
                  md: { w: 1, h: 1 }
                  sm: { w: 1, h: 1 }
                  xs: { w: 1, h: 1 }
                  xxs: { w: 1, h: 1 }
                props:
                  showBorder: true
                  debugContent: '1'
    Catalog starred entities

    You can use the CatalogStarredEntitiesCard card to provide a dedicated space on the Home page for users to view catalog entities that they have marked as starred.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: CatalogStarredEntitiesCard
    Featured docs

    You can use the FeaturedDocsCard card as a way to highlight specific documentation within Red Hat Developer Hub, as it is available for deployment on the Home page.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: FeaturedDocsCard
    EntitySection

    You can use the EntitySection card to create a visually engaging section that highlights catalog entities of various kinds, such as Component, API, Resource, and System.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: EntitySection
              config:
                layouts:
                  xl: { w: 12, h: 6 }
                  lg: { w: 12, h: 6 }
                  md: { w: 12, h: 6 }
                  sm: { w: 12, h: 6 }
                  xs: { w: 12, h: 6 }
                  xxs: { w: 12, h: 14.5 }
    OnboardingSection

    You can use the OnboardingSection card to quickly discover learning resources within RHDH.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: OnboardingSection
              config:
                layouts:
                  xl: { w: 12, h: 5 }
                  lg: { w: 12, h: 5 }
                  md: { w: 12, h: 5 }
                  sm: { w: 12, h: 5 }
                  xs: { w: 12, h: 7 }
                  xxs: { w: 12, h: 12 }
    TemplateSection

    You can use the TemplateSection card to quickly explore and initiate software templates in RHDH.

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          mountPoints:
            - mountPoint: home.page/cards
              importName: TemplateSection
              config:
                layouts:
                  xl: { w: 12, h: 5 }
                  lg: { w: 12, h: 5 }
                  md: { w: 12, h: 5 }
                  sm: { w: 12, h: 5 }
                  xs: { w: 12, h: 5 }
                  xxs: { w: 12, h: 14 }

9.3.9.8. Define the layout of the Red Hat Developer Hub Home page

The Home page uses a 12-column grid to position your cards. You can use the optimal parameters to define the layout of your Developer Hub Home page.

Prerequisites

  • Include the following optimal parameters in each of your breakpoints:

    • width (w)
    • height (h)
    • position (x and y)

Procedure

  1. Configure your Developer Hub app-config.yaml configuration file by choosing one of the following options:

    1. Use the full space on smaller windows and half of the space on larger windows as follows:

      dynamicPlugins:
        frontend:
          red-hat-developer-hub.backstage-plugin-dynamic-home-page:
            mountPoints:
              - mountPoint: home.page/cards
                importName: Placeholder
                config:
                  layouts:
                    xl: { w: 6, h: 2 }
                    lg: { w: 6, h: 2 }
                    md: { w: 6, h: 2 }
                    sm: { w: 12, h: 2 }
                    xs: { w: 12, h: 2 }
                    xxs: { w: 12, h: 2 }
                  props:
                    showBorder: true
                    debugContent: a placeholder
    2. Show the cards side by side by defining the x parameter as shown in the following example:

      dynamicPlugins:
        frontend:
          red-hat-developer-hub.backstage-plugin-dynamic-home-page:
            mountPoints:
              - mountPoint: home.page/cards
                importName: Placeholder
                config:
                  layouts:
                    xl: { w: 6, h: 2 }
                    lg: { w: 6, h: 2 }
                    md: { w: 6, h: 2 }
                    sm: { w: 12, h: 2 }
                    xs: { w: 12, h: 2 }
                    xxs: { w: 12, h: 2 }
                  props:
                    showBorder: true
                    debugContent: left
              - mountPoint: home.page/cards
                importName: Placeholder
                config:
                  layouts:
                    xl: { w: 6, h: 2, x: 6 }
                    lg: { w: 6, h: 2, x: 6 }
                    md: { w: 6, h: 2, x: 6 }
                    sm: { w: 12, h: 2, x: 0 }
                    xs: { w: 12, h: 2, x: 0 }
                    xxs: { w: 12, h: 2, x: 0 }
                  props:
                    showBorder: true
                    debugContent: right

      However, you can see a second card below this card by default.

    3. Show the cards in three columns by defining the x parameter as shown in the following example:

      dynamicPlugins:
        frontend:
          red-hat-developer-hub.backstage-plugin-dynamic-home-page:
            mountPoints:
              - mountPoint: home.page/cards
                importName: Placeholder
                config:
                  layouts:
                    xl: { w: 4, h: 2 }
                    lg: { w: 4, h: 2 }
                    md: { w: 4, h: 2 }
                    sm: { w: 6, h: 2 }
                    xs: { w: 12, h: 2 }
                    xxs: { w: 12, h: 2 }
                  props:
                    showBorder: true
                    debugContent: left
              - mountPoint: home.page/cards
                importName: Placeholder
                config:
                  layouts:
                    xl: { w: 4, h: 2, x: 4 }
                    lg: { w: 4, h: 2, x: 4 }
                    md: { w: 4, h: 2, x: 4 }
                    sm: { w: 6, h: 2, x: 6 }
                    xs: { w: 12, h: 2 }
                    xxs: { w: 12, h: 2 }
                  props:
                    showBorder: true
                    debugContent: center
              - mountPoint: home.page/cards
                importName: Placeholder
                config:
                  layouts:
                    xl: { w: 4, h: 2, x: 8 }
                    lg: { w: 4, h: 2, x: 8 }
                    md: { w: 4, h: 2, x: 8 }
                    sm: { w: 6, h: 2 }
                    xs: { w: 12, h: 2 }
                    xxs: { w: 12, h: 2 }
                  props:
                    showBorder: true
                    debugContent: right

Additional resources

9.3.9.9. Customize your dynamic homepage

You can customize your homepage to suit your preferences by using the drag-and-drop, resizing, and widget management functionality.

You can do the following actions with the customizable homepage:

  • Drag and drop: Move cards around the layout
  • Resize: Adjust card dimensions
  • Add widget: Select from available cards to add to the homepage
  • Remove cards: Delete cards from the homepage
  • Restore defaults: Reset to the original card configuration
  • User persistence: Settings are saved depending on how you use Backstage Storage API

Additional cards automatically appear based on the installed and enabled plugins. The plugins provide the following two main components:

  • DynamicHomePage: The read-only homepage that displays configured cards without your customization.
  • DynamicCustomizableHomePage: The interactive homepage that allows users to move, resize, and manage cards.

The default homepage displays the OnboardingSection, the EntitySection, and the TemplateSection cards by default. These cards define the default width (w) and height (h) for the cards at various responsiveness levels.

The homepage automatically loads the following configuration:

dynamicPlugins:
  frontend:
    red-hat-developer-hub.backstage-plugin-dynamic-home-page:
      dynamicRoutes:
        - path: /
          importName: DynamicHomePage
      mountPoints:
        - mountPoint: home.page/cards
          importName: OnboardingSection
          config:
            layouts:
              xl: { w: 12, h: 6 }
              lg: { w: 12, h: 6 }
              md: { w: 12, h: 7 }
              sm: { w: 12, h: 8 }
              xs: { w: 12, h: 9 }
              xxs: { w: 12, h: 14 }
        - mountPoint: home.page/cards
          importName: EntitySection
          config:
            layouts:
              xl: { w: 12, h: 7 }
              lg: { w: 12, h: 7 }
              md: { w: 12, h: 8 }
              sm: { w: 12, h: 9 }
              xs: { w: 12, h: 11 }
              xxs: { w: 12, h: 15 }
        - mountPoint: home.page/cards
          importName: TemplateSection
          config:
            layouts:
              xl: { w: 12, h: 5 }
              lg: { w: 12, h: 5 }
              md: { w: 12, h: 5 }
              sm: { w: 12, h: 5 }
              xs: { w: 12, h: 7 }
              xxs: { w: 12, h: 13 }
              xs: { w: 12, h: 7.5 }
              xxs: { w: 12, h: 13.5 }

Procedure

  1. You can arrange the cards and adjust their dimensions using the drag-and-drop and resize functionality. The following is an example of an interactive homepage where you can add, remove, move, and resize cards:

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          dynamicRoutes:
            - path: /
              importName: DynamicCustomizableHomePage
          mountPoints:
             - mountPoint: home.page/cards
               importName: OnboardingSection
               config:
                layouts:
                  xl: { w: 12, h: 6 }
                  lg: { w: 12, h: 6 }
                  md: { w: 12, h: 7 }
                  sm: { w: 12, h: 8 }
                  xs: { w: 12, h: 9 }
                  xxs: { w: 12, h: 14 }
            - mountPoint: home.page/cards
              importName: EntitySection
              config:
                layouts:
                  xl: { w: 12, h: 7 }
                  lg: { w: 12, h: 7 }
                  md: { w: 12, h: 8 }
                  sm: { w: 12, h: 9 }
                  xs: { w: 12, h: 11 }
                  xxs: { w: 12, h: 15 }
            - mountPoint: home.page/cards
              importName: TemplateSection
              config:
                layouts:
                  xl: { w: 12, h: 5 }
                  lg: { w: 12, h: 5 }
                  md: { w: 12, h: 5 }
                  sm: { w: 12, h: 5 }
                  xs: { w: 12, h: 7.5 }
                  xxs: { w: 12, h: 13.5 }
            # Additional cards available in "Add widget" dialog
            - mountPoint: home.page/cards
              importName: RecentlyVisitedCard
            - mountPoint: home.page/cards
              importName: TopVisitedCard
  2. You can change the title by overriding the title property of the dynamic homepage plugin as shown in the following example:

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          dynamicRoutes:
            - path: /
              importName: DynamicHomePage # or DynamicCustomizableHomePage for customizable homepage
              config:
                props:
                  title: 'Howdy {{firstName}} or {{displayName}}'

    The title property supports two variables:

  3. {{displayName}}: This contains the full displayName of the catalog entity.
  4. {{firstName}}: This contains the first part (separated by a space) of the displayName.
  5. You can use a subtitle property which is not used by default as shown in the following example:

    dynamicPlugins:
      frontend:
        red-hat-developer-hub.backstage-plugin-dynamic-home-page:
          dynamicRoutes:
            - path: /
              importName: DynamicHomePage # or DynamicCustomizableHomePage
              config:
                props:
                  title: Our custom RHDH instance
                   subtitle: 'Hello {{displayName}}'

9.3.9.10. Customize QuickAccessCard card icons on the Red Hat Developer Hub homepage

As an administrator, you can customize the QuickAccessCard card icons on the Red Hat Developer Hub homepage to enhance its visual appeal and user experience. You can integrate custom branding or standard icons by leveraging a remote JSON configuration file.

Procedure

  1. Add the JSON Data source. The QuickAccessCard card on the homepage supports loading data from a JSON file. This JSON file can be hosted in your GitHub repository or any accessible endpoint.
  2. Configure the Proxy in your RHDH app-config.yaml file.

    To allow the homepage to fetch data from the hosted JSON file, add the following proxy configuration to your RHDH app-config.yaml file:

    proxy:
      endpoints:
      # customize your backstage instance
      '/developer-hub':
        target: https://raw.githubusercontent.com/ # For example, https://raw.githubusercontent.com/
        pathRewrite:
          '^/api/proxy/developer-hub$': <path_to_your>.json # For example, /redhat-developer/rhdh/main/packages/app/public/homepage/data.json
        changeOrigin: true
        secure: true

    The following table lists the supported icon types:

    Icon typeExampleRendered as

    Backstage system icon

    "catalog"

    Uses Backstage system [icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx)

    SVG String

    "<svg>…​</svg>"

    Renders inline SVG

    Image URL

    "https://example.com/icon.png"

    Renders external image. External images might be restricted to Content Security Policy (CSP) which can be configured in your RHDH app-config.yaml file.

    Relative Path

    "/homepage/icons/icon.png"

    Loads the icon from the app public folder (if present)

    Note

    SVGs must be valid strings when stored inside JSON (use single quotes inside <svg>).

    The following is an example of a JSON file:

    [
     {
     "title": "Community",
     "isExpanded": true,
     "links": [
     {
     "iconUrl": "https://img.icons8.com/ios/50/globe--v1.png",
     "label": "Website",
     "url": "https://developers.redhat.com/"
     },
     {
     "iconUrl": "https://img.icons8.com/ios/50/link--v1.png",
     "label": "Blog",
     "url": "https://developers.redhat.com/blog"
     },
     {
     "iconUrl": "github",
     "label": "GitHub",
     "url": "https://github.com/redhat-developer"
     },
     {
     "iconUrl": "https://img.icons8.com/color/48/slack.png",
     "label": "Slack",
     "url": "https://join.slack.com/xyz"
     },
     {
     "iconUrl": "https://img.icons8.com/color/48/youtube-squared.png",
     "label": "Videos for developers",
     "url": "https://developers.redhat.com/videos"
     },
     {
     "iconUrl": "<svg xmlns='http://www.w3.org/2000/svg' xml:space='preserve' width='2048' height='2048' style='shape-rendering:geometricPrecision;text-rendering:geometricPrecision;image-rendering:optimizeQuality;fill-rule:evenodd;clip-rule:evenodd'><defs><style>.fil0{fill:none}.fil4{fill:#bdbdbd;fill-rule:nonzero}</style></defs><g id='Layer_x0020_1'><path class='fil0' d='M0 0h2048v2048H0z'/><path class='fil0' d='M255.999 255.999h1536v1536h-1536z'/><path class='fil0' d='M256 256h1536v1536H256z'/><g id='_342647616'><path id='_342648000' style='fill:#e53935;fill-rule:nonzero' d='m273.04 666.226 737.28-367.843 13.68-6.824 13.68 6.824 737.28 367.843 17.04 8.503v234.834L993.281 1418.52 255.999 909.563V674.729z'/><path id='_342647880' style='fill:#fff' d='M609.28 711.961h829.439V1541.4H609.28z'/><path id='_342647808' style='fill:#c62828;fill-rule:nonzero' d='m1024 1279.73 723.6-361.079 44.4-22.156v859.945H255.999V896.495l44.402 22.156z'/><path id='_342647736' class='fil4' d='M1331.2 896.285H716.716v-61.442H1331.2z'/><path id='_342647688' class='fil4' d='M1203.22 1049.88H844.698v-61.439h358.522z'/></g></g></svg>",
     "label": "Mailing List",
     "url": "https://groups.google.com/g/xyz"
     },
     ]
    }
    ]

Chapter 10. Secure

10.1. Secure

Manage authentication and authorization in Red Hat Developer Hub to control user access, verify identities, and enforce role-based policies.

You can enable authentication in Red Hat Developer Hub to allow users to sign in using credentials from an external identity provider, such as RHBK, GitHub, or Microsoft Azure, and provision user and group data to the software catalog.

Red Hat Developer Hub (RHDH) administrators can use role-based access control (RBAC) to manage authorizations of other users by defining roles, permissions, and policies for users and groups.

10.2. Configure authentication providers to verify user identities

10.2.1. Configure authentication providers to verify user identities

Enable authentication with your main identity provider to allow users to sign in to Red Hat Developer Hub using their organizational credentials.

10.2.2. Authentication methods and identity provider selection

10.2.2.1. Authentication methods and identity provider selection

User provisioning and authentication are two independent mechanisms in Red Hat Developer Hub. You can configure them separately depending on your requirements.

10.2.2.2. Understand authentication and user provisioning

User provisioning and authentication are two independent mechanisms in Red Hat Developer Hub. You can configure them separately depending on your requirements.

10.2.2.2.1. User provisioning

To fully enable catalog features, provision user and group data from an Identity Provider (IdP) to the Developer Hub software catalog. Catalog provider plugins handle this task asynchronously. These plugins query the IdP for relevant user and group information, and create or update corresponding entities in the Developer Hub catalog. Scheduled provisioning ensures that the catalog accurately reflects the users and groups in your organization.

You can provision users and groups from any supported source, including Red Hat Build of Keycloak (RHBK), GitHub, GitLab, Microsoft Azure, or LDAP. LDAP provisioning works independently of your authentication provider. Following associations are supported:

User provisioningAuthentication

RHBK

RHBK

LDAP

RHBK

GitHub

GitHub

Microsoft Azure

Microsoft Azure

For example, you can authenticate users with RHBK while provisioning user and group data from your LDAP directory.

Configuring user provisioning is critical for several reasons.

  • Enabling authorization by allowing you to define access controls based on user and group memberships synchronized from your IdP.
  • Provisioning user and group data to the catalog is necessary for various catalog features that rely on understanding entity ownership and relationships between users, groups, and software components.

    Important

    Without this provisioning step, features such as displaying who owns a catalog entity might not function correctly.

Tip

To explore Developer Hub features in a non-production environment, you can:

  • To use Developer Hub without external IdP, enable the guest user to skip configuring authentication and authorization, log in as the guest user, and access all Developer Hub features.
  • To use Developer Hub without authorization policies and features relying on the software catalog, you can enable the dangerouslyAllowSignInWithoutUserInCatalog resolver option. This setting bypasses the check requiring a user to be in the catalog but still enforces authentication.
Important

Developer Hub uses a one-way synchronization model, where user and group data flow from your Identity Provider to the Developer Hub software catalog. As a result, deleting users or groups manually through the Developer Hub Web UI or REST API might be ineffective or cause inconsistencies, since Developer Hub will create those entities again during the next import.

10.2.2.2.2. Authentication

When a user attempts to access Developer Hub, Developer Hub redirects them to a configured authentication provider, such as Red Hat Build of Keycloak (RHBK), GitHub, GitLab, or Microsoft Azure. This external IdP is responsible for authenticating the user.

On successful authentication, the Developer Hub authentication plugin, configured in your app-config.yaml file, processes the response from the IdP, resolves the identity in the Developer Hub software catalog, and establishes a user session within Developer Hub.

Authentication works independently of user provisioning. By default you cannot authenticate users without provisioning them to the software catalog. You can override this behavior to authenticate users without provisioning them to the software catalog, by using the dangerouslyAllowSignInWithoutUserInCatalog parameter. However, provisioning is a prerequisite for full catalog functionality, such as entity ownership and group-based access controls.

10.2.3. Configure guest access to securely test non-production environments

10.2.3.1. Configure guest access to securely test non-production environments

For trial or non-production environments, you can enable guest access to explore Developer Hub features without configuring authentication. For production environments, disable guest access to ensure security.

10.2.3.2. Enable the Guest login

To allow users to log in as a guest on the login page, enable the guest login option.

Procedure

  1. In the app-config.yaml file, set the authentication environment to development:

    auth:
      environment: development
  2. Restart the Developer Hub application to apply the changes.

Verification

  1. Go to the login page of your Developer Hub instance.
  2. Verify that the option to log in as a guest is available.

10.2.3.3. Disable the Guest login

To prevent users from logging in as a guest on the login page, disable the guest login option.

Procedure

  1. In the app-config.yaml file, set the authentication environment to production:

    auth:
      environment: production
  2. Restart the Developer Hub application to apply the changes.

Verification

  1. Go to the login page of your Developer Hub instance.
  2. Verify that the option to log in as a guest is no longer available.

10.2.4. Share credentials with your identity provider to secure communications

10.2.4.1. Share credentials with your identity provider to secure communications

Share credentials between your identity provider and Red Hat Developer Hub to enable secure communication for authentication and user provisioning.

10.2.4.2. Share a secret with Red Hat Build of Keycloak (RHBK)

Register your Red Hat Developer Hub application in Red Hat Build of Keycloak (RHBK) and store the credentials in Developer Hub to enable secure communication.

Prerequisites

Procedure

  1. Register your Developer Hub app in RHBK:

    1. Use an existing realm, or create a realm, with a distinctive Name such as <my_realm>. Save the value for the next step:
  2. RHBK realm base URL, such as: <your_rhbk_URL>/realms/<your_realm>.

    1. In the created realm, secure the first application, with:

      1. Client ID: A distinctive client ID, such as <RHDH>.
      2. Valid redirect URIs: Set to the OIDC handler URL: https://<my_developer_hub_domain>/api/auth/oidc/handler/frame.
      3. Go to the Credentials tab and copy the Client secret.
      4. Save the values for the next step:
  3. Client ID
  4. Client Secret

    1. In the same realm, get the credential information for an existing user or create a user. Save the user credential information for the verification steps.
  5. Create a long, complex, and unique string to use as the Developer Hub session secret key.
  6. Add the following key-value pairs to your Developer Hub secrets. You can use these secrets in the Developer Hub configuration files by using their environment variable name.

    KEYCLOAK_CLIENT_ID
    Enter the saved Client ID.
    KEYCLOAK_CLIENT_SECRET
    Enter the saved Client Secret.
    KEYCLOAK_BASE_URL
    Enter the saved RHBK realm base URL.
    KEYCLOAK_REALM
    Enter the realm name to provision users.
    KEYCLOAK_LOGIN_REALM
    Enter the realm name to authenticate users.
    SESSION_SECRET
    Enter the created session secret key.

Verification

  • Verify that the secret key-value pairs are stored in your Developer Hub secrets.

10.2.4.3. Share a secret with LDAP

Collect your LDAP credentials and store them in Red Hat Developer Hub to enable user and group provisioning from your LDAP directory.

Prerequisites

Procedure

  1. Collect the following LDAP credentials from your LDAP server:

    LDAP URL
    Your LDAP server URL, such as ldaps://ds.example.net.
    Bind DN
    Your bind distinguished name, such as cn=admin,OU=Users,DC=rhdh,DC=test.
    LDAP secret
    Your LDAP secret.
  2. Optional: To use a secure LDAP connection (ldaps://), store your LDAP certificates in the ldap_certs.pem file and your LDAP keys in the ldap_keys.pem file.

    Warning

    In production mode, use a secure LDAP connection.

  3. Add the LDAP_SECRET key-value pair to your Developer Hub secrets. You can use this secret in the Developer Hub configuration files by using its environment variable name.

    LDAP_SECRET
    Enter your LDAP secret.
  4. Optional: To use a secure LDAP connection (ldaps://), add your LDAP certificates and keys files to a an OpenShift secret.

    $ oc create secret generic my-rhdh-ldap-secrets \
        --from-file=./ldap_certs.pem \
        --from-file=./ldap_keys.pem

Verification

  • Verify that the secret key-value pairs are stored in your Developer Hub secrets.

10.2.4.4. Share secrets with GitHub

Register GitHub Apps and store the credentials in Red Hat Developer Hub to enable secure communication. For security, create two separate GitHub Apps following the principle of least privilege:

Integration App (Developer Hub to GitHub)
Authenticates Developer Hub to GitHub for catalog operations such as importing users, groups, and repositories. Requires: GITHUB_APP_APP_ID, GITHUB_APP_CLIENT_ID_INTEGRATION, GITHUB_APP_CLIENT_SECRET_INTEGRATION, and GITHUB_APP_PRIVATE_KEY.
Authentication App (user to Developer Hub)
Authenticates users signing in to Developer Hub with their GitHub credentials. Requires only OAuth credentials: GITHUB_APP_CLIENT_ID and GITHUB_APP_CLIENT_SECRET.

Prerequisites

Procedure

  1. Create a GitHub App for integration.

    Note

    Use a GitHub App instead of an OAuth app to use fine-grained permissions and short-lived tokens, scale with the number of installations by avoiding rate limits, and have a more transparent integration by avoiding to request user input.

    1. Register a GitHub App with the following configuration:

      GitHub App name
      Enter a unique name identifying your GitHub App, such as integrating-with-rhdh-<GUID>.
      Homepage URL
      Enter your Developer Hub URL: https://<my_developer_hub_domain>.
      Webhook
      Clear "Active".
      Repository permissions
      Contents
      Read-only
      Commit statuses
      Read-only
      Organization permissions
      Members
      Read-only
      Where can this GitHub App be installed?
      Select Only on this account.
    2. In the GeneralClients secrets section, click Generate a new client secret.
    3. In the GeneralPrivate keys section, click Generate a private key.
    4. In the Install App tab, choose an account to install your GitHub App on.
    5. Save the following values for the next step:
  2. App ID
  3. Client ID
  4. Client secret
  5. Private key
  6. Store the integration app credentials: Add the following key/value pairs to your Developer Hub secrets.

    GITHUB_APP_APP_ID
    Enter the saved App ID.
    GITHUB_APP_CLIENT_ID_INTEGRATION
    Enter the saved Client ID.
    GITHUB_APP_CLIENT_SECRET_INTEGRATION
    Enter the saved Client Secret.
    GITHUB_APP_PRIVATE_KEY
    Enter the saved Private key.
    GITHUB_URL
    Enter the GitHub host domain: https://github.com.
    GITHUB_ORG
    Enter your GitHub organization name, such as <your_github_organization_name>.
  7. Create a separate GitHub App for authentication.

    1. Register a GitHub App with the following configuration:

      GitHub App name
      Enter a unique name identifying your GitHub App, such as authenticating-with-rhdh-<GUID>.
      Homepage URL
      Enter your Developer Hub URL: https://<my_developer_hub_domain>.
      Authorization callback URL
      Enter your Developer Hub authentication backend URL: https://<my_developer_hub_domain>/api/auth/github/handler/frame.
      Webhook
      Clear "Active".
      Organization permissions
      Enable Read-only access to Members.
      Where can this GitHub App be installed?
      Select Only on this account.
    2. In the GeneralClients secrets section, click Generate a new client secret.
    3. Save the following values for the next step:
  8. Client ID
  9. Client secret
  10. Store the authentication app credentials: Add the following key/value pairs to your Developer Hub secrets.

    GITHUB_APP_CLIENT_ID
    Enter the saved Client ID.
    GITHUB_APP_CLIENT_SECRET
    Enter the saved Client Secret.

Verification

  • Verify that the secret key-value pairs for both apps are stored in your Developer Hub secrets.

10.2.4.5. Share a secret with Microsoft Azure

Register your Red Hat Developer Hub application in Microsoft Azure and store the credentials in Developer Hub to enable secure communication.

Prerequisites

  • You have the permission to register an application in Azure.

    Tip

    Alternatively, ask your Azure administrator to prepare the required Azure application.

  • You added a custom Developer Hub application configuration, and have enough permissions to change it.
  • Your Developer Hub backend can access the following hosts:

    login.microsoftonline.com
    The Microsoft Azure authorization server, which enables the authentication flow.
    graph.microsoft.com
    The server for retrieving organization data, including user and group data, to import into the Developer Hub catalog.

Procedure

  1. Register your Developer Hub app in Azure, by using the Azure portal.

    1. Sign in to the Microsoft Entra admin center.
    2. Optional: If you have access to multiple tenants, use the Settings icon in the top menu to switch to the tenant in which you want to register the application from the Directories + subscriptions menu.
    3. Browse to Applications > App registrations, and create a New registration with the configuration:

      Name
      Enter a name to identify your application in Azure, such as <Authenticating with Developer Hub>.
      Supported account types
      Select Accounts in this organizational directory only.
      Redirect URI
      Select a platform
      Select Web.
      URL
      Enter the backend authentication URI set in Developer Hub: https://<my_developer_hub_domain>/api/auth/microsoft/handler/frame
    4. On the Applications > App registrations > <Authenticating with Developer Hub> > Manage > API permissions page, Add a Permission, Microsoft Graph, select the following permissions:

      Application Permissions
      GroupMember.Read.All, User.Read.All

      Enter permissions that enable provisioning user and groups to the Developer Hub software catalog.

      Optional: Grant admin consent for these permissions. Even if your company does not require admin consent, consider doing so as it means users do not need to individually consent the first time they access Developer Hub.

      Delegated Permissions
      User.Read, email, offline_access, openid, profile

      Enter permissions that enable authenticating users.

      Optional: Enter optional custom scopes for the Microsoft Graph API that you define both here and in your app-config.yaml Developer Hub configuration file.

    5. On the Applications > App registrations > <Authenticating with Developer Hub> > Manage > Certificates & secrets page, in the Client secrets tab, create a New client secret.
    6. Save the following values for the next step:

      • Directory (tenant) ID
      • Application (client) ID
      • Application (client) Secret ID
  2. Add your Azure credentials to Developer Hub, by adding the following key/value pairs to your Developer Hub secrets:

    MICROSOFT_TENANT_ID
    Enter your saved Directory (tenant) ID.
    MICROSOFT_CLIENT_ID
    Enter your saved Application (client) ID.
    MICROSOFT_CLIENT_SECRET
    Enter your saved Application (client) secret.

Verification

  • Verify that the secret key-value pairs are stored in your Developer Hub secrets.

10.2.4.6. Share secrets with GitLab

Register a GitLab OAuth 2 application and store the credentials in Red Hat Developer Hub to enable secure communication. These credentials serve two purposes:

Integration (Developer Hub to GitLab)
GITLAB_HOST and GITLAB_TOKEN authenticate Developer Hub to GitLab for catalog operations such as importing users, groups, and repositories.
Authentication (user to Developer Hub)
GITLAB_CLIENT_ID and GITLAB_CLIENT_SECRET authenticate users signing in to Developer Hub with their GitLab credentials.

Prerequisites

Procedure

  1. Register the GitLab OAuth 2 application.

    Important

    You must use the required callback URL and permissions.

    1. Register a GitLab OAuth 2 application using the following configuration:

      GitLab OAuth 2 application name
      Enter a unique name, such as authenticating-with-rhdh-<GUID>.
      Redirect URI
      Enter your Developer Hub URL: https://<my_developer_hub_domain>.
      Authorization callback URL
      Enter your authentication backend URL: https://<my_developer_hub_domain>/api/auth/gitlab/handler/frame.
      Authorized application scope
      Enable email, profile, openid, and read_user.
    2. Save the application and record these values for the next step:
  2. OAuth 2 Client ID, available in the Application ID field
  3. OAuth 2 Client secret, accessible by selecting Copy in the Secret field
  4. Set up a GitLab personal access token (PAT) with read_api scope. Save the token value for the next step.
  5. Add your GitLab credentials to your RHDH secrets using the following key/value pairs. Use these environment variables in your RHDH configuration files.

    GITLAB_HOST
    Enter your GitLab host: <gitlab_host>.
    GITLAB_CLIENT_ID
    Enter the saved OAuth 2 Client ID.
    GITLAB_CLIENT_SECRET
    Enter the saved OAuth 2 Client Secret.
    GITLAB_TOKEN
    Enter the saved Personal access token.
    GITLAB_URL
    Enter the GitLab host domain: `<gitlab_host_domain>`.
    GITLAB_PARENT_ORG
    Enter your GitLab organization name, such as <your_gitlab_organization_name>.

Verification

  • Verify that the secret key-value pairs are stored in your Developer Hub secrets.

10.2.5. Import users and groups to synchronize enterprise directory data

10.2.5.1. Import users and groups to synchronize enterprise directory data

Import users and groups from your identity provider to the Red Hat Developer Hub software catalog to enable user identity resolution and role-based access control.

10.2.5.2. Import users and groups from RHBK

10.2.5.2.1. Import users and groups from RHBK

Import users and groups from Red Hat Build of Keycloak (RHBK) to the Red Hat Developer Hub software catalog to enable user identity resolution and role-based access control.

10.2.5.2.2. Import users and groups from Red Hat Build of Keycloak (RHBK)

Import Red Hat Build of Keycloak (RHBK) users and groups to the Red Hat Developer Hub software catalog.

Prerequisites

Procedure

  1. Enable the Keycloak catalog provider plugin in your dynamic-plugins.yaml file.

    The plugin is named after RHBK upstream project.

    plugins:
      - package: './dynamic-plugins/dist/backstage-community-plugin-catalog-backend-module-keycloak-dynamic'
        disabled: false
  2. Add a catalog.providers.keycloakOrg section to your app-config.yaml file:

    catalog:
      providers:
        keycloakOrg:
          default:
            baseUrl: ${KEYCLOAK_BASE_URL}
            clientId: ${KEYCLOAK_CLIENT_ID}
            clientSecret: ${KEYCLOAK_CLIENT_SECRET}
            realm: ${KEYCLOAK_REALM}
            loginRealm: ${KEYCLOAK_LOGIN_REALM}
    baseUrl
    Enter your RHBK server URL, defined earlier.
    clientId
    Enter your Developer Hub application client ID in RHBK, defined earlier.
    clientSecret
    Enter your Developer Hub application client secret in RHBK, defined earlier.
    realm
    Enter the realm name to provision users.
    loginRealm
    Enter the realm name to authenticate users.
  3. Optional: Add optional fields to the keycloackOrg catalog provider section in your app-config.yaml file:

    catalog:
      providers:
        keycloakOrg:
          default:
            baseUrl: ${KEYCLOAK_BASE_URL}
            clientId: ${KEYCLOAK_CLIENT_ID}
            clientSecret: ${KEYCLOAK_CLIENT_SECRET}
            realm: ${KEYCLOAK_REALM}
            loginRealm: ${KEYCLOAK_LOGIN_REALM}
            userQuerySize: 100
            groupQuerySize: 100
            schedule:
              frequency: { hours: 1 }
              timeout: { minutes: 50 }
              initialDelay: { seconds: 15}
    userQuerySize
    Enter the user count to query simultaneously. Default value: 100.
    groupQuerySize
    Enter the group count to query simultaneously. Default value: 100.
    schedule
    frequency
    Enter the schedule frequency. Supports cron, ISO duration, and "human duration" as used in code.
    timeout
    Enter the timeout for the user provisioning job. Supports ISO duration and "human duration" as used in code.
    initialDelay
    Enter the initial delay to wait for before starting the user provisioning job. Supports ISO duration and "human duration" as used in code.

Verification

  • Check the console logs.

    Successful synchronization example:

    2025-06-27T16:02:34.647Z catalog info Read 5 Keycloak users and 3 Keycloak groups in 0.4 seconds. Committing... class="KeycloakOrgEntityProvider" taskId="KeycloakOrgEntityProvider:default:refresh" taskInstanceId="db55c34b-46b3-402b-b12f-2fbc48498e82" trace_id="606f80a9ce00d1c86800718c4522f7c6" span_id="7ebc2a254a546e90" trace_flags="01"
    
    2025-06-27T16:02:34.650Z catalog info Committed 5 Keycloak users and 3 Keycloak groups in 0.0 seconds. class="KeycloakOrgEntityProvider" taskId="KeycloakOrgEntityProvider:default:refresh" taskInstanceId="db55c34b-46b3-402b-b12f-2fbc48498e82" trace_id="606f80a9ce00d1c86800718c4522f7c6" span_id="7ebc2a254a546e90" trace_flags="01"
10.2.5.2.3. Create a custom transformer to provision users from Red Hat Build of Keycloak (RHBK) to the software catalog

Customize how Red Hat Developer Hub provisions users and groups to Developer Hub software catalog entities, by creating a backend module that uses the keycloakTransformerExtensionPoint to offer custom user and group transformers for the Keycloak backend.

Procedure

  1. Create a new backend module with the yarn new command.

    $ yarn new
    ? What type of module would you like to create? backend-plugin-module
    ? Enter the ID of the plugin [required] catalog
    ? Enter the ID of the module [required] keycloak-org-transformer

    The command creates a plugin named catalog-backend-module-keycloak-org-transformer.

  2. Install required packages:

    $ yarn --cwd plugins/catalog-backend-module-keycloak-org-transformer add @backstage/plugin-catalog-backend-module-keycloak-org
  3. Refer to the sample plugin and implement plugins/catalog-backend-module-keycloak-org-transformer/src/module.ts.
  4. Package and export the plugin as a Dynamic Plugin, and embed the required package for the custom transformer.

    $ npx @red-hat-developer-hub/cli@latest plugin export \
      --embed-package @backstage/plugin-catalog-backend-module-keycloak-org
    Important

    Verify that the installed plugin version is compatible with the Backstage version.

    See the Dynamic plugins reference for the version to import.

  5. Publish and enable the plugin in Developer Hub. For more information, see Installing and viewing plugins in Red Hat Developer Hub.

Verification

  1. Every time that Developer Hub starts, it imports the users and groups. Check the console logs to verify the synchronization result.

    Successful synchronization example:

    {"class":"KeycloakOrgEntityProvider","level":"info","message":"Read 3 Keycloak users and 2 Keycloak groups in 1.5 seconds. Committing...","plugin":"catalog","service":"backstage","taskId":"KeycloakOrgEntityProvider:default:refresh","taskInstanceId":"bf0467ff-8ac4-4702-911c-380270e44dea","timestamp":"2024-09-25 13:58:04"}
    {"class":"KeycloakOrgEntityProvider","level":"info","message":"Committed 3 Keycloak users and 2 Keycloak groups in 0.0 seconds.","plugin":"catalog","service":"backstage","taskId":"KeycloakOrgEntityProvider:default:refresh","taskInstanceId":"bf0467ff-8ac4-4702-911c-380270e44dea","timestamp":"2024-09-25 13:58:04"}
  2. After the first import is complete, go to the Catalog page and select User to view the list of users.
  3. When you select a user, you see the information imported from RHBK. Verify that the user entities reflect the custom transformations you defined in the plugin.
  4. You can select a group, view the list, and access or review the information imported from RHBK. Verify that the group entities reflect the custom transformations you defined in the plugin.
  5. You can log in with an RHBK account.

10.2.5.3. Provision users with LDAP

10.2.5.3.1. Provision users with LDAP

Provision users and groups from your LDAP directory to the Red Hat Developer Hub software catalog to enable user identity resolution and role-based access control.

10.2.5.3.2. Enable user provisioning with LDAP

You can provision users and groups from a Lightweight Directory Access Protocol (LDAP) directory directly to the Red Hat Developer Hub software catalog.

Note

LDAP provisioning works with any authentication provider. You do not need Red Hat Build of Keycloak (RHBK) to use LDAP for user and group provisioning. For example, you can authenticate users with GitHub or Microsoft Azure while provisioning user and group data from your LDAP directory.

Prerequisites

Procedure

  1. Enable the LDAP catalog provider plugin in your dynamic-plugins.yaml file.

    plugins:
      - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-ldap-dynamic'
        disabled: false
  2. Enable provisioning LDAP users and groups to the Developer Hub software catalog, by adding the LDAP catalog provider section to your app-config.yaml file:

    1. Optional: Remove other catalog providers, by removing the other catalog providers section.
    2. Enter the mandatory fields:

      catalog:
        providers:
          ldapOrg:
            default:
              target: ldaps://ds.example.net
              bind:
                dn: cn=admin,ou=Users,dc=rhdh
                secret: ${LDAP_SECRET}
              users:
                - dn: OU=Users,OU=RHDH Local,DC=rhdh,DC=test
                  options:
                    filter: (uid=*)
              groups:
                - dn: OU=Groups,OU=RHDH Local,DC=rhdh,DC=test
              schedule:
                frequency: PT1H
                timeout: PT15M
      target
      Enter your LDAP server URL, such as ldaps://ds.example.net.
      bind

      Enter your service account information:

      dn
      Enter your service account distinguished name (DN), such as cn=admin,OU=Users,DC=rhdh,DC=test
      secret
      Enter the name of the variable containing your LDAP secret: ${LDAP_SECRET}.
      users

      Enter information about how to find your users:

      dn
      Enter the DN containing the user information.
      options
      filter
      Enter your filter, such as (uid=*) to provision to the RHDH software catalog only users with an existing uid.
      groups

      Enter information about how to find your groups:

      dn
      Enter the DN containing the group information.
      schedule

      Enter your schedule information:

      frequency
      Enter your schedule frequency, in the cron, ISO duration, or "human duration" format.
      timeout
      Enter your schedule timeout, in the ISO duration or "human duration" format.
      initialDelay
      Enter your schedule initial delay, in the ISO duration or "human duration" format.
    3. Optional: To change how Developer Hub maps LDAP user fields to the software catalog, enter optional maps and set fields.

      catalog:
        providers:
          ldapOrg:
            default:
              target: ldaps://ds.example.net
              bind:
                dn: cn=admin,ou=Users,dc=rhdh
                secret: ${LDAP_SECRET}
              users:
                - dn: OU=Users,OU=RHDH Local,DC=rhdh,DC=test
                  options:
                    filter: (uid=*)
                  map:
                    rdn: uid
                    name: uid
                    description: {}
                    displayName: cn
                    email: mail
                    picture: {}
                    memberOf: memberOf
                  set:
                    metadata.customField: 'hello'
              groups:
                - dn: OU=Groups,OU=RHDH Local,DC=rhdh,DC=test
              schedule:
                frequency: PT1H
                timeout: PT15M
      rdn
      To change the default value: uid, enter the relative distinguished name of each entry.
      name
      To change the default value: uid, enter the LDAP field to map to the RHDH metadata.name field.
      description
      To set a value, enter the LDAP field to map to the RHDH metadata.description field.
      displayName
      To change the default value: cn, enter the LDAP field to map to the RHDH metadata.displayName field.
      email
      To change the default value: mail, enter the LDAP field to map to the RHDH spec.profile.email field.
      picture
      To set a value, enter the LDAP field to map to the RHDH spec.profile.picture field.
      memberOf
      To change the default value: memberOf, enter the LDAP field to map to the RHDH spec.memberOf field.
      set
      To set a value, enter the hard coded JSON to apply to the entities after ingestion, such as metadata.customField: 'hello'.
    4. Optional: To change how Developer Hub maps LDAP group fields to the software catalog, enter optional groups.maps fields.

      catalog:
        providers:
          ldapOrg:
            default:
              target: ldaps://ds.example.net
              bind:
                dn: cn=admin,ou=Users,dc=rhdh
                secret: ${LDAP_SECRET}
              users:
                - dn: OU=Users,OU=RHDH Local,DC=rhdh,DC=test
                  options:
                    filter: (uid=*)
              groups:
                - dn: OU=Groups,OU=RHDH Local,DC=rhdh,DC=test
                  map:
                    rdn: uid
                    name: uid
                    description: {}
                    displayName: cn
                    email: mail
                    picture: {}
                    memberOf: memberOf
                    members: member
                    type: groupType
                  set:
                    metadata.customField: 'hello'
              schedule:
                frequency: PT1H
                timeout: PT15M
      rdn
      To change the default value: cn, enter the relative distinguished name of each entry.
      name
      To change the default value: cn, enter the LDAP field to map to the RHDH metadata.name field.
      description
      To set a value, enter the LDAP field to map to the RHDH metadata.description field.
      displayName
      To change the default value: cn, enter the LDAP field to map to the RHDH metadata.displayName field.
      email
      To change the default value: mail, enter the LDAP field to map to the RHDH spec.profile.email field.
      picture
      To set a value, enter the LDAP field to map to the RHDH spec.profile.picture field.
      memberOf
      To change the default value: memberOf, enter the LDAP field to map to the RHDH spec.memberOf field.
      members
      To change the default value: member, enter the LDAP field to map to the RHDH spec.children field.
      type
      To change the default value: groupType, enter the LDAP field to map to the RHDH spec.type field.
      set
      To set a value, enter the hard coded JSON to apply to the entities after ingestion, such as metadata.customField: 'hello'.
    5. Recommended: To use a secure LDAP connection (ldaps://), enter optional tls fields.

      catalog:
        providers:
          ldapOrg:
            default:
              target: ldaps://ds.example.net
              bind:
                dn: cn=admin,ou=Users,dc=rhdh
                secret: ${LDAP_SECRET}
              users:
      ldapOrg:
        default:
          tls:
            rejectUnauthorized: true
            keys: '/path/to/keys.pem'
            certs: '/path/to/certs.pem'
      rejectUnauthorized

      Set to false to allow self-signed certificates

      Warning

      This option is not recommended for production.

      keys
      Enter a file containing private keys in PEM format
      certs
      Enter a file containing cert chains in PEM format
    6. Optional: Enter configuration for vendor-specific attributes to set custom attribute names for distinguished names (DN) and universally unique identifiers (UUID) in LDAP directories. Default values are defined per supported vendor and automatically detected.

      catalog:
        providers:
          ldapOrg:
            default:
              vendor:
                dnAttributeName: customDN
                uuidAttributeName: customUUID
      dnAttributeName
      Enter the attribute name that holds the distinguished name (DN) for an entry.
      uuidAttributeName
      Enter the attribute name that holds a universal unique identifier (UUID) for an entry.
    7. Optional: Enter low level users and groups configuration in the options subsection.

      catalog:
        providers:
          ldapOrg:
            default:
              target: ldaps://ds.example.net
              bind:
                dn: cn=admin,ou=Users,dc=rhdh
                secret: ${LDAP_SECRET}
              users:
                options:
                  scope: sub
                  filter: (uid=*)
                  attributes:
                    - cn
                    - uid
                    - description
                  paged:
                  pageSize: 500
              groups:
                options:
                  scope: sub
                  filter: (cn=*)
                  attributes:
                    - cn
                    - uid
                    - description
                  paged:
                    pageSize: 500
                    pagePause: true
      scope
      To change the default value: one, enter how deep the search should go within the directory tree:
  3. base to search only the base DN.
  4. one to search one level below the base DN.
  5. sub to search all descendant entries.

    filter
    To change the default value: (objectclass=*), enter your LDAP filter. With the default mapping:
  6. For users, enter (uid=*) to make sure only users with valid uid field is synced, since users without uid will cause error and ingestion fails.
  7. For groups, enter (cn=*)

    Tip

    When you change the mapping, also update the filter.

    attributes
    To change the default value: all attributes ['*', '+'], enter the array of attribute names to import from LDAP.
    paged

    Enter a value to enable paged results.

    pageSize
    Enter a value to set the results page size, such as 500.
    pagePause
    Enter true to tell the client to wait for the asynchronous results of the next page, when the page limit has been reached.
  8. Recommended: To use a secure LDAP connection (ldaps://), mount your LDAP certificates and keys files in your Developer Hub deployment, by editing your Backstage custom resource.

    kind: Backstage
    spec:
      application:
        extraFiles:
          mountPath: /opt/ldap-secrets
          secrets:
            - name: my-rhdh-database-database-secrets
              key: ldap-certs.pem, ldap-keys.pem

Verification

  • To verify user and group provisioning, check the console logs.

    Successful synchronization example:

    2025-10-15T20:45:49.072Z catalog info Read 4 LDAP users and 6 LDAP groups in 0.3 seconds. Committing... class="LdapOrgEntityProvider" taskId="LdapOrgEntityProvider:default:refresh" taskInstanceId="9bb48fd5-2f55-4096-9fd0-61cee6679952" trace_id="6a318e2eadba84e20df773948668aa4c" span_id="cbec568cb6e64985" trace_flags="01"
    2025-10-15T20:45:49.075Z catalog info Committed 4 LDAP users and 6 LDAP groups in 0.0 seconds. class="LdapOrgEntityProvider" taskId="LdapOrgEntityProvider:default:refresh" taskInstanceId="9bb48fd5-2f55-4096-9fd0-61cee6679952" trace_id="6a318e2eadba84e20df773948668aa4c" span_id="cbec568cb6e64985" trace_flags="01"
10.2.5.3.3. Create a custom transformer to provision users from LDAP to the software catalog

Customize how Red Hat Developer Hub provisions users and groups to Developer Hub software catalog entities, by creating a backend module plugin that uses the ldapOrgEntityProviderTransformsExtensionPoint to offer custom user and group transformers for the LDAP backend.

Procedure

  1. Create a new backend module:

    $ yarn new
    ? What type of module would you like to create? backend-plugin-module
    ? Enter the ID if the plugin [required]? catalog
    ? Enter the ID of the module [required]? ldap-transformer

    The command creates a plugin named catalog-backend-module-ldap-transformer.

  2. Install required packages:

    $ yarn --cwd plugins/catalog-backend-module-ldap-transformer add @backstage/plugin-catalog-backend-module-ldap
  3. Refer to the sample plugin and implement plugins/catalog-backend-module-ldap-transformer/src/module.ts.
  4. Package and export the plugin as a Dynamic Plugin, and embed the required package for the custom transformer.

    $ npx @red-hat-developer-hub/cli@latest plugin export \
      --embed-package @backstage/plugin-catalog-backend-module-ldap
    Important

    Verify that the installed plugin version is compatible with the Backstage version.

    See the Dynamic plugins reference for the version to import.

  5. Publish and enable the plugin in Developer Hub. For more information, see Installing and viewing plugins in Red Hat Developer Hub.

Verification

  1. Every time that Developer Hub starts, it imports the users and groups. Check the console logs to verify the synchronization result.
  2. After the first import is complete, go to the Catalog page and select User to view the list of users.
  3. When you select a user, you see the information imported from LDAP. Verify that the user entities reflect the custom transformations you defined in the plugin.
  4. You can select a group, view the list, and access or review the information imported from LDAP. Verify that the group entities reflect the custom transformations you defined in the plugin.
  5. You can log in with an LDAP account.

10.2.5.4. Import users and groups from GitHub

10.2.5.4.1. Import users and groups from GitHub

Import users and groups from GitHub to the Red Hat Developer Hub software catalog to enable user identity resolution and role-based access control.

10.2.5.4.2. Import users and groups from GitHub

Import GitHub users and groups to the Red Hat Developer Hub software catalog.

Prerequisites

Procedure

  1. Enable the GitHub catalog provider plugin in your dynamic-plugins.yaml file.

    plugins:
      - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic'
        disabled: false
  2. Add a GitHub catalog provider and integration section to your app-config.yaml file:

    catalog:
      providers:
        githubOrg:
          id: githuborg
          githubUrl: "${GITHUB_URL}"
          orgs: [ "${GITHUB_ORG}" ]
          schedule:
            frequency:
              minutes: 30
            initialDelay:
              seconds: 15
            timeout:
              minutes: 15
    integrations:
      github:
        - host: "${GITHUB_URL}"
          apps:
            - appId: ${GITHUB_APP_APP_ID}
              clientId: ${GITHUB_APP_CLIENT_ID_INTEGRATION}
              clientSecret: ${GITHUB_APP_CLIENT_SECRET_INTEGRATION}
              privateKey: |
                ${GITHUB_APP_PRIVATE_KEY}
    id

    Enter a stable identifier for this provider, such as githuborg.

    Warning

    Entities from this provider are associated with this identifier. Therefore, do not to change the identifier over time since that might lead to orphaned entities or conflicts.

    githubUrl
    Enter the configured secret variable name: ${GITHUB_URL}.
    orgs
    Enter the configured secret variable name: ${GITHUB_ORG}.
    schedule.frequency
    Enter your schedule frequency, in the cron, ISO duration, or "human duration" format.
    schedule.timeout
    Enter your schedule timeout, in the ISO duration or "human duration" format.
    schedule.initialDelay
    Enter your schedule initial delay, in the ISO duration or "human duration" format.
    integrations.github.host
    Enter the configured secret variable name: ${GITHUB_URL}.
    integrations.github.apps.appId
    Enter the configured secret variable name: ${GITHUB_APP_APP_ID}.
    integrations.github.apps.clientId
    Enter the configured secret variable name: ${GITHUB_APP_CLIENT_ID_INTEGRATION}.
    integrations.github.apps.clientSecret
    Enter the configured secret variable name: ${GITHUB_APP_CLIENT_SECRET_INTEGRATION}.
    integrations.github.apps.privateKey
    Enter the configured secret variable name: ${GITHUB_APP_PRIVATE_KEY}.

Verification

  • Check user and group provisioning in the console logs.

    Successful synchronization example:

    {"class":"GithubMultiOrgEntityProvider","level":"info","message":"Reading GitHub users and teams for org: rhdh-dast","plugin":"catalog","service":"backstage","target":"https://github.com","taskId":"GithubMultiOrgEntityProvider:githuborg:refresh","taskInstanceId":"801b3c6c-167f-473b-b43e-e0b4b780c384","timestamp":"2024-09-09 23:55:58"}
    {"class":"GithubMultiOrgEntityProvider","level":"info","message":"Read 7 GitHub users and 2 GitHub groups in 0.4 seconds. Committing...","plugin":"catalog","service":"backstage","target":"https://github.com","taskId":"GithubMultiOrgEntityProvider:githuborg:refresh","taskInstanceId":"801b3c6c-167f-473b-b43e-e0b4b780c384","timestamp":"2024-09-09 23:55:59"}
10.2.5.4.3. Create a custom transformer to provision users from GitHub to the software catalog

Customize how Red Hat Developer Hub provisions users and groups to Developer Hub software catalog entities, by creating a backend module plugin that uses the githubOrgEntityProviderTransformsExtensionPoint to offer custom user and group transformers for the GitHub backend.

Procedure

  1. Create a new backend module:

    $ yarn new
    ? What type of module would you like to create? backend-plugin-module
    ? Enter the ID if the plugin [required]? catalog
    ? Enter the ID of the module [required]? github-org-transformer

    The command creates a plugin named catalog-backend-module-github-org-transformer.

  2. Install required packages:

    $ yarn --cwd plugins/catalog-backend-module-github-org-transformer add @backstage/plugin-catalog-backend-module-github-org
  3. (Optional) Install recommended packages to extend the default transformers or Transformer type checking:

    $ yarn --cwd plugins/catalog-backend-module-github-org-transformer add @backstage/plugin-catalog-backend-module-github
  4. (Optional) Install recommended packages for UserEntity or GroupEntity type checking:

    $ yarn --cwd plugins/catalog-backend-module-github-org-transformer add @backstage/catalog-model
  5. Refer to the sample plugin and implement your custom plugins/catalog-backend-module-github-org-transformer/src/module.ts and make your required transformations to user and group entities.
  6. Package and export the plugin as a Dynamic Plugin, and embed the required package for the custom transformer.

    $ npx @red-hat-developer-hub/cli@latest plugin export \
      --embed-package @backstage/plugin-catalog-backend-module-github \
      --embed-package @backstage/plugin-catalog-backend-module-github-org
    Important

    Verify that the installed plugin version is compatible with the Backstage version.

    See the Dynamic plugins reference for the version to import.

  7. Publish and enable the plugin in Developer Hub. For more information, see Installing and viewing plugins in Red Hat Developer Hub.

Verification

  1. Every time that Developer Hub starts, it imports the users and groups. Check the console logs to verify the synchronization result.
  2. After the first import is complete, go to the Catalog page and select User to view the list of users.
  3. When you select a user, you see the information imported from GitHub. Verify that the user entities reflect the custom transformations you defined in the plugin.
  4. You can select a group, view the list, and access or review the information imported from GitHub. Verify that the group entities reflect the custom transformations you defined in the plugin.
  5. You can log in with a GitHub account.

10.2.5.5. Import users and groups from Microsoft Azure

10.2.5.5.1. Import users and groups from Microsoft Azure

Import users and groups from Microsoft Azure to the Red Hat Developer Hub software catalog to enable user identity resolution and role-based access control.

10.2.5.5.2. Import users and groups from Microsoft Azure

Import Microsoft Azure users and groups to the Red Hat Developer Hub software catalog.

Prerequisites

Procedure

  1. Enable the Microsoft Graph catalog provider plugin in your dynamic-plugins.yaml file.

    plugins:
      - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-msgraph-dynamic'
        disabled: false
  2. Add a Microsoft Graph catalog provider section to your app-config.yaml file:

    catalog:
      providers:
        microsoftGraphOrg:
          providerId:
            target: https://graph.microsoft.com/v1.0
            tenantId: ${MICROSOFT_TENANT_ID}
            clientId: ${MICROSOFT_CLIENT_ID}
            clientSecret: ${MICROSOFT_CLIENT_SECRET}
            schedule:
              frequency:
                hours: 1
              timeout:
                minutes: 50
              initialDelay:
                minutes: 50
    target
    Enter https://graph.microsoft.com/v1.0 to define the MSGraph API endpoint the provider is connecting to. You might change this parameter to use a different version, such as the beta endpoint.
    tenantId
    Enter the configured secret variable name: ${MICROSOFT_TENANT_ID}.
    clientId
    Enter the configured secret variable name: ${MICROSOFT_CLIENT_ID}.
    clientSecret
    Enter the configured secret variable name: ${MICROSOFT_CLIENT_SECRET}.
    schedule
    frequency
    Enter the schedule frequency in the cron, ISO duration, or human duration format. In a large organization, user provisioning might take a long time, therefore avoid using a low value.
    timeout
    Enter the schedule timeout in the ISO duration or human duration format. In a large organization, user provisioning might take a long time, therefore avoid using a low value.
    initialDelay
    Enter the schedule initial delay in the ISO duration or human duration format.
  3. Optional: Add optional fields to the Microsoft authentication provider section in your app-config.yaml file:

    catalog:
      providers:
        microsoftGraphOrg:
          providerId:
            authority: https://login.microsoftonline.com/
            queryMode: advanced
            user:
              expand: manager
              filter: accountEnabled eq true and userType eq 'member'
              loadPhotos: true
              select: ['id', 'displayName', 'description']
            userGroupMember:
              filter: "displayName eq 'Backstage Users'"
              search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
            group:
              expand: member
              filter: securityEnabled eq false and mailEnabled eq true and groupTypes/any(c:c+eq+'Unified')
              search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")'
              select: ['id', 'displayName', 'description']
    authority
    Enter your Azure authority URL if it is different from the default: https://login.microsoftonline.com.
    queryMode
    Enter advanced when the default basic query mode is insufficient for your queries to the Microsoft Graph API. See Microsoft Azure advanced queries.
    user

    Add this section to configure optional user query parameters.

    expand

    Enter your expansion parameter to include the expanded resource or collection referenced by a single relationship (navigation property) in your results. A single request can expand only one relationship. See Microsoft Graph query expand parameter.

    You can combine this parameter with userGroupMember.filter or user.filter.

    filter

    Enter your user filter. See Microsoft Graph API and Microsoft Graph API query filter parameters syntax.

    This parameter and userGroupMember.filter are mutually exclusive, specify only one.

    loadPhotos
    Developer Hub loads photos by default. Enter false to avoid loading user photos.
    select
    Enter the Microsoft Graph resource type list to retrieve.
    userGroupMember

    Add this section to use group membership to get users.

    filter

    Enter your filter to filter groups and fetch their members.

    This parameter and user.filter are mutually exclusive, specify only one.

    search

    Enter your search query to search for groups and fetch their members.

    This parameter and user.filter are mutually exclusive, specify only one.

    group

    Enter your configuration to get groups.

    expand

    Enter your expansion parameter to include the expanded resource or collection referenced by a single relationship (navigation property) in your results. A single request can expand only one relationship. See Customize Microsoft Graph responses with query parameters.

    You can combine this parameter with user.filter or userGroupMember.filter.

    filter
    Enter your group filter parameter. See Microsoft Graph API query group syntax.
    search
    Enter your group search parameter. See Microsoft Graph API query search parameter.
    select
    Enter the Microsoft Graph resource type list to retrieve.

Verification

  • Check the console logs for MicrosoftGraphOrgEntityProvider events.

    Successful synchronization example:

    2025-06-23T13:37:55.804Z catalog info Read 9 msgraph users and 3 msgraph groups in 1.5 seconds. Committing... class="MicrosoftGraphOrgEntityProvider" taskId="MicrosoftGraphOrgEntityProvider:providerId:refresh" taskInstanceId="e104a116-6481-4ceb-9bc4-0f8f9581f959" trace_id="e4c633659cffd6b1529afa55a5bfbad7" span_id="76affd0420e8baa6" trace_flags="01"
    
    2025-06-23T13:37:55.811Z catalog info Committed 9 msgraph users and 3 msgraph groups in 0.0 seconds. class="MicrosoftGraphOrgEntityProvider" taskId="MicrosoftGraphOrgEntityProvider:providerId:refresh" taskInstanceId="e104a116-6481-4ceb-9bc4-0f8f9581f959" trace_id="e4c633659cffd6b1529afa55a5bfbad7" span_id="76affd0420e8baa6" trace_flags="01"
10.2.5.5.3. Create a custom transformer to provision users from Azure to the software catalog

Customize how Red Hat Developer Hub provisions users and groups to Developer Hub software catalog entities, by creating a backend module plugin that uses the microsoftGraphOrgEntityProviderTransformExtensionPoint to offer custom user and group transformers for the Azure backend.

Procedure

  1. Create a new backend module:

    $ yarn new
    ? What type of module would you like to create? backend-plugin-module
    ? Enter the ID if the plugin [required]? catalog
    ? Enter the ID of the module [required]? msgraph-transformer

    The command creates a plugin named catalog-backend-module-msgraph-transformer.

  2. Install required packages:

    $ yarn --cwd plugins/catalog-backend-module-msgraph-transformer add @backstage/plugin-catalog-backend-module-msgraph
  3. (Optional) Install recommended packages for UserEntity or GroupEntity type checking:

    $ yarn --cwd plugins/catalog-backend-module-msgraph-transformer add @backstage/catalog-model
  4. Refer to the sample plugin and implement plugins/catalog-backend-module-msgraph-transformer/src/module.ts.
  5. Package and export the plugin as a Dynamic Plugin, and embed the required package for the custom transformer.

    $ npx @red-hat-developer-hub/cli@latest plugin export \
      --embed-package @backstage/plugin-catalog-backend-module-msgraph
    Important

    Verify that the installed plugin version is compatible with the Backstage version.

    See the Dynamic plugins reference for the version to import.

  6. Publish and enable the plugin in Developer Hub. For more information, see Installing and viewing plugins in Red Hat Developer Hub.

Verification

  1. Every time that Developer Hub starts, it imports the users and groups. Check the console logs to verify the synchronization result.
  2. After the first import is complete, go to the Catalog page and select User to view the list of users.
  3. When you select a user, you see the information imported from Microsoft Entra ID. Verify that the user entities reflect the custom transformations you defined in the plugin.
  4. You can select a group, view the list, and access or review the information imported from Microsoft Azure. Verify that the group entities reflect the custom transformations you defined in the plugin.
  5. You can log in with an Entra ID account.

10.2.5.6. Import users and groups from GitLab

10.2.5.6.1. Import users and groups from GitLab

Import users and groups from GitLab to the Red Hat Developer Hub software catalog to enable user identity resolution and role-based access control.

10.2.5.6.2. Import users and groups from GitLab

Import GitLab users and groups to the Red Hat Developer Hub software catalog.

Prerequisites

Procedure

  • Add a GitLab catalog provider and integration section to your RHDH app-config.yaml file:

    catalog:
      providers:
        gitlab:
          default:
            host: ${GITLAB_HOST}
            orgEnabled: true
            group: ${GITLAB_PARENT_ORG}
            relations:
              - INHERITED
              - DESCENDANTS
              - SHARED_FROM_GROUPS
            groupPattern: [\s\S]*
            restrictUsersToGroup: true
            includeUsersWithoutSeat: true
            schedule:
              initialDelay:
                seconds: 0
              frequency:
                minutes: 50
              timeout:
                minutes: 50
    integrations:
      gitlab:
        - host: ${GITLAB_HOST}
          token: ${GITLAB_TOKEN}
    host
    Enter your GitLab instance address: ${GITLAB_HOST}.
    orgEnabled
    Set to true to enable the ingestion of GitLab organizational data, such as users and groups. For the GitLab site, you must also provide a value for the group parameter.
    group
    Enter your configured GitLab parent group: ${GITLAB_PARENT_ORG}.
    relations

    Optional. Specify the types of group memberships to include during ingestion. You can use the following values:

    INHERITED
    Optional. Includes members of any ancestor groups as members of the current group.
    DESCENDANTS
    Optional. Includes members of any descendant groups as members of the current group.
    SHARED_FROM_GROUPS
    Optional. Includes members of any invited groups as members of the current group.
    groupPattern
    Optional. Filters found groups based on provided pattern. Defaults to [\s\S]*, which means to not filter anything.
    restrictUsersToGroup
    Set to true to import only users who are direct members of the configured group.
    includeUsersWithoutSeat
    Set to true to include users who do not occupy a paid seat. This setting applies only to GitLab SaaS.
    schedule.initialDelay
    Enter your schedule initial delay, in the ISO duration or HumanDuration format.
    schedule.frequency
    Enter your schedule frequency, in the cron, ISO duration, or HumanDuration format.
    schedule.timeout
    Enter your schedule timeout, in the ISO duration or HumanDuration format.
    integrations.gitlab.host
    Enter your GitLab instance address: ${GITLAB_HOST}.
    integrations.gitlab.token
    Enter the configured secret variable name: ${GITLAB_TOKEN}.

Verification

  • Open RHDH and wait for first ingestion.
10.2.5.6.3. Create a custom transformer to provision users from GitLab to the software catalog

Customize how Red Hat Developer Hub provisions users and groups to Developer Hub software catalog entities, by creating a backend module plugin that uses the gitlabOrgEntityProviderTransformsExtensionPoint to offer custom user and group transformers for the GitLab backend.

Procedure

  1. Create a new backend module:

    $ yarn new
    ? What type of module would you like to create? backend-plugin-module
    ? Enter the ID if the plugin [required]? catalog
    ? Enter the ID of the module [required]? gitlab-org-transformer

    The command creates a plugin named catalog-backend-module-gitlab-org-transformer.

  2. Install required packages:

    $ yarn --cwd plugins/catalog-backend-module-gitlab-org-transformer add @backstage/plugin-catalog-backend-module-gitlab-org
  3. (Optional) Install recommended packages to extend the default transformers or Transformer type checking:

    $ yarn --cwd plugins/catalog-backend-module-gitlab-org-transformer add @backstage/plugin-catalog-backend-module-gitlab
  4. (Optional) Install recommended packages for UserEntity or GroupEntity type checking:

    $ yarn --cwd plugins/catalog-backend-module-gitlab-org-transformer add @backstage/catalog-model
  5. Refer to the sample plugin and implement plugins/catalog-backend-module-gitlab-org-transformer/src/module.ts.
  6. Package and export the plugin as a Dynamic Plugin, and embed the required package for the custom transformer.

    $ npx @red-hat-developer-hub/cli@latest plugin export \
      --embed-package @backstage/plugin-catalog-backend-module-gitlab \
      --embed-package @backstage/plugin-catalog-backend-module-gitlab-org \
      --ignore-version-check @backstage/backend-defaults
    Important

    Verify that the installed plugin version is compatible with the Backstage version.

    See the Dynamic plugins reference for the version to import.

  7. Publish and enable the plugin in Developer Hub. For more information, see Installing and viewing plugins in Red Hat Developer Hub.

Verification

  1. Every time that Developer Hub starts, it imports the users and groups. Check the console logs to verify the synchronization result.
  2. After the first import is complete, go to the Catalog page and select User to view the list of users.
  3. When you select a user, you see the information imported from GitLab. Verify that the user entities reflect the custom transformations you defined in the plugin.
  4. You can select a group, view the list, and access or review the information imported from GitLab. Verify that the group entities reflect the custom transformations you defined in the plugin.
  5. You can log in with a GitLab account.

10.2.6. Enable authentication to verify identities against enterprise directories

10.2.6.1. Enable authentication to verify identities against enterprise directories

Enable authentication with your main identity provider to allow users to sign in to Red Hat Developer Hub using their organizational credentials.

10.2.6.2. Enable authentication with Red Hat Build of Keycloak (RHBK)

Configure Red Hat Build of Keycloak (RHBK) as your Red Hat Developer Hub sign-in provider by enabling the OIDC authentication provider.

Procedure

  1. The OIDC provider authentication backend plugin requires Developer Hub to support sessions. Enable session support by adding the session secret to your app-config.yaml file:

    auth:
      session:
        secret: ${SESSION_SECRET}
  2. Add an OIDC provider section to your app-config.yaml file:

    auth:
      environment: production
      providers:
        oidc:
          production:
            metadataUrl: ${KEYCLOAK_BASE_URL}
            clientId: ${KEYCLOAK_CLIENT_ID}
            clientSecret: ${KEYCLOAK_CLIENT_SECRET}
            prompt: auto
    signInPage: oidc
    environment: production
    Mark the environment as production to hide the Guest login in the Developer Hub home page.
    metadataUrl, clientId, clientSecret
    Configure the OIDC provider with your secrets.
    prompt

    Enter auto to allow the identity provider to automatically determine whether to prompt for credentials or bypass the login redirect if an active RHBK session exists.

    The identity provider defaults to none, which assumes that you are already logged in. Sign-in requests without an active session are rejected.

    signInPage
    Enter oidc to enable the OIDC provider as default sign-in provider.
  3. Optional: Add optional fields to the OIDC authentication provider section in your app-config.yaml file:

    auth:
      providers:
        oidc:
          production:
            metadataUrl: ${KEYCLOAK_BASE_URL}
            clientId: ${KEYCLOAK_CLIENT_ID}
            clientSecret: ${KEYCLOAK_CLIENT_SECRET}
            callbackUrl: ${KEYCLOAK_CALLBACK_URL}
            tokenEndpointAuthMethod: ${KEYCLOAK_TOKEN_ENDPOINT_METHOD}
            tokenSignedResponseAlg: ${KEYCLOAK_SIGNED_RESPONSE_ALG}
            additionalScopes: ${KEYCLOAK_SCOPE}
            signIn:
              resolvers:
                - resolver: oidcSubClaimMatchingKeycloakUserId
                - resolver: preferredUsernameMatchingUserEntityName
                - resolver: emailMatchingUserEntityProfileEmail
                - resolver: emailLocalPartMatchingUserEntityName
                  dangerouslyAllowSignInWithoutUserInCatalog: true
            sessionDuration: { hours: 24 }
      backstageTokenExpiration: { minutes: _<user_defined_value>_ }
    signInPage: oidc
    callbackUrl
    RHBK callback URL.
    tokenEndpointAuthMethod
    Enter your token endpoint authentication method.
    tokenSignedResponseAlg
    Token signed response algorithm.
    additionalScopes
    Enter additional RHBK scopes to request for during the authentication flow.
    signIn
    resolvers

    After successful authentication, the user signing in must be resolved to an existing user in the Developer Hub catalog. To best match users securely for your use case, consider configuring a specific resolver.

    Enter the resolver list to override the default resolver: oidcSubClaimMatchingKeycloakUserId.

    Available values:

    oidcSubClaimMatchingKeycloakUserId
    Matches the user with the immutable sub parameter from OIDC to the RHBK user ID. Consider using this resolver for enhanced security.
    oidcLdapUuidMatchingAnnotation

    Matches the user by their immutable LDAP UUID. Requires a custom client scope in Red Hat Build of Keycloak.

    For setup instructions, see Match users by LDAP UUID with Red Hat Build of Keycloak.

    emailLocalPartMatchingUserEntityName
    Matches the email local part with the user entity name.
    emailMatchingUserEntityProfileEmail
    Matches the email with the user entity profile email.
    preferredUsernameMatchingUserEntityName

    Matches the preferred username with the user entity name.

    The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed.

    Warning

    In production mode, configure only one resolver to make sure users are securely matched.

    dangerouslyAllowSignInWithoutUserInCatalog: true

    Configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.

    Warning

    In production mode, do not enable the dangerouslyAllowSignInWithoutUserInCatalog option.

    sessionDuration
    Lifespan of the user session. Enter a duration in ms library format (such as '24h', '2 days'), ISO duration, or "human duration" as used in code.
    backstageTokenExpiration

    Enter a value to modify the Developer Hub token expiration from its default value of one hour. It refers to the validity of short-term cryptographic tokens, not to the session duration. The expiration value must be set between 10 minutes and 24 hours.

    Warning

    If multiple valid refresh tokens are issued due to frequent refresh token requests, older tokens will remain valid until they expire. Enhance security and prevent potential misuse of older tokens by enabling a refresh token rotation strategy in your RHBK realm.

    1. From the Configure section of the navigation menu, click Realm Settings.
    2. From the Realm Settings page, click the Tokens tab.
    3. From the Refresh tokens section of the Tokens tab, toggle the Revoke Refresh Token to the Enabled position.
  4. To disable the guest login option, in the app-config.yaml file, set the authentication environment to production:

    auth:
      environment: production

Verification

  1. Go to the Developer Hub login page.
  2. Your Developer Hub sign-in page displays Sign in using OIDC and the Guest user sign-in is disabled.
  3. Log in with OIDC by using the saved Username and Password values.

10.2.6.3. Match users by LDAP UUID with Red Hat Build of Keycloak

When you use Red Hat Build of Keycloak with LDAP user federation, configure the oidcLdapUuidMatchingAnnotation sign-in resolver to match users by their immutable LDAP UUID for secure user resolution. This requires a custom client scope in Red Hat Build of Keycloak that exposes the LDAP UUID as a token claim.

Prerequisites

  • LDAP user federation is configured in Red Hat Build of Keycloak.
  • LDAP provisioning is enabled in Red Hat Developer Hub. For more information, see Enable user provisioning with LDAP.
  • A Red Hat Developer Hub client is created in Red Hat Build of Keycloak.

Procedure

  1. In the Red Hat Build of Keycloak admin console, go to Client scopes and click Create client scope. Name the scope ldap_uuid.
  2. In the ldap_uuid scope, click the Mappers tab, then click Add mapper > Configure a new mapper > User Attribute. Configure the mapper with the following values:

    • Name: LDAP_ID
    • User Attribute: LDAP_ID
    • Token Claim Name: ldap_uuid
    • Claim JSON Type: String
    • Add to ID token: ON
    • Add to userinfo: ON
  3. Go to Clients > your Red Hat Developer Hub client > Client scopes. Click Add client scope and add ldap_uuid as a Default scope.
  4. Optional: Add the oidcLdapUuidMatchingAnnotation resolver to your app-config.yaml file, to replace the default ldap_uuid resolver:

    auth:
      providers:
        oidc:
          production:
            signIn:
              resolvers:
                - resolver: oidcLdapUuidMatchingAnnotation
                  ldapUuidKey: ldap_uuid
    ldapUuidKey
    Enter the token claim name containing the LDAP UUID value. The default value is ldap_uuid. This value must match the Token Claim Name configured in step 2.
  5. Restart the Red Hat Developer Hub application to apply the changes.

10.2.6.4. Enable authentication with GitHub

Configure GitHub as your Red Hat Developer Hub sign-in provider.

Procedure

  1. Add a GitHub authentication provider section to your app-config.yaml file:

    auth:
      environment: production
      providers:
        github:
          production:
            clientId: ${GITHUB_APP_CLIENT_ID}
            clientSecret: ${GITHUB_APP_CLIENT_SECRET}
    signInPage: github
    environment
    Enter production to disable the Guest login option in the Developer Hub login page.
    clientId
    Enter the configured secret variable name: ${GITHUB_APP_CLIENT_ID}.
    clientSecret
    Enter the configured secret variable name: ${GITHUB_APP_CLIENT_SECRET}.
    signInPage
    Enter github to enable the GitHub provider as your Developer Hub sign-in provider.
  2. Optional: Add optional fields to the GitHub authentication provider section in your app-config.yaml file:

    auth:
      environment: production
      providers:
        github:
          production:
            clientId: ${GITHUB_APP_CLIENT_ID}
            clientSecret: ${GITHUB_APP_CLIENT_SECRET}
            callbackUrl: <your_intermediate_service_url/handler>
            sessionDuration: { hours: 24 }
            signIn:
              resolvers:
                - resolver: usernameMatchingUserEntityName
                  dangerouslyAllowSignInWithoutUserInCatalog: true
    signInPage: github
    callbackUrl
    Enter the callback URL that GitHub uses when initiating an OAuth flow, such as: <your_intermediate_service_url/handler>. Define it when Developer Hub is not the immediate receiver, such as in cases when you use one OAuth app for many Developer Hub instances.
    sessionDuration
    Enter the user session lifespan, in ms library format (such as '24h', '2 days'), ISO duration, or "human duration".
    signIn
    resolvers
    After successful authentication, Developer Hub resolves the user signing in to an existing user in the Developer Hub catalog. Configure a specific resolver to best match users securely for your use case..

    Enter the resolver list to override the default resolver: usernameMatchingUserEntityName.

    The authentication provider tries each sign-in resolver in order until it succeeds. If none of the attempts succeed, the sign-in fails.

    Warning

    In production mode, configure only one resolver to make sure users are securely matched.

    resolver
    Enter the sign-in resolver name. Available resolvers: usernameMatchingUserEntityName, preferredUsernameMatchingUserEntityName, emailMatchingUserEntityProfileEmail.
    dangerouslyAllowSignInWithoutUserInCatalog

    Enter true to configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.

    Warning

    In production mode, do not enable dangerouslyAllowSignInWithoutUserInCatalog.

  3. To disable the guest login option, in the app-config.yaml file, set the authentication environment to production:

    auth:
      environment: production

Verification

  1. Go to the Developer Hub login page.
  2. Your Developer Hub sign-in page displays Sign in using GitHub and the Guest user sign-in is disabled.
  3. Log in with a GitHub account.

10.2.6.5. Enable authentication with Microsoft Azure

Configure Microsoft Azure as your Red Hat Developer Hub sign-in provider.

Procedure

  1. Add the Microsoft authentication provider to your app-config.yaml file:

    auth:
      environment: production
      providers:
        microsoft:
          production:
            clientId: ${MICROSOFT_CLIENT_ID}
            clientSecret: ${MICROSOFT_CLIENT_SECRET}
            tenantId: ${MICROSOFT_TENANT_ID}
    signInPage: microsoft
    environment
    Enter production to disable the Guest login option in the Developer Hub login page.
    clientId
    Enter the configured secret variable name: ${MICROSOFT_CLIENT_ID}.
    clientSecret
    Enter the configured secret variable name: ${MICROSOFT_CLIENT_SECRET}.
    tenantId
    Enter the configured secret variable name: ${MICROSOFT_TENANT_ID}.
    signInPage
    Enter microsoft to set the Azure provider as your Developer Hub sign-in provider.
  2. Optional: Add optional fields to the Microsoft authentication provider section in your app-config.yaml file:

    auth:
      environment: production
      providers:
        microsoft:
          production:
            clientId: ${MICROSOFT_CLIENT_ID}
            clientSecret: ${MICROSOFT_CLIENT_SECRET}
            tenantId: ${MICROSOFT_TENANT_ID}
            domainHint: ${MICROSOFT_TENANT_ID}
            additionalScopes:
               - Mail.Send
            sessionDuration:
              hours: 24
            signIn:
              resolvers:
                - resolver: usernameMatchingUserEntityName
                  dangerouslyAllowSignInWithoutUserInCatalog: true
    signInPage: microsoft
    domainHint

    Leave this parameter empty, or enter the tenant ID when your application registration is single-tenant.

    Leave this parameter empty when your application registration is multitenant.

    Enter the tenant ID to reduce login friction for users with accounts in multiple tenants, by automatically filtering out accounts from other tenants. For more information, see Home Realm Discovery.

    additionalScopes
    Enter the list of additional scopes to add scopes for the application registration. The default and mandatory value lists following scopes: openid, offline_access, profile, email, User.Read.
    sessionDuration
    Lifespan of the user session. Enter a duration in ms library (such as '24h', '2 days'), ISO duration, or "human duration" format.
    signIn.resolvers

    After successful authentication, Developer Hub resolves the user signing in to an existing user in the Developer Hub catalog. To best match users securely for your use case, consider configuring a specific resolver.

    Enter the resolver list to override the default resolver: userIdMatchingUserEntityAnnotation.

    The authentication provider tries each sign-in resolver in order until it succeeds, and fails if none succeed.

    Warning

    In production mode, configure only one resolver to make sure users are securely matched.

    resolver

    Enter the sign-in resolver name. Available resolvers:

    emailMatchingUserEntityAnnotation
    Use this resolver to look up the user by matching their Microsoft email to the email entity annotation.
    emailLocalPartMatchingUserEntityName
    Use this resolver to look up the user by matching their Microsoft email user name to the user entity name.
    emailMatchingUserEntityProfileEmail
    Use this resolver to look up the user by matching their Microsoft email to the user entity profile email.
    dangerouslyAllowSignInWithoutUserInCatalog

    Enter true to configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.

    Warning

    In production mode, do not enable dangerouslyAllowSignInWithoutUserInCatalog.

  3. To disable the guest login option, in the app-config.yaml file, set the authentication environment to production:

    auth:
      environment: production

Verification

  1. Go to the Developer Hub login page.
  2. Your Developer Hub sign-in page displays Sign in using Microsoft and the Guest user sign-in is disabled.
  3. Log in with an Azure account.

10.2.6.6. Enable authentication with GitLab

Configure GitLab as your Red Hat Developer Hub sign-in provider.

Procedure

  1. Add a GitLab authentication provider section to your RHDH app-config.yaml file:

    includeTransitiveGroupOwnership: true
    signInPage: gitlab
    auth:
      environment: production
      session:
        secret: <name_of_secret>
      providers:
        gitlab:
          production:
            audience: https://${GITLAB_HOST}
            clientId: ${GITLAB_CLIENT_ID}
            clientSecret: ${GITLAB_CLIENT_SECRET}
            callbackUrl: https://__<my_developer_hub_domain>__/api/auth/gitlab/handler/frame
    audience
    Enter your GitLab instance address: https://${GITLAB_HOST}
    clientId
    Enter the configured client ID: ${GITLAB_CLIENT_ID}.
    clientSecret
    Enter the configured secret variable name: ${GITLAB_CLIENT_SECRET}.
    callbackUrl
    Enter your Developer Hub authentication backend URL: https://<my_developer_hub_domain>/api/auth/gitlab/handler/frame
  2. To disable the guest login option, in the app-config.yaml file, set the authentication environment to production:

    auth:
      environment: production

Verification

  1. Go to the Developer Hub login page.
  2. Your Developer Hub sign-in page displays Sign in using GitLab and the Guest user sign-in is disabled.
  3. Log in with a GitLab account.

10.2.6.7. Enable authentication with PingFederate

You can enable authentication with PingFederate to allow users to sign in to Developer Hub by using their PingFederate credentials and match authenticated users to their LDAP catalog entities.

Prerequisites

Procedure

  1. Configure the LDAP Data Store for binary attributes.

    Configure the Data Store to treat unique identifiers as binary data to ensure they are processed correctly for OGNL transformations.

    1. In PingFederate, go to System > Data Stores and edit your LDAP store.
    2. In Advanced options > LDAP Binary Attributes, add objectGUID to the list.
    3. In the Attribute Source lookup configuration, set the Encoding Type for objectGUID to Hex.
  2. Create the Authentication Policy Contract.

    The contract bridges the LDAP directory and the OIDC policy, transforming the binary GUID into a string format.

    1. Create a new contract named rhdh-contract.
    2. Add an Attribute Source linked to your LDAP Data Store.
    3. Set the Search Filter to sAMAccountName=${username}.
    4. Expose the LDAP UUID attribute (for example, objectGUID for Active Directory) within the contract. Under Contract Fulfillment, map the sub claim to the objectGUID from LDAP by using an Expression source.
    5. Enter the following OGNL expression to format the binary GUID as a UUID string:

      #GUID = #this.get("ds.<ldap-data-source-id>.objectGUID").toString(),
      #GUID.substring(6,8) + #GUID.substring(4,6) + #GUID.substring(2,4) + #GUID.substring(0,2) + "-" +
      #GUID.substring(10,12) + #GUID.substring(8,10) + "-" +
      #GUID.substring(14,16) + #GUID.substring(12,14) + "-" +
      #GUID.substring(16,20) + "-" + #GUID.substring(20,32)

      Replace <ldap-data-source-id> with the ID of your LDAP Data Store in PingFederate.

  3. Configure OAuth and OIDC scopes.

    Ensure PingFederate allows the standard OIDC scopes requested by Developer Hub.

    1. Navigate to System > OAuth Scopes.
    2. Ensure email and profile are added to the Common Scopes list.
  4. Bridge the contract to the OIDC policy.

    Configure the policy to deliver the transformed UUID through the sub claim in the ID token and UserInfo endpoint.

    1. Access Token Mapping: Map the sub field from rhdh-contract to your Access Token Manager.
    2. OIDC Policy Fulfillment: Fulfill the sub claim by selecting Access Token as the source and sub as the value.
    3. Enable Delivery: In the OIDC Policy Attribute Contract, select the ID Token and UserInfo checkboxes for the sub claim.
    4. Extend Contract: Add ldap_uuid to the Attribute Contract and map it to the sub value by using the Access Token to ensure consistency.
  5. Create the OIDC client.

    1. In PingFederate, go to Applications > OAuth Clients and click Add Client.
    2. Under Client Authentication, select Client Secret, generate a secret, and save it.
    3. Enter the Redirect URI: https://<my_developer_hub_domain>/api/auth/oidc/handler/frame.
    4. Under Allowed Grant Types, select Authorization Code.
    5. Under OpenID Connect > Policy, select the OIDC policy you created.
    6. Save the following values for the next step:

      1. Client ID
      2. Client Secret
      3. OIDC metadata URL: The .well-known/openid-configuration endpoint URL for your PingFederate instance.
  6. Create a long, complex, and unique string to use as the Developer Hub session secret key.
  7. Add your PingFederate credentials and the session secret key to Developer Hub, by adding the following key-value pairs to your Developer Hub secrets. You can use these secrets in the Developer Hub configuration files by using their environment variable name.

    AUTH_OIDC_CLIENT_ID
    Enter the saved Client ID.
    AUTH_OIDC_CLIENT_SECRET
    Enter the saved Client Secret.
    AUTH_OIDC_METADATA_URL
    Enter the saved OIDC metadata URL.
    SESSION_SECRET
    Enter the created session secret key.
  8. Enable session support by adding the session secret to your app-config.yaml file:

    auth:
      session:
        secret: ${SESSION_SECRET}
  9. Enable the PingFederate authentication provider with the LDAP UUID matching resolver by adding the OIDC provider section in your app-config.yaml file:

    auth:
      environment: production
      providers:
        oidc:
          production:
            metadataUrl: ${AUTH_OIDC_METADATA_URL}
            clientId: ${AUTH_OIDC_CLIENT_ID}
            clientSecret: ${AUTH_OIDC_CLIENT_SECRET}
            signIn:
              resolvers:
                - resolver: oidcLdapUuidMatchingAnnotation
                  ldapUuidKey: sub
    signInPage: oidc
    environment: production
    Mark the environment as production to hide the Guest login on the Developer Hub home page.
    metadataUrl
    Enter your PingFederate OIDC metadata URL, defined earlier.
    clientId
    Enter your Developer Hub application client ID in PingFederate, defined earlier.
    clientSecret
    Enter your Developer Hub application client secret in PingFederate, defined earlier.
    oidcLdapUuidMatchingAnnotation
    Match the authenticated user to an LDAP catalog entity by using the LDAP UUID. By default, Developer Hub attempts to match the ldap_uuid claim from the UserInfo endpoint to the LDAP catalog entity.
    ldapUuidKey
    Enter the claim key containing the LDAP UUID. Set to sub to use the sub claim, which contains the transformed UUID from the PingFederate policy contract.
    signInPage
    Enter oidc to enable the OIDC provider as the default sign-in provider.

Verification

  1. Go to the Developer Hub login page.
  2. Verify that the Developer Hub sign-in page displays Sign in using OIDC and the Guest user sign-in is disabled.
  3. Log in with OIDC by using your PingFederate user credentials.

10.2.6.8. Enable user authentication with GitHub as an auxiliary authentication provider

If your primary authentication provider is not GitHub, you can configure GitHub as an auxiliary provider to grant users the GitHub permissions needed for templates or plugins, without re-resolving user identities.

Prerequisites

  • You have enough permissions in GitHub to create and manage a GitHub App.

    Tip

    Alternatively, ask your GitHub administrator to prepare the required GitHub App.

  • You have added a custom Developer Hub application configuration, and have enough permissions to change it.
  • You have configured a primary authentication provider to provision user and group identities to the Red Hat Developer Hub software catalog, and establish Developer Hub user sessions.

Procedure

  1. Add the auth.providers.github section to your app-config.yaml file:

    auth:
      providers:
        github:
          production:
            clientId: ${GITHUB_APP_CLIENT_ID}
            clientSecret: ${GITHUB_APP_CLIENT_SECRET}
            disableIdentityResolution: true

    where: clientId:: Enter the configured secret variable name: ${GITHUB_APP_CLIENT_ID}.

    clientSecret
    Enter the configured secret variable name: ${GITHUB_APP_CLIENT_SECRET}.
    disableIdentityResolution
    Enter true to skip user identity resolution for this provider to enable sign-in from an auxiliary authentication provider.
    Warning

    Do not enable this setting on the primary authentication provider you plan on using for sign-in and identity management.

  2. To disable the guest login option, in the app-config.yaml file, set the authentication environment to production:

    auth:
      environment: production

Verification

  1. Go to the Developer Hub login page.
  2. Log in with your primary authentication provider account.
  3. In the top user menu, go to Settings > Authentication Providers.
  4. In the GitHub line, click the Sign in button and log in.
  5. In the GitHub line, the button displays Sign out.

10.2.7. Connect your platform to external identity providers and APIs

10.2.7.1. Connect your platform to external identity providers and APIs

Enable authentication with external services to allow Red Hat Developer Hub to communicate with secondary identity providers and external APIs.

10.2.7.2. Configure service-to-service authentication to secure API calls

10.2.7.2.1. Configure service-to-service authentication to secure API calls

You can configure service-to-service authentication to secure communication between services, including plugin-to-plugin and external-service-to-plugin communication.

Important

The availability of service-to-service authentication might vary for REST APIs. Each plugin defines the restrictions on this feature. Consult your specific plugin’s documentation for detailed limitations.

For example, the RBAC plugin supports exclusively all GET requests, but no POST requests.

10.2.7.2.2. Enable service-to-service authentication by using a static token

You can use a static token to enable service-to-service authentication. This method is simpler to set up than JWKS tokens but requires careful token management to ensure security. * Following security best practices.

Some security best practices when using static tokens include:

Regular rotation
Rotate tokens on a regular schedule to limit the impact of potential leaks. Document the rotation process to ensure consistency.
Secure storage
Never store tokens in plain text in the app-config.yaml configuration file. Instead, use the environment variable mechanism available in Developer Hub.
Access control
Implement the principle of least privilege, restricting tokens to specific plugins and operations; regularly review and update access permissions.
Analyze logs
Monitor and track token usage to identify unusual patterns and set up alerts for failed authentication attempts if you have a monitoring system integration available.
Documentation
Document all authentication methods in use and keep an inventory of all tokens and their purposes, and keep security policies up to date.

Static token authentication might be a good solution for simple, non-critical scenarios, such as:

Development and testing environments
These require quick setup and configuration, simple debugging and troubleshooting, and easy integration with development tools. Static token authentication can be an easy option, especially when using ephemeral testing environments.
Simple automation tasks
Basic CI/CD pipelines, simple maintenance scripts, and basic monitoring systems.
Internal tools and utilities
Development tools, testing frameworks, and internal automation scripts.

However, static token authentication might not be suitable for:

  • Production environments with high security requirements.
  • Systems handling sensitive data.
  • Large-scale deployments with many external services.
  • Environments requiring frequent token rotation.

Prerequisites

  • You have administrative access to configure Developer Hub in your OpenShift cluster.

Procedure

  1. Generate a secure token.

    You can use a tool such as Node.js:

    $ node -p'require('crypto').randomBytes(24).toString('base64')'

    This command generates a 24-byte random value and encodes it in base64 format. The resulting token is sufficiently strong for authentication purposes, and properly encoded for use in HTTP headers.

  2. Add the generated token in your Developer Hub secrets in OpenShift to define the <YOUR_SERVICE_TOKEN_ENV_VAR> environment variable where your services can access it.
  3. Add the generated token or JWKS URL to your app-config.yaml Developer Hub configuration file in OpenShift.

    backend:
      auth:
        - type: static
          options:
            token: "$<YOUR_SERVICE_TOKEN_ENV_VAR>"
            subject: "<your_service_name>"
          accessRestrictions:
            - plugin: "<target_plugin_name>"
    type
    Enter static to specify that authentication is using a static token.
    options

    Enter the configuration options for static token authentication.

    token
    Enter the environment variable name from the earlier step.
    subject
    (Optional) Enter a unique identifier for the service that will be using this token.
    plugin
    (Optional) Enter the name of the target plugin that the service will communicate with.
  4. Use the token in the Authorization header of your service requests.

    When making requests from one service to another, include the static token in the Authorization header as follows:

    Authorization: Bearer <your_generated_token>

    Replace <your_generated_token> with the actual token you generated in step 1.

    For instance, to list all available locations in the catalog by using the curl command, you would use:

    $ curl --location --request GET 'https://<my_developer_hub_domain>/api/catalog/locations' \
    --header 'Content-Type: application/json' \
    --header 'Authorization: Bearer <your_generated_token>'

Verification

  • In the Audit Logs of the service receiving the request, verify that Developer Hub authenticated the request successfully by using the subject value as the actor.
10.2.7.2.3. Enable service-to-service authentication by using JSON web key sets (JWKS) tokens

You can use JSON Web Key Sets (JWKS) tokens to enable service-to-service authentication.

Consider using JWKS tokens when you need a more secure and scalable authentication method compared to static tokens. While JWKS tokens require more setup and configuration, they offer enhanced security features that are crucial for production environments and sensitive applications:

Asymmetric encryption
Your trusted Identity Provider issues JWKS tokens by using asymmetric encryption. JWKS uses a pair of shared keys: one public, one private, instead of a single shared static token. The Identity Provider signs the JSON Web Token (JWT) with its private key, then Developer Hub verifies it using the public key fetched from the JWKS endpoint. Developer Hub can validate these tokens without sharing secret keys directly. This means Developer Hub never has access to the private signing key, reducing the risk of compromise.
Easy key rotation
The Identity Provider can rotate signing keys regularly without requiring changes to Developer Hub afterward. This minimizes downtime and enhances security.
Ability to validate claims
JWKS tokens include claims such as issuer and audience. Developer Hub can verify these claims to ensure the token is from a trusted source and prevent the external service from using the token in unintended contexts.

The diagram illustrates the authentication flow between an external service and Developer Hub:

  • The external service requests, receives, and returns an access token from the identity provider to request a resource from Developer Hub.
  • The identity provider issues a JWKS token signed with its private key, and provides the public key via the JWKS endpoint.
  • Developer Hub receives and validates the token and its claims.
The diagram illustrates the authentication flow between an external service and Developer Hub.

Prerequisites

  • You have administrative access to configure Developer Hub in your OpenShift cluster.
  • Developer Hub can access a JWKS endpoint available from your Identity Provider.
  • You have configured the external service to obtain a JWT from your Identity Provider and include it in the Authorization header of requests to Developer Hub.

Procedure

  • Add the JWKS URL to your app-config.yaml Developer Hub configuration file:

    backend:
      auth:
        externalAccess:
          - type: jwks
            options:
              url: <your_jwks_endpoint>
              algorithm: RS256
              issuer: <your_issuer_claim>
              audience: <your_audience_claim>
              subjectPrefix: <your_subject_prefix>

    where:

    type
    Enter jwks to specify that authentication is using JWKS tokens.
    options

    Enter the configuration options for JWKS authentication.

    url
    Enter the URL of your JWKS endpoint, such as http://your-idp.example.com/well-known/jwks.json.
    algorithm
    (Optional) Enter the signing algorithm used by your Identity Provider, such as RS256.
    issuer
    (Optional) Enter the expected issuer claim in the token iss field, such as http://your-idp.example.com.
    audience
    (Optional) Enter the expected audience claim in the token aud field, such as management.
    subjectPrefix
    (Optional) Enter a prefix to add to the subject claim, and to display in the Audit Log for debugging and tracking purposes, such as your_prefix.
10.2.7.2.4. Set access restrictions to external service tokens

By default, when you configure service-to-service access in Red Hat Developer Hub, any external service with a valid token has unrestricted access to all backend plugins and actions. To limit the scope of an external service, you can define access restrictions.

Procedure

  1. Restrict access to specific plugins.

    For example, to restrict access to the catalog plugin for the static tokens, add the following accessRestrictions section to your app-config.yaml Developer Hub configuration file:

    backend:
      auth:
        externalAccess:
          - type: static
              accessRestrictions:
              - plugin: catalog
    type
    Specify whether this is a jwks or static token.
    plugin
    Specify the allowed plugin, such as catalog, scaffolder, or techdocs.

    With this configuration:

    1. The token is only allowed to make requests to the catalog plugin.
    2. The token has unrestricted access to all actions within the catalog plugin.
  2. Restrict access by action attributes, to filter permissions based on what kind of action to allow.

    List the specific actions defined by the permission, such as create and read.

    backend:
      auth:
        externalAccess:
          - type: jwks
            accessRestrictions:
              - plugin: catalog
                permissionAttribute:
                  action:
                    - create
                    - read
  3. Restrict access by explicit permission IDs, to control access at the permission rule level.

    List the exact ID of the permission to allow.

    backend:
      auth:
        externalAccess:
          - type: jwks
            accessRestrictions:
              - plugin: catalog
                permission:
                  - catalog.entity.create
                  - catalog.entity.read

    By choosing between explicit permission IDs and action-based attributes, you can strike the right balance between precision and flexibility depending on your external service needs.

10.2.8. Configure session expiration and auto-logout policies

10.2.8.1. Configure session expiration and auto-logout policies

You can manage how long users stay authenticated in Red Hat Developer Hub by configuring session duration and auto-logout settings.

10.2.8.2. Session management

10.2.8.2.1. Session management

Session management in Red Hat Developer Hub involves multiple mechanisms that control how long users stay authenticated and what happens when sessions expire.

10.2.8.2.2. Understand session management in Developer Hub

Session management in Red Hat Developer Hub involves multiple mechanisms that control how long users stay authenticated and what happens when sessions expire.

10.2.8.2.2.1. What happens when a session expires

When a session approaches expiration, Developer Hub can display a pre-expiration warning dialog that includes a countdown timer. The timing of this warning depends on how you configure the auto-logout feature.

After the session expires, Developer Hub redirects the user to the login page. To continue working, the user must re-authenticate with the configured identity provider and is then returned to Developer Hub.

10.2.8.2.2.2. AutoLogout (frontend inactivity)

The AutoLogout feature monitors user activity in the browser and logs out the user after a configurable idle period. AutoLogout revokes the refresh token for Developer Hub, but does not end the Identity Provider (IdP) session. The logout mechanism is the same as if you manually logout from the user settings page.

You configure AutoLogout under the auth.autologout section of your app-config.yaml file.

10.2.8.2.2.3. Session duration (provider-level)

Session duration controls the absolute session lifetime regardless of user activity. This is a backend HTTP-only cookie configuration. When this duration elapses, no warning popup is displayed. Instead, the user is redirected to the sign-in page the next time they interact with Developer Hub, such as navigating to a new page or refreshing the browser.

You configure session duration per provider by using the auth.providers.<name>.<env>.sessionDuration parameter in your app-config.yaml file. This parameter accepts milliseconds, ISO duration, or human-readable duration values (for example, 24h, 2 days).

10.2.8.2.2.4. Identity Provider session settings

Your Identity Provider (IdP), such as Red Hat Build of Keycloak, GitHub, Microsoft Azure, or GitLab, maintains its own session timeout independently of Developer Hub.

Signing out of Developer Hub does not end the IdP SSO session. This is expected behavior. If the IdP session is still active when a user signs back in to Developer Hub, re-authentication might be seamless, with no password prompt.

10.2.8.2.2.5. How the mechanisms interact

The three session management mechanisms operate at different layers:

AutoLogout
Triggers on user inactivity in the browser. Frontend-only: does not revoke tokens or end server-side sessions.
Session duration
Controls the absolute session lifetime on the server side. The session expires after the configured duration regardless of user activity. No warning popup is displayed; the user is redirected to the sign-in page on next interaction.
Identity Provider session
Outlives Developer Hub sign-out. A user might re-enter Developer Hub without a password prompt if the IdP session is still active.

The mechanism with the shortest timeout takes effect first. For example, if AutoLogout is set to 30 minutes of idle time but the session duration is set to 15 minutes, the session expires after 15 minutes regardless of user activity.

10.2.8.3. Configure session management

You can configure the session duration for your authentication provider in Red Hat Developer Hub.

Prerequisites

  • You have administrative access to the Red Hat Developer Hub configuration files.

Procedure

  1. To set the absolute session lifetime for an authentication provider, add the sessionDuration parameter to your app-config.yaml file:

    auth:
      providers:
        <name>:
          <env>:
            sessionDuration: 24h
    sessionDuration

    Enter the session lifetime in milliseconds, ISO duration, or human-readable format (for example, 24h, 2 days). When this duration elapses, the session expires regardless of user activity.

    This parameter is not set by default.

  2. Restart the Red Hat Developer Hub application to apply the changes.

10.2.8.4. Enable auto-logout for inactive users

To enhance security, you can configure Red Hat Developer Hub to automatically log out users after a specified period of inactivity. This helps prevent unauthorized access to stale user sessions.

Procedure

  1. Add the auth.autologout section to your {my-app-config.yaml} file.

    auth:
      autologout:
        enabled: true
        idleTimeoutMinutes: 60
        promptBeforeIdleSeconds: 10
        useWorkerTimers: false
        logoutIfDisconnected: true

    where:

    enabled

    Enter true to enable auto-logout.

    Enter false to disable auto-logout.

    The default value is false.

    idleTimeoutMinutes

    (Optional) Enter the number of minutes of inactivity before automatically logging out the user.

    The default value is 60 minutes.

    promptBeforeIdleSeconds

    (Optional) Enter the number of seconds before the auto-logout occurs to prompt the user about the pending logout.

    The default value is 10 seconds.

    useWorkerTimers

    (Optional) Enter false to use main thread timers, when your browser does not support web workers. Your browser might stop timers in inactive tabs, which can affect the auto-logout functionality.

    Enter true to use web worker timers for tracking user activity, and avoid issues when your browser stops timers in inactive tabs.

    The default value is false.

    logoutIfDisconnected

    (Optional) Enter true to log out the users with no active connection, in case of network issues, or when they have no active Developer Hub tab open in their browser.

    Enter false to keep the user logged in during temporary disconnections, or when they have no active Developer Hub tab open in their browser.

    The default value is true.

  2. Restart the Red Hat Developer Hub application to apply the changes.

Verification

  1. Log in to the Red Hat Developer Hub application.
  2. Remain inactive for the duration specified in idleTimeoutMinutes.
  3. Observe that a prompt is displayed before the auto-logout occurs, as specified in promptBeforeIdleSeconds.
  4. Confirm that you are automatically logged out after the inactivity period.

10.2.8.5. Reduce the size of issued tokens

If user identity tokens grow large and cause HTTP errors, you can use the omitIdentityTokenOwnershipClaim flag to remove the ent claim from the JWT payload and reduce token size.

Procedure

  • In the app-config.yaml file, set omitIdentityTokenOwnershipClaim to true as follows:

    auth:
      omitIdentityTokenOwnershipClaim: true

10.3. Define authorization policies to restrict access based on user roles

10.3.1. Define authorization policies to restrict access based on user roles

Configure role-based access control (RBAC) to define roles, permissions, and policies for users and groups in Developer Hub.

Role-based access control (RBAC) is a security concept that defines how to control access to resources in a system by specifying a mapping between users of the system and the actions that those users can perform on resources in the system. You can use RBAC to define roles with specific permissions and then assign the roles to users and groups.

RBAC on Developer Hub is built on top of the Permissions framework, which defines RBAC policies in code. Rather than defining policies in code, you can use the Developer Hub RBAC feature to define policies in a declarative fashion by using a simple CSV based format. You can define the policies by using Developer Hub web interface or REST API instead of editing the CSV directly.

An administrator can define authorizations in Developer Hub by taking the following steps:

  1. Enable the RBAC feature and give authorized users access to the feature.
  2. Define roles and policies by combining the following methods:

    • The Developer Hub policy administrator uses the Developer Hub web interface or REST API.
    • The Developer Hub administrator edits the main Developer Hub configuration file.
    • The Developer Hub administrator edits external files.

10.3.2. Enable and give access to the role-based access control (RBAC) feature

Enable the RBAC plugin and declare policy administrators to manage permissions and access the RBAC REST API and Web UI.

The role-based access control (RBAC) feature is disabled by default. Enable the RBAC plugin and declare policy administrators to start using RBAC features.

The permission policies for users and groups in the Developer Hub are managed by permission policy administrators. Only permission policy administrators can access the RBAC REST API.

Procedure

  1. The RBAC plugin is installed but disabled by default. To enable the ./dynamic-plugins/dist/backstage-community-plugin-rbac plugin, edit your dynamic-plugins.yaml with the following content.

    dynamic-plugins.yaml fragment

    plugins:
      - package: ./dynamic-plugins/dist/backstage-community-plugin-rbac
        disabled: false

    See Installing and viewing plugins in Red Hat Developer Hub.

  2. Declare policy administrators to enable a select number of authenticated users to configure RBAC policies through the REST API or Web UI, instead of changing the CSV file directly.

    The permissions can be specified in a separate CSV file referenced in your my-rhdh-app-config config map, or permissions can be created using the REST API or Web UI.

    To declare users such as <your_policy_administrator_name> as policy administrators, edit your custom Developer Hub ConfigMap, such as app-config-rhdh, and add following code to the app-config.yaml content:

    app-config.yaml fragment

    permission:
      enabled: true
      rbac:
        admin:
          users:
            - name: user:default/<your_policy_administrator_name>

  3. To display the available permissions provided by installed plugins in the Developer Hub UI, you must supply the corresponding list of plugin IDs. There are two ways to do this, by updating your application configuration or by using the RBAC REST API permissions endpoint.

    1. To supply plugins by updating your application configuration, you can specify the plugins with permissions in your app-config.yaml file as follows:

      app-config.yaml fragment

      permission:
        enabled: true
        rbac:
          admin:
            users:
              - name: user:default/<your_policy_administrator_name>
          pluginsWithPermission:
            - catalog
            - scaffolder
            - permission

    2. To specify the plugins with permissions by using the RBAC REST API permissions endpoint, see the RBAC REST API permissions endpoint.

Verification

  1. Sign out from the existing Red Hat Developer Hub session and log in again using the declared policy administrator account.
  2. With RBAC enabled, most features are disabled by default.

    1. Navigate to the Catalog page in RHDH. The Create button is not visible. You cannot create new components.
    2. Navigate to the API page. The Register button is not visible.

Next steps

  • Explicitly enable permissions to resources in Developer Hub.

10.3.3. Determine permission policy and role configuration source

Identify the source of permission policies and roles to keep data consistency and find which source controls each resource.

You can configure Red Hat Developer Hub policy and roles by using different sources. To keep data consistency, Developer Hub associates each permission policy and role with one unique source. You can only use this source to change the resource.

The available sources are:

Configuration file

Configure roles and policies in the Developer Hub app-config.yaml configuration file, for instance to declare your policy administrators.

The Configuration file pertains to the default role:default/rbac_admin role provided by the RBAC plugin. The default role has limited permissions to create, read, update, delete permission policies or roles, and to read catalog entities.

Note

In case the default permissions are insufficient for your administrative requirements, you can create a custom admin role with the required permission policies.

REST API
Configure roles and policies by using the Developer Hub Web UI or by using the REST API.
CSV file
Configure roles and policies by using external CSV files.
Legacy

The legacy source applies to policies and roles defined before RBAC backend plugin version 2.1.3, and is the least restrictive among the source location options.

Important

Replace the permissions and roles using the legacy source with the permissions using the REST API or the CSV file sources.

Procedure

  • To find the source of a role or policy, use a GET request.

10.3.4. Design your policy rules

Design policy rules carefully to avoid permission conflicts and unintended access denials in Developer Hub.

Carefully design your policies to avoid permission conflicts that can result in unintended access denials.

Red Hat Developer Hub applies policies as follows:

  • The default policy is deny.
  • A conditional rule overrides a basic rule.
  • A deny basic rule overrides an allow basic rule.
  • An allow conditional rule overrides a deny basic rule.
  • A deny conditional rule overrides an allow conditional rule.

Procedure

  1. Use allow rules to explicitly allow access.
  2. Avoid creating deny rules unless you know precisely how they can affect existing basic allow rules and existing conditional rules.

10.3.5. Manage roles using the Web UI

10.3.5.1. Manage roles using the Web UI

Use the Developer Hub Web UI to create, modify, and delete roles and assign permissions to users and groups.

Policy administrators can use the Developer Hub web interface (Web UI) to assign specific roles and permissions to individual users or groups. Assigning roles ensures that access to resources and functionalities is regulated across the Developer Hub.

With the policy administrator role in Developer Hub, you can assign permissions to users and groups. This role allows you to view, create, change, and delete the roles by using the Developer Hub Web UI.

10.3.5.2. Create a role in the Red Hat Developer Hub Web UI

Create a role in Developer Hub by using the Web UI to define permissions, users, and groups.

You can create a role in the Red Hat Developer Hub using the Web UI.

Prerequisites

  • If RBAC is enabled, you have a role with the following permissions: policy.entity.create, policy.entity.read, catalog.entity.read.

Procedure

  1. Go to Administration at the bottom of the sidebar in the Developer Hub.

    The RBAC tab is displayed, showing all the created roles in the Developer Hub.

  2. (Optional) Click any role to view the role information on the OVERVIEW page.
  3. Click CREATE to create a role.
  4. Enter the name and description of the role in the given fields and click NEXT.
  5. Add users and groups using the search field, and click NEXT.
  6. Select Plugin and Permission from the drop-downs in the Add permission policies section.
  7. Select or clear the Policy that you want to set in the Add permission policies section, and click NEXT.
  8. Review the added information in the Review and create section.
  9. Click CREATE.

Verification

The created role is displayed in the list available in the RBAC tab.

10.3.5.3. Edit a role in the Red Hat Developer Hub Web UI

Edit a role in Developer Hub by using the Web UI to change role details, users, groups, and permission policies.

You can edit a role in the Red Hat Developer Hub using the Web UI.

Note

The policies generated from a policy.csv or ConfigMap file cannot be edited or deleted using the Developer Hub Web UI.

Prerequisites

  • If RBAC is enabled, you have a role with the following permissions: policy.entity.update, policy.entity.read, catalog.entity.read.
  • The role that you want to edit is created in the Developer Hub.

Procedure

  1. Go to Administration at the bottom of the sidebar in the Developer Hub.

    The RBAC tab is displayed, showing all the created roles in the Developer Hub.

  2. (Optional) Click any role to view the role information on the OVERVIEW page.
  3. Select the edit icon for the role that you want to edit.
  4. Edit the details of the role, such as name, description, users and groups, and permission policies, and click NEXT.
  5. Review the edited details of the role and click SAVE.

Verification

  1. After saving the changes, you can view the edited details of the role on the OVERVIEW page of the role.
  2. You can also edit a role’s users and groups or permissions by using the edit icon on the Users and Groups or Permissions cards on the OVERVIEW page.

10.3.5.4. Delete a role in the Red Hat Developer Hub Web UI

Delete a role in Developer Hub by using the Web UI to remove roles that are no longer needed.

You can delete a role in the Red Hat Developer Hub using the Web UI.

Note

The policies generated from a policy.csv or ConfigMap file cannot be edited or deleted using the Developer Hub Web UI.

Prerequisites

  • If RBAC is enabled, you have a role with the following permissions: policy.entity.delete, policy.entity.read, catalog.entity.read.
  • The role that you want to delete is created in the Developer Hub.

Procedure

  1. Go to Administration at the bottom of the sidebar in the Developer Hub.

    The RBAC tab is displayed, showing all the created roles in the Developer Hub.

  2. (Optional) Click any role to view the role information on the OVERVIEW page.
  3. Select the delete icon from the Actions column for the role that you want to delete.

    The Delete this role? pop-up is displayed on the screen.

  4. Click DELETE.

10.3.6. Manage policies using the REST API

10.3.6.1. Manage policies using the REST API

Automate the maintenance of permission policies and roles by using the Developer Hub RBAC REST API.

To automate the maintenance of Red Hat Developer Hub permission policies and roles, you can use Developer Hub role-based access control (RBAC) REST API.

You can perform the following actions with the REST API:

  • Retrieve information about:

    • All permission policies
    • Specific permission policies
    • Specific roles
    • Static plugins permission policies
  • Create, update, or delete:

    • Permission policy
    • Role

10.3.6.2. Send requests to the RBAC REST API by using the curl utility

Send RBAC REST API requests by using the curl utility to create, update, and delete roles and permission policies.

You can send RBAC REST API requests by using the curl utility.

Procedure

  1. Find your Bearer token to authenticate to the REST API.

    1. In your browser, open the web console Network tab.
    2. In the main screen, reload the Developer Hub Homepage.
    3. In the web console Network tab, search for the query?term= network call.
    4. Save the token in the response JSON for the next steps.
  2. In a terminal, run the curl command and review the response:

    GET request, or DELETE request not requiring JSON body data

    Enter a curl command with the following parameters and review the response:

    $ curl -v \
      -H "Authorization: Bearer <token>" \
      -X <method> "https://<my_developer_hub_domain>/<endpoint>" \
    POST or PUT request, or DELETE request requiring JSON body data

    Enter a curl command with the following parameters and review the response:

    $ curl -v -H "Content-Type: application/json" \
      -H "Authorization: Bearer <token>" \
      -X <method> "https://<my_developer_hub_domain>/<endpoint>" \
      -d <body>
    <token>
    Enter your saved authorization token.
    <method>

    Enter the HTTP method for your API endpoint.

    GET
    To retrieve specified information from a specified resource endpoint.
    POST
    To create or update a resource.
    PUT
    To update a resource.
    DELETE
    To delete a resource.
    https://<my_developer_hub_domain>
    Enter your Developer Hub URL.
    <endpoint>
    Enter the API endpoint to which you want to send a request, such as /api/permission/policies.
    <body>

    Enter the JSON body with data that your API endpoint requires with the HTTP POST, or PUT request, and might require with the HTTP DELETE request.

    • To create a role:

      $ curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer <token>" \
        -X POST "https://<my_developer_hub_domain>/api/permission/roles" \
        -d '{
            "memberReferences": ["group:default/example"],
            "name": "role:default/test",
            "metadata": { "description": "This is a test role" }
          }'
    • To update a role:

      $ curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer <token>" \
        -X PUT "https://<my_developer_hub_domain>/api/permission/roles/role/default/test" \
        -d '{
                "oldRole": {
                  "memberReferences":  [ "group:default/example" ],
                  "name": "role:default/test"
                },
                "newRole": {
                  "memberReferences": [ "group:default/example", "user:default/test" ],
                  "name": "role:default/test"
                }
              }'
    • To create a permission policy:

      $ curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer $token" \
        -X POST "https://<my_developer_hub_domain>/api/permission/policies" \
        -d '[{
            "entityReference":"role:default/test",
            "permission": "catalog-entity",
            "policy": "read", "effect":"allow"
          }]'
    • To update a permission policy:

      $ curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer $token" \
        -X PUT "https://<my_developer_hub_domain>/api/permission/policies/role/default/test" \
        -d '{
               "oldPolicy": [
                 {
                   "permission": "catalog-entity", "policy": "read", "effect": "allow"
                 }
               ],
               "newPolicy":
                 [
                   {
                     "permission": "policy-entity", "policy": "read", "effect": "allow"
                   }
                 ]
             }'
    • To create a condition:

      $ curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer $token" \
        -X POST "https://<my_developer_hub_domain>/api/permission/roles/conditions" \
        -d '{
            "result": "CONDITIONAL",
            "roleEntityRef": "role:default/test",
            "pluginId": "catalog",
            "resourceType": "catalog-entity",
            "permissionMapping": ["read"],
            "conditions": {
              "rule": "IS_ENTITY_OWNER",
              "resourceType": "catalog-entity",
              "params": {"claims": ["group:default/janus-authors"]}
            }
          }'
    • To update a condition:

      $ curl -v -H "Content-Type: application/json" \
        -H "Authorization: Bearer $token" \
        -X PUT "https://<my_developer_hub_domain>/api/permission/roles/conditions/1" \
        -d '{
                "result":"CONDITIONAL",
                "roleEntityRef":"role:default/test",
                "pluginId":"catalog",
                "resourceType":"catalog-entity",
                "permissionMapping": ["read",  "update", "delete"],
                "conditions": {
                  "rule": "IS_ENTITY_OWNER",
                  "resourceType": "catalog-entity",
                  "params": {"claims": ["group:default/janus-authors"]}
                }
             }'

Verification

  • Review the returned HTTP status code:

    200 OK
    The request was successful.
    201 Created
    The request resulted in a new resource being successfully created.
    204 No Content
    The request was successful, and the response payload has no more content.
    400 Bad Request
    Input error with the request.
    401 Unauthorized
    Lacks valid authentication for the requested resource.
    403 Forbidden
    Refusal to authorize request.
    404 Not Found
    Could not find requested resource.
    409 Conflict
    Request conflict with the current state and the target resource.

10.3.6.3. Send requests to the RBAC REST API by using a REST client

Send RBAC REST API requests by using any REST client with authorization tokens and appropriate HTTP methods.

You can send RBAC REST API requests by using any REST client.

Procedure

  1. Find your Bearer token to authenticate to the REST API.

    1. In your browser, open the web console Network tab.
    2. In the main screen, reload the Developer Hub Homepage.
    3. In the web console Network tab, search for the query?term= network call.
    4. Save the token in the response JSON for the next steps.
  2. In your REST client, run a command with the following parameters and review the response:

    Authorization
    Enter your saved authorization token.
    HTTP method

    Enter the HTTP method for your API endpoint.

    GET
    To retrieve specified information from a specified resource endpoint.
    POST
    To create or update a resource.
    PUT
    To update a resource.
    DELETE
    To delete a resource.
    URL
    Enter your Developer Hub URL and API endpoint: https://<my_developer_hub_domain>/<endpoint>, such as https://<my_developer_hub_domain>/api/permission/policies.
    Body
    Enter the JSON body with data that your API endpoint might need with the HTTP POST request.

10.3.6.4. Send requests to the RBAC REST API by using an external service

Send GET requests to the RBAC REST API from an external service authenticated with a service-to-service token.

You can send GET requests to the RBAC REST API by using an external service authenticated by using a service-to-service token.

Prerequisites

Procedure

  1. The external service sends a GET request to the RBAC REST API with the service-to-service token in the Authorization header.
  2. The RBAC REST API validates the service-to-service token, and then processes the request if the token is valid. Otherwise, the RBAC REST API returns an error response.
  3. The RBAC REST API returns the response to the external service.
  4. The external service processes the response from the RBAC REST API.

10.3.6.5. Supported REST API endpoints

10.3.6.5.1. Supported REST API endpoints

Reference information about the supported RBAC REST API endpoints for managing roles, permission policies, conditional policies, and user statistics in Developer Hub.

10.3.6.5.2. Supported RBAC REST API endpoints

Reference information about RBAC REST API endpoints for managing roles, permissions, and conditional policies.

The RBAC REST API provides endpoints for managing roles, permissions, and conditional policies in the Developer Hub and for retrieving information about the roles and policies.

10.3.6.5.2.1. Roles

The RBAC REST API supports the following endpoints for managing roles in the Red Hat Developer Hub.

[GET] /api/permission/roles

Returns all roles in Developer Hub.

Example response (JSON):

[
  {
    "memberReferences": ["user:default/username"],
    "name": "role:default/guests"
  },
  {
    "memberReferences": [
      "group:default/groupname",
      "user:default/username"
    ],
    "name": "role:default/rbac_admin"
  }
]
[GET] /api/permission/roles/<kind>/<namespace>/<name>

Returns information for a single role in Developer Hub.

Example response (JSON):

[
  {
    "memberReferences": [
      "group:default/groupname",
      "user:default/username"
    ],
    "name": "role:default/rbac_admin"
  }
]
[POST] /api/permission/roles/<kind>/<namespace>/<name>
Creates a role in Developer Hub.
NameDescriptionTypePresence

body

The memberReferences, group, namespace, and name the new role to be created.

Request body

Required

Example request body (JSON):

+

{
  "memberReferences": ["group:default/test"],
  "name": "role:default/test_admin"
}

Example response:

+

201 Created
[PUT] /api/permission/roles/<kind>/<namespace>/<name>
Updates memberReferences, kind, namespace, or name for a role in Developer Hub.

Request parameters: The request body contains the oldRole and newRole objects:

NameDescriptionTypePresence

body

The memberReferences, group, namespace, and name the new role to be created.

Request body

Required

Example request body (JSON):

+

{
  "oldRole": {
    "memberReferences": ["group:default/test"],
    "name": "role:default/test_admin"
  },
  "newRole": {
    "memberReferences": ["group:default/test", "user:default/test2"],
    "name": "role:default/test_admin"
  }
}

Example response:

+

200 OK
[DELETE] /api/permission/roles/<kind>/<namespace>/<name>?memberReferences=<VALUE>
Deletes the specified user or group from a role in Developer Hub.
NameDescriptionTypePresence

kind

Kind of the entity

String

Required

namespace

Namespace of the entity

String

Required

name

Name of the entity

String

Required

memberReferences

Associated group information

String

Required

Example response:

+

204
[DELETE] /api/permission/roles/<kind>/<namespace>/<name>
Deletes a specified role from Developer Hub.
NameDescriptionTypePresence

kind

Kind of the entity

String

Required

namespace

Namespace of the entity

String

Required

name

Name of the entity

String

Required

Example response:

+

204
10.3.6.5.2.2. Permission policies

The RBAC REST API supports the following endpoints for managing permission policies in the Red Hat Developer Hub.

[GET] /api/permission/policies
Returns permission policies list for all users.

Example response (JSON):

+

[
  {
    "entityReference": "role:default/test",
    "permission": "catalog-entity",
    "policy": "read",
    "effect": "allow",
    "metadata": {
      "source": "csv-file"
    }
  },
  {
    "entityReference": "role:default/test",
    "permission": "catalog.entity.create",
    "policy": "use",
    "effect": "allow",
    "metadata": {
      "source": "csv-file"
    }
  },
]
[GET] /api/permission/policies/<kind>/<namespace>/<name>
Returns permission policies related to the specified entity reference.
NameDescriptionTypePresence

kind

Kind of the entity

String

Required

namespace

Namespace of the entity

String

Required

name

Name related to the entity

String

Required

Example response (JSON):

+

[
  {
    "entityReference": "role:default/test",
    "permission": "catalog-entity",
    "policy": "read",
    "effect": "allow",
    "metadata": {
      "source": "csv-file"
    }
  },
  {
    "entityReference": "role:default/test",
    "permission": "catalog.entity.create",
    "policy": "use",
    "effect": "allow",
    "metadata": {
      "source": "csv-file"
    }
  }
]
[POST] /api/permission/policies
Creates a permission policy for a specified entity.
NameDescriptionTypePresence

entityReference

Reference values of an entity including kind, namespace, and name

String

Required

permission

Permission from a specific plugin, resource type, or name

String

Required

policy

Policy action for the permission, such as create, read, update, delete, or use

String

Required

effect

Indication of allowing or not allowing the policy

String

Required

Example request body (JSON):

+

[
  {
    "entityReference": "role:default/test",
    "permission": "catalog-entity",
    "policy": "read",
    "effect": "allow"
  }
]

Example response:

+

201 Created
[PUT] /api/permission/policies/<kind>/<namespace>/<name>
Updates a permission policy for a specified entity.

Request parameters: The request body contains the oldPolicy and newPolicy objects:

NameDescriptionTypePresence

permission

Permission from a specific plugin, resource type, or name

String

Required

policy

Policy action for the permission, such as create, read, update, delete, or use

String

Required

effect

Indication of allowing or not allowing the policy

String

Required

Example request body (JSON):

+

{
  "oldPolicy": [
    {
      "permission": "catalog-entity",
      "policy": "read",
      "effect": "allow"
    },
    {
      "permission": "catalog.entity.create",
      "policy": "create",
      "effect": "allow"
    }
  ],
  "newPolicy": [
    {
      "permission": "catalog-entity",
      "policy": "read",
      "effect": "deny"
    },
    {
      "permission": "policy-entity",
      "policy": "read",
      "effect": "allow"
    }
  ]
}

Example response:

+

200
[DELETE] /api/permission/policies/<kind>/<namespace>/<name>?permission={value1}&policy={value2}&effect={value3}
Deletes a permission policy added to the specified entity.
NameDescriptionTypePresence

kind

Kind of the entity

String

Required

namespace

Namespace of the entity

String

Required

name

Name related to the entity

String

Required

permission

Permission from a specific plugin, resource type, or name

String

Required

policy

Policy action for the permission, such as create, read, update, delete, or use

String

Required

effect

Indication of allowing or not allowing the policy

String

Required

Example response:

+

204 No Content
[DELETE] /api/permission/policies/<kind>/<namespace>/<name>
Deletes all permission policies added to the specified entity.
NameDescriptionTypePresence

kind

Kind of the entity

String

Required

namespace

Namespace of the entity

String

Required

name

Name related to the entity

String

Required

Example request body (JSON):

+

[
  {
    "entityReference": "role:default/test",
    "permission": "catalog-entity",
    "policy": "delete",
    "effect": "allow"
  },
  {
    "entityReference": "role:default/test",
    "permission": "catalog-entity",
    "policy": "update",
    "effect": "allow"
  }
]

Example response:

+

204 No Content
[GET] /api/permission/plugins/policies
Returns permission policies for all static plugins.

Example response (JSON):

+

[
  {
    "pluginId": "catalog",
    "policies": [
      {
        "isResourced": true,
        "permission": "catalog-entity",
        "policy": "read"
      },
      {
        "isResourced": false,
        "permission": "catalog.entity.create",
        "policy": "create"
      },
      {
        "isResourced": true,
        "permission": "catalog-entity",
        "policy": "delete"
      },
      {
        "isResourced": true,
        "permission": "catalog-entity",
        "policy": "update"
      },
      {
        "isResourced": false,
        "permission": "catalog.location.read",
        "policy": "read"
      },
      {
        "isResourced": false,
        "permission": "catalog.location.create",
        "policy": "create"
      },
      {
        "isResourced": false,
        "permission": "catalog.location.delete",
        "policy": "delete"
      }
    ]
  },
  ...
]
[GET] /api/permission/plugins/id
Returns object with list plugin IDs:

Example response (JSON):

+

[
  {
    "ids": ["catalog", "permission"]
  }
]
[POST] /api/permission/plugins/id
Add more plugins IDs defined in the request object.

Request Parameters: object in JSON format.

Example request body (JSON):

+

[
  {
    "ids": ["scaffolder"]
  }
]

Returns a status code of 200 and JSON with actual object stored in the server:

Example response (JSON):

+

[
  {
    "ids": ["catalog", "permission", "scaffolder"]
  }
]
[DELETE] /api/permission/plugins/id
Delete plugins IDs defined in the request object.

Request Parameters: object in JSON format.

Example request body (JSON):

+

[
  {
    "ids": ["scaffolder"]
  }
]

Returns a status code of 200 and JSON with actual object stored in the server:

Example response (JSON):

+

[
  {
    "ids": ["catalog", "permission"]
  }
]
Note

To prevent an inconsistent state after a deployment restart, the REST API does not allow deletion of plugin IDs that were provided by using the application configuration. These ID values can only be removed through the configuration file.

10.3.6.5.2.3. Conditional policies

The RBAC REST API supports the following endpoints for managing conditional policies in the Red Hat Developer Hub.

[GET] /api/permission/plugins/condition-rules
Returns available conditional rule parameter schemas for the available plugins that are enabled in Developer Hub.

Example response (JSON):

+

[
   {
      "pluginId": "catalog",
      "rules": [
         {
            "name": "HAS_ANNOTATION",
            "description": "Allow entities with the specified annotation",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "annotation": {
                     "type": "string",
                     "description": "Name of the annotation to match on"
                  },
                  "value": {
                     "type": "string",
                     "description": "Value of the annotation to match on"
                  }
               },
               "required": [
                  "annotation"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "HAS_LABEL",
            "description": "Allow entities with the specified label",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "label": {
                     "type": "string",
                     "description": "Name of the label to match on"
                  }
               },
               "required": [
                  "label"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "HAS_METADATA",
            "description": "Allow entities with the specified metadata subfield",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "key": {
                     "type": "string",
                     "description": "Property within the entities metadata to match on"
                  },
                  "value": {
                     "type": "string",
                     "description": "Value of the given property to match on"
                  }
               },
               "required": [
                  "key"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "HAS_SPEC",
            "description": "Allow entities with the specified spec subfield",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "key": {
                     "type": "string",
                     "description": "Property within the entities spec to match on"
                  },
                  "value": {
                     "type": "string",
                     "description": "Value of the given property to match on"
                  }
               },
               "required": [
                  "key"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "IS_ENTITY_KIND",
            "description": "Allow entities matching a specified kind",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "kinds": {
                     "type": "array",
                     "items": {
                        "type": "string"
                     },
                     "description": "List of kinds to match at least one of"
                  }
               },
               "required": [
                  "kinds"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "IS_ENTITY_OWNER",
            "description": "Allow entities owned by a specified claim",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "claims": {
                     "type": "array",
                     "items": {
                        "type": "string"
                     },
                     "description": "List of claims to match at least one on within ownedBy"
                  }
               },
               "required": [
                  "claims"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         }
      ]
   }
   ... <another plugin condition parameter schemas>
]
[GET] /api/permission/roles/conditions/:id
Returns conditions for the specified ID.

Example response (JSON):

+

{
  "id": 1,
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/test",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["read"],
  "conditions": {
    "anyOf": [
      {
        "rule": "IS_ENTITY_OWNER",
        "resourceType": "catalog-entity",
        "params": {
          "claims": ["group:default/team-a"]
        }
      },
      {
        "rule": "IS_ENTITY_KIND",
        "resourceType": "catalog-entity",
        "params": {
          "kinds": ["Group"]
        }
      }
    ]
  }
}
[GET] /api/permission/roles/conditions
Returns list of all conditions for all roles.

Example response (JSON):

+

[
  {
    "id": 1,
    "result": "CONDITIONAL",
    "roleEntityRef": "role:default/test",
    "pluginId": "catalog",
    "resourceType": "catalog-entity",
    "permissionMapping": ["read"],
    "conditions": {
      "anyOf": [
        {
          "rule": "IS_ENTITY_OWNER",
          "resourceType": "catalog-entity",
          "params": {
            "claims": ["group:default/team-a"]
          }
        },
        {
          "rule": "IS_ENTITY_KIND",
          "resourceType": "catalog-entity",
          "params": {
            "kinds": ["Group"]
          }
        }
      ]
    }
  }
]
[POST] /api/permission/roles/conditions
Creates a conditional policy for the specified role.
NameDescriptionTypePresence

result

Always has the value CONDITIONAL

String

Required

roleEntityRef

String entity reference to the RBAC role, such as role:default/dev

String

Required

pluginId

Corresponding plugin ID, such as catalog

String

Required

permissionMapping

Array permission action, such as ['read', 'update', 'delete']

String array

Required

resourceType

Resource type provided by the plugin, such as catalog-entity

String

Required

conditions

Condition JSON with parameters or array parameters joined by criteria

JSON

Required

name

Name of the role

String

Required

metadata.description

The description of the role

String

Optional

Example request body (JSON):

+

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/test",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["read"],
  "conditions": {
    "rule": "IS_ENTITY_OWNER",
    "resourceType": "catalog-entity",
    "params": {
      "claims": ["group:default/team-a"]
    }
  }
}

Example response (JSON):

+

{
  "id": 1
}
[PUT] /permission/roles/conditions/:id
Updates a condition policy for a specified ID.
NameDescriptionTypePresence

result

Always has the value CONDITIONAL

String

Required

roleEntityRef

String entity reference to the RBAC role, such as role:default/dev

String

Required

pluginId

Corresponding plugin ID, such as catalog

String

Required

permissionMapping

Array permission action, such as ['read', 'update', 'delete']

String array

Required

resourceType

Resource type provided by the plugin, such as catalog-entity

String

Required

conditions

Condition JSON with parameters or array parameters joined by criteria

JSON

Required

name

Name of the role

String

Required

metadata.description

The description of the role

String

Optional

Example request body (JSON):

+

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/test",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["read"],
  "conditions": {
    "anyOf": [
      {
        "rule": "IS_ENTITY_OWNER",
        "resourceType": "catalog-entity",
        "params": {
          "claims": ["group:default/team-a"]
        }
      },
      {
        "rule": "IS_ENTITY_KIND",
        "resourceType": "catalog-entity",
        "params": {
          "kinds": ["Group"]
        }
      }
    ]
  }
}

Example response:

+

200
[DELETE] /api/permission/roles/conditions/:id
Deletes a conditional policy for the specified ID.

Example response:

+

204
10.3.6.5.2.4. User statistics

The licensed-users-info-backend plugin exposes various REST API endpoints to retrieve data related to logged-in users.

No additional configuration is required for the licensed-users-info-backend plugin. If the RBAC backend plugin is enabled, then an administrator role must be assigned to access the endpoints, as the endpoints are protected by the policy.entity.read permission.

The base URL for user statistics endpoints is http://SERVER:PORT/api/licensed-users-info, such as http://localhost:7007/api/licensed-users-info.

[GET] /users/quantity
Returns the total number of logged-in users.

Example request:

+

curl -X GET "http://localhost:7007/api/licensed-users-info/users/quantity" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $token"

Example response:

+

{ "quantity": "2" }
[GET] /users
Returns a list of logged-in users with their details.

Example request:

+

curl -X GET "http://localhost:7007/api/licensed-users-info/users" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $token"

Example response:

+

[
  {
    "userEntityRef": "user:default/dev",
    "lastTimeLogin": "Thu, 22 Aug 2024 16:27:41 GMT",
    "displayName": "John Leavy",
    "email": "dev@redhat.com"
  }
]
[GET] /users
Returns a list of logged-in users in CSV format.

Example request:

+

curl -X GET "http://localhost:7007/api/licensed-users-info/users" \
-H "Content-Type: text/csv" \
-H "Authorization: Bearer $token"

Example response:

+

userEntityRef,displayName,email,lastTimeLogin
user:default/dev,John Leavy,dev@redhat.com,"Thu, 22 Aug 2024 16:27:41 GMT"
10.3.6.5.3. User statistics in Red Hat Developer Hub

Monitor active user counts and download user lists by using the licensed-users-info-backend plugin for licensing transparency.

In Red Hat Developer Hub, the licensed-users-info-backend plugin provides statistical information about the logged-in users by using the Web UI or REST API endpoints.

The licensed-users-info-backend plugin enables administrators to monitor the number of active users on Developer Hub. Using this feature, organizations can compare their actual usage with the number of licenses they have purchased. Additionally, you can share the user metrics with Red Hat for transparency and exact licensing.

The licensed-users-info-backend plugin is enabled by default. This plugin enables a Download User List link at the bottom of the Administration → RBAC tab.

10.3.7. Define policies in external files to provision permissions during cluster deployment

10.3.7.1. Define policies in external files to provision permissions during cluster deployment

Configure permissions and roles in external files before starting Developer Hub to automate maintenance.

To automate Red Hat Developer Hub maintenance, you can configure permissions and roles in external files, before starting Developer Hub.

10.3.7.2. Define authorizations in external files by using the Operator

Define permissions and roles in external CSV and YAML files and configure Developer Hub to use them with the Operator.

To automate Red Hat Developer Hub maintenance, you can define permissions and roles in external files, before starting Developer Hub. You need to prepare your files, upload them to your OpenShift Container Platform project, and configure Developer Hub to use the external files.

Procedure

  1. Define your policies in a rbac-policies.csv CSV file by using the following format:

    1. Define role permissions:

      p, <role_entity_reference>, <permission>, <action>, <allow_or_deny>
      <role_entity_reference>
      Role entity reference, such as: role:default/guest.
      <permission>

      Permission, such as: bulk.import, catalog.entity.read, or catalog.entity.refresh, or permission resource type, such as: bulk-import or catalog-entity.

      See: Permission policies reference.

      <action>
      Action type, such as: use, read, create, update, delete.
      <allow_or_deny>
      Access granted: allow or deny.
    2. Assign the role to a group or a user:

      g, <group_or_user>, <role_entity_reference>
      <group_or_user>

      Group, such as: user:default/mygroup, or user, such as: user:default/myuser.

      p, role:default/guests, catalog-entity, read, allow
      p, role:default/guests, catalog.entity.create, create, allow
      g, user:default/my-user, role:default/guests
      g, group:default/my-group, role:default/guests
  2. Define your conditional policies in a rbac-conditional-policies.yaml YAML file by using the following format:

    result: CONDITIONAL
    roleEntityRef: <role_entity_reference>
    pluginId: <plugin_id>
    permissionMapping:
      - read
      - update
      - delete
    conditions: <conditions>

    See: Conditional policies reference.

  3. Upload your rbac-policies.csv and rbac-conditional-policies.yaml files to a rbac-policies config map in your OpenShift Container Platform project containing Developer Hub.

    $ oc create configmap rbac-policies \
         --from-file=rbac-policies.csv \
         --from-file=rbac-conditional-policies.yaml
  4. Update your Backstage custom resource to mount in the Developer Hub filesystem your files from the rbac-policies config map:

    apiVersion: rhdh.redhat.com/v1alpha5
    kind: Backstage
    spec:
      application:
        extraFiles:
          mountPath: /opt/app-root/src
          configMaps:
            - name: rbac-policies
  5. Update your Developer Hub app-config.yaml configuration file to use the rbac-policies.csv and rbac-conditional-policies.yaml external files:

    permission:
      enabled: true
      rbac:
        conditionalPoliciesFile: /opt/app-root/src/rbac-conditional-policies.yaml
        policies-csv-file: /opt/app-root/src/rbac-policies.csv
        policyFileReload: true

10.3.7.3. Define authorizations in external files by using Helm

Define permissions and roles in external CSV and YAML files and configure Developer Hub to use them with Helm.

To automate Red Hat Developer Hub maintenance, you can define permissions and roles in external files, before starting Developer Hub. You need to prepare your files, upload them to your OpenShift Container Platform project, and configure Developer Hub to use the external files.

Procedure

  1. Define your policies in a rbac-policies.csv CSV file by using the following format:

    1. Define role permissions:

      p, <role_entity_reference>, <permission>, <action>, <allow_or_deny>
      <role_entity_reference>
      Role entity reference, such as: role:default/guest.
      <permission>

      Permission, such as: bulk.import, catalog.entity.read, or catalog.entity.refresh, or permission resource type, such as: bulk-import or catalog-entity.

      See: Permission policies reference.

      <action>
      Action type, such as: use, read, create, update, delete.
      <allow_or_deny>
      Access granted: allow or deny.
    2. Assign the role to a group or a user:

      g, <group_or_user>, <role_entity_reference>
      <group_or_user>

      Group, such as: user:default/mygroup, or user, such as: user:default/myuser.

      Sample rbac-policies.csv:

      p, role:default/guests, catalog-entity, read, allow
      p, role:default/guests, catalog.entity.create, create, allow
      g, user:default/my-user, role:default/guests
      g, group:default/my-group, role:default/guests
  2. Define your conditional policies in a rbac-conditional-policies.yaml YAML file by using the following format:

    result: CONDITIONAL
    roleEntityRef: <role_entity_reference>
    pluginId: <plugin_id>
    permissionMapping:
      - read
      - update
      - delete
    conditions: <conditions>

    See: Conditional policies reference.

  3. Upload your rbac-policies.csv and rbac-conditional-policies.yaml files to a rbac-policies config map in your OpenShift Container Platform project containing Developer Hub.

    $ oc create configmap rbac-policies \
         --from-file=rbac-policies.csv \
         --from-file=rbac-conditional-policies.yaml
  4. Update your Developer Hub Backstage Helm chart to mount in the Developer Hub filesystem your files from the rbac-policies config map:

    1. In the Developer Hub Helm Chart, go to Root Schema → Backstage chart schema → Backstage parameters → Backstage container additional volume mounts.
    2. Select Add Backstage container additional volume mounts and add the following values:

      mountPath
      /opt/app-root/src/rbac
      Name
      rbac-policies
    3. Add the RBAC policy to the Backstage container additional volumes in the Developer Hub Helm Chart:

      name
      rbac-policies
      configMap
      defaultMode
      420
      name
      rbac-policies
  5. Update your Developer Hub app-config.yaml configuration file to use the rbac-policies.csv and rbac-conditional-policies.yaml external files:

    permission:
      enabled: true
      rbac:
        conditionalPoliciesFile: /opt/app-root/src/rbac-conditional-policies.yaml
        policies-csv-file: /opt/app-root/src/rbac-policies.csv
        policyFileReload: true

10.3.7.4. Configure RBAC for Extensions by using the RBAC CSV file

You can grant access to Extensions plugin management by adding permission policies to your RBAC CSV file.

Prerequisites

Procedure

  1. Add the following policies to your CSV file to allow users to view and manage plugins in Extensions:

    g, user:default/<YOUR_USERNAME>, role:default/extensions-admin
    p, role:default/extensions-admin, extensions.plugin.configuration.read, read, allow
    p, role:default/extensions-admin, extensions.plugin.configuration.write, create, allow
    p, role:default/extensions-admin, catalog.entity.read, read, allow

    See Extensions permissions.

  2. Optional: Restrict access to specific plugins by defining a conditional policy in the rbac-conditional-policies.yaml file as described in Defining conditional policies:

    result: CONDITIONAL
    roleEntityRef: "role:default/extensions-admin"
    pluginId: extensions
    resourceType: extensions-plugin
    permissionMapping:
      - create
    conditions:
      rule: HAS_NAME
      resourceType: extensions-plugin
      params:
        pluginNames: [<your_plugin_name>]

    where:

    pluginNames

    Enter the plugin name or title for user access.

    This policy allows users to install or update only the specified plugins and restricts access to all other plugins.

  3. Optional: Restrict access by annotation by defining a conditional policy:

    result: CONDITIONAL
    roleEntityRef: "role:default/extensions-admin"
    pluginId: extensions
    resourceType: extensions-plugin
    permissionMapping:
      - create
    conditions:
      rule: HAS_ANNOTATION
      resourceType: extensions-plugin
      params:
        annotation: "extensions.backstage.io/certified-by"
        value: "Red Hat"

    This policy allows users to install or update only the plugins that have the specified annotation.

Verification

  • Verify that the user can view and manage plugins in Extensions.

10.3.8. Configure guest access

10.3.8.1. Configure guest access

Enable guest access to test role and policy creation without configuring an authentication provider.

Use guest access with the role-based access control (RBAC) front-end plugin to allow a user to test role and policy creation without the need to set up and configure an authentication provider.

Note

Guest access is not recommended for production.

10.3.8.2. Configure the RBAC backend plugin

Enable the permission framework and configure admin users by updating the app-config-rhdh.yaml file.

You can configure the RBAC backend plugin by updating the app-config.yaml file to enable the permission framework.

Prerequisites

  • You have installed the @backstage-community/plugin-rbac plugin in Developer Hub. For more information, see Configuring dynamic plugins.

Procedure

  • Update the app-config.yaml file to enable the permission framework as shown:

    permission
      enabled: true
      rbac:
        admin:
          users:
            - name: user:default/guest
        pluginsWithPermission:
          - catalog
          - permission
          - scaffolder
    Note

    The pluginsWithPermission section of the app-config.yaml file includes only three plugins by default. Update the section as needed to include any additional plugins that also incorporate permissions.

10.3.8.3. Set up the guest authentication provider

Enable guest authentication for testing RBAC features without configuring a full authentication provider.

You can enable guest authentication and use it alongside the RBAC front-end plugin.

Prerequisites

  • You have installed the @backstage-community/plugin-rbac plugin in Developer Hub. For more information, see Configuring dynamic plugins.

Procedure

  • In the app-config.yaml file, add the user entity reference to resolve and enable the dangerouslyAllowOutsideDevelopment option, as shown in the following example:

    auth:
      environment: development
      providers:
        guest:
          userEntityRef: user:default/guest
          dangerouslyAllowOutsideDevelopment: true
    Note

    You can use user:default/guest as the user entity reference to match the added user under the permission.rbac.admin.users section of the app-config.yaml file.

10.3.9. Permission policy types

Reference information about resource type and basic permission types in Developer Hub.

Permission policies in Red Hat Developer Hub are a set of rules to govern access to resources or functionalities. These policies state the authorization level that is granted to users based on their roles. The permission policies are implemented to keep security and confidentiality within a given environment.

You can define the following types of permissions in Developer Hub:

  • resource type
  • basic

The distinction between the two permission types depends on whether a permission includes a defined resource type.

You can define the resource type permission by using either the associated resource type or the permission name as shown in the following example:

p, role:default/myrole, catalog.entity.read, read, allow
g, user:default/myuser, role:default/myrole

p, role:default/another-role, catalog-entity, read, allow
g, user:default/another-user, role:default/another-role

You can define the basic permission in Developer Hub using the permission name as shown in the following example:

p, role:default/myrole, catalog.entity.create, create, allow
g, user:default/myuser, role:default/myrole

10.3.10. Conditional policies in Red Hat Developer Hub

Use conditional policies with criteria, objects, and aliases to filter access to Developer Hub resources based on dynamic parameters.

The permission framework in Red Hat Developer Hub provides conditions, supported by the RBAC backend plugin (backstage-plugin-rbac-backend). The conditions work as content filters for the Developer Hub resources that are provided by the RBAC backend plugin.

The RBAC backend API stores conditions assigned to roles in the database. When you request to access the front-end resources, the RBAC backend API searches for the corresponding conditions and delegates them to the appropriate plugin by using its plugin ID. If you are assigned to multiple roles with different conditions, then the RBAC backend merges the conditions by using the anyOf criteria.

Conditional criteria

A condition in Developer Hub is a simple condition with a rule and parameters. However, a condition can also contain a parameter or an array of parameters combined by conditional criteria. The supported conditional criteria includes:

allOf
Ensures that all conditions within the array must be true for the combined condition to be satisfied.
anyOf
Ensures that at least one of the conditions within the array must be true for the combined condition to be satisfied.
not
Ensures that the condition within it must not be true for the combined condition to be satisfied.
Conditional object

The plugin specifies the parameters supported for conditions. You can access the conditional object schema from the RBAC API endpoint to understand how to construct a conditional JSON object, which is then used by the RBAC backend plugin API.

A conditional object contains the following parameters:

ParameterTypeDescription

result

String

Always has the value CONDITIONAL

roleEntityRef

String

String entity reference to the RBAC role, such as role:default/dev

pluginId

String

Corresponding plugin ID, such as catalog

permissionMapping

String array

Array permission actions, such as ['read', 'update', 'delete']

resourceType

String

Resource type provided by the plugin, such as catalog-entity

conditions

JSON

Condition JSON with parameters or array parameters joined by criteria

Conditional policy aliases

The RBAC backend plugin (backstage-plugin-rbac-backend) supports the use of aliases in conditional policy rule parameters. The conditional policy aliases are dynamically replaced with the corresponding values during policy evaluation. Each alias in conditional policy is prefixed with a $ sign indicating its special function.

The supported conditional aliases include:

$currentUser

This alias is replaced with the user entity reference for the user who requests access to the resource. For example, if user Tom from the default namespace requests access, $currentUser becomes user:default/tom.

Example conditional policy object with $currentUser alias:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/developer",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["delete"],
  "conditions": {
    "rule": "IS_ENTITY_OWNER",
    "resourceType": "catalog-entity",
    "params": {
      "claims": ["$currentUser"]
    }
  }
}
$ownerRefs

This alias is replaced with ownership references, usually as an array that includes the user entity reference and the user’s parent group entity reference. For example, for user Tom from team-a, $ownerRefs becomes ['user:default/tom', 'group:default/team-a'].

Example conditional policy object with $ownerRefs alias:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/developer",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["delete"],
  "conditions": {
    "rule": "IS_ENTITY_OWNER",
    "resourceType": "catalog-entity",
    "params": {
      "claims": ["$ownerRefs"]
    }
  }
}

10.3.11. Download active users list in Red Hat Developer Hub

Download the list of active users in CSV format from the RBAC page in Developer Hub.

You can download the list of users in CSV format by using the Developer Hub web interface.

Prerequisites

  • RBAC plugins (@backstage-community/plugin-rbac and @backstage-community/plugin-rbac-backend) must be enabled in Red Hat Developer Hub.
  • If RBAC is enabled, you have a role with the following permission: policy.entity.read.

Procedure

  1. In Red Hat Developer Hub, navigate to Administration and select the RBAC tab.
  2. At the bottom of the RBAC page, click Download User List.
  3. Optional: Change the file name in the Save as field and click Save.
  4. To access the downloaded users list, go to the Downloads folder on your local machine and open the CSV file.

10.3.12. Delegate RBAC management to decentralize administration

10.3.12.1. Delegate RBAC management to decentralize administration

Delegate RBAC responsibilities to team leads by using the multitenancy feature and IS_OWNER conditional rule.

An enterprise customer requires the ability to delegate role-based access control (RBAC) responsibilities to other individuals in the organization. In this scenario, you, as the administrator, can give access to the RBAC plugin specifically to designated users, such as team leads. Each team lead is then able to manage permissions only for users within their assigned team or department, without visibility into or control over permissions outside their assigned scope. This approach allows team leads to manage access and permissions for their own teams independently, while administrators keep global oversight.

In Red Hat Developer Hub, you can delegate RBAC access by using the multitenancy feature of the RBAC plugin, specifically the IS_OWNER conditional rule. You can either use the web UI or the RBAC backend API, depending on your preferred workflow and level of automation:

  • Use the web UI to create roles, assign users or groups, define permissions, and apply ownership conditions through an intuitive interface.
  • Use the API for a more flexible and automatable approach, where you can programmatically manage roles, permissions, and ownership conditions using authenticated curl requests.

By delegating RBAC access through either method, you can expect the following outcomes:

  • Team leads can manage RBAC settings for their teams independently.
  • Visibility of other users' or teams' permissions is restricted.
  • Administrators retain overarching control while delegating team-specific access.

Use groups to configure persona-specific homepage layouts, ensuring users see homepage content appropriate to their role.

10.3.12.2. Configure RBAC delegation

10.3.12.2.1. Configure RBAC delegation

Configure RBAC delegation to allow designated users to manage permissions for their teams by using the web UI or the RBAC backend API.

10.3.12.2.2. Delegate RBAC access in Red Hat Developer Hub by using the web UI

Delegate RBAC access to team leads by using the Web UI to create roles with IS_OWNER conditional rules.

You can delegate the RBAC access in Red Hat Developer Hub by using the web UI.

Prerequisites

  • Your RHDH instance is running with the RBAC plugin installed and configured.
  • You have administrative access to RHDH.

Procedure

  1. Log in to your RHDH instance with administrator credentials.
  2. Navigate to Administration → RBAC.
  3. Click Create Role and define a new role for team leads, such as role:default/team_lead.
  4. In the Members section, add the user or group, such as user:default/team_lead.
  5. Grant permissions required by team leads, such as:

    policy.entity.create
    To allow policy creation.
    catalog-entity:read
    To allow catalog access.
  6. Apply conditions to limit access as follows:

    IS_OWNER
    Use the IS_OWNER rule to ensure team leads can only manage resources they own.
  7. Click Save to create the role and apply changes.

Verification

  • Log in as a team lead.
  • Verify the following:

    • RBAC UI is accessible.
    • Only users or roles related to their team are visible.
    • No access to roles or permissions outside their scope is granted.
10.3.12.2.3. Delegate RBAC access in Red Hat Developer Hub by using API

Delegate RBAC access to team leads by using the RBAC backend API to create roles with IS_OWNER conditional rules.

You can delegate the RBAC access in Red Hat Developer Hub by using the RBAC backend API.

Prerequisites

  • Your RHDH instance is running with the RBAC plugin installed and configured.
  • You have administrative access to RHDH.
  • You have API access using curl or another tool.

Procedure

  1. Create a new role designated for team leads by using the RBAC backend API:

    For example, to create a new role for the team lead by using the RBAC backend API:

    $ curl -X POST 'http://localhost:7007/api/permission/roles' \
    --header "Authorization: Bearer $ADMIN_TOKEN" \
    --header "Content-Type: application/json" \
    --data '{
      "memberReferences": ["user:default/team_lead"],
      "name": "role:default/team_lead",
      "metadata": {
        "description": "This is an example team lead role"
      }
    }'
  2. Allow team leads to read catalog entities and create permissions in the RBAC plugin using the following API request:

    For example, to grant the team lead role permission to create RBAC policies and read catalog entities:

    $ curl -X POST 'http://localhost:7007/api/permission/policies' \
    --header "Authorization: Bearer $ADMIN_TOKEN" \
    --header "Content-Type: application/json" \
    --data '[
      {
        "entityReference": "role:default/team_lead",
        "permission": "policy.entity.create",
        "policy": "create",
        "effect": "allow"
      },
      {
        "entityReference": "role:default/team_lead",
        "permission": "catalog-entity",
        "policy": "read",
        "effect": "allow"
      }
    ]'
  3. To ensure team leads can only manage what they own, use the IS_OWNER conditional rule as follows:

    For example, to apply a conditional access policy by using the IS_OWNER rule for the team lead role:

    $ curl -X POST 'http://localhost:7007/api/permission/roles/conditions' \
    --header "Authorization: Bearer $ADMIN_TOKEN" \
    --header "Content-Type: application/json" \
    --data '{
     "result": "CONDITIONAL",
     "pluginId": "permission",
     "resourceType": "policy-entity",
     "conditions": {
       "rule": "IS_OWNER",
       "resourceType": "policy-entity",
       "params": {
         "owners": [
           "user:default/team_lead"
         ]
       }
     },
     "roleEntityRef": "role:default/team_lead",
     "permissionMapping": [
       "read",
       "update",
       "delete"
     ]
    }'

    The previous example of conditional policy limits visibility and control to only owned roles and policies.

  4. Log in to RHDH as team lead and verify the following:

    1. Use the following request and verify that you do not see any roles:

      For example, to retrieve roles visible to the team lead:

      $ curl -X GET 'http://localhost:7007/api/permission/roles' \
      --header "Authorization: Bearer $TEAM_LEAD_TOKEN"
    2. Use the following request to create a new role for their team:

      For example, to create a new role for their team with ownership assigned:

      $ curl -X POST 'http://localhost:7007/api/permission/roles' \
      --header "Authorization: Bearer $TEAM_LEAD_TOKEN" \
      --header "Content-Type: application/json" \
      --data '{
        "memberReferences": ["user:default/team_member"],
        "name": "role:default/team_a",
        "metadata": {
          "description": "This is an example team_a role",
          "owner": "user:default/team_lead"
        }
      }'
      Note

      You can set the ownership during creation, but you can also update the ownership at any time.

    3. Use the following request to assign a permission policy to the new role:

      For example, to grant read access to catalog entities for the new role:

      $ curl -X POST 'http://localhost:7007/api/permission/policies' \
      --header "Authorization: Bearer $ADMIN_TOKEN" \
      --header "Content-Type: application/json" \
      --data '[
        {
          "entityReference": "role:default/team_a",
          "permission": "catalog-entity",
          "policy": "read",
          "effect": "allow"
        }
      ]'
    4. Use the following request to verify that only team-owned roles and policies are visible:

      For example, to retrieve roles and permission policies visible to the team lead:

      $ curl -X GET 'http://localhost:7007/api/permission/roles' \
      --header "Authorization: Bearer $TEAM_LEAD_TOKEN"
      
      $ curl -X GET 'http://localhost:7007/api/permission/policies' \
      --header "Authorization: Bearer $TEAM_LEAD_TOKEN"

Verification

  • Log in as a team lead and verify the following:

    • The RBAC UI is accessible.
    • Only the assigned users or group is visible.
    • Permissions outside the scoped team are not viewable or editable.
  • Log in as an administrator and verify that you retain full visibility and control.

Chapter 11. Observe

11.1. Observe

TODO: Replace this placeholder with an overview of Observe.

11.2. Monitor system logs and application metrics to ensure platform availability

11.2.1. Monitor system logs and application metrics to ensure platform availability

TODO: Replace this placeholder with an overview of Monitor system logs and application metrics to ensure platform availability.

11.3. Manage telemetry collection to balance data insights with privacy requirements

11.3.1. Manage telemetry collection to balance data insights with privacy requirements

TODO: Replace this placeholder with an overview of Manage telemetry collection to balance data insights with privacy requirements.

11.4. Capture and review audit logs to trace user activities and maintain accountability

11.4.1. Capture and review audit logs to trace user activities and maintain accountability

TODO: Replace this placeholder with an overview of Capture and review audit logs to trace user activities and maintain accountability.

11.5. Centralize workflow observability

11.5.1. Centralize workflow observability

TODO: Replace this placeholder with an overview of Centralize workflow observability.

11.5.2. Deploy observability manifests to configure the Jaeger and Loki stacks

11.5.2.1. Deploy observability manifests to configure the Jaeger and Loki stacks

TODO: Replace this placeholder with an overview of Deploy observability manifests to configure the Jaeger and Loki stacks.

11.5.3. Trace attribute definitions and filtering keys

11.5.3.1. Trace attribute definitions and filtering keys

TODO: Replace this placeholder with an overview of Trace attribute definitions and filtering keys.

11.6. Collect diagnostic data to troubleshoot platform issues

11.6.1. Collect diagnostic data to troubleshoot platform issues

TODO: Replace this placeholder with an overview of Collect diagnostic data to troubleshoot platform issues.

11.6.2. Run must-gather on OpenShift to collect diagnostic data

11.6.2.1. Run must-gather on OpenShift to collect diagnostic data

TODO: Replace this placeholder with an overview of Run must-gather on OpenShift to collect diagnostic data.

Chapter 12. Integrate

12.1. Integrate

TODO: Replace this placeholder with an overview of Integrate.

12.2. Enable AI assistance for developers

12.2.1. Enable AI assistance for developers

TODO: Replace this placeholder with an overview of Enable AI assistance for developers.

12.2.2. Developer Lightspeed for RHDH architecture

12.2.2.1. Developer Lightspeed for RHDH architecture

TODO: Replace this placeholder with an overview of Developer Lightspeed for RHDH architecture.

12.2.3. Build a private knowledge base with Lightspeed Notebooks

12.2.3.1. Build a private knowledge base with Lightspeed Notebooks

TODO: Replace this placeholder with an overview of Build a private knowledge base with Lightspeed Notebooks.

12.2.4. Configure Model Context Protocol tools to enhance AI interactions with portal data

12.2.4.1. Configure Model Context Protocol tools to enhance AI interactions with portal data

TODO: Replace this placeholder with an overview of Configure Model Context Protocol tools to enhance AI interactions with portal data.

12.2.4.2. Enable Scaffolder MCP tools

12.2.4.2.1. Enable Scaffolder MCP tools

TODO: Replace this placeholder with an overview of Enable Scaffolder MCP tools.

12.2.5. Accelerate AI model discovery by integrating the OpenShift AI Connector

12.2.5.1. Accelerate AI model discovery by integrating the OpenShift AI Connector

TODO: Replace this placeholder with an overview of Accelerate AI model discovery by integrating the OpenShift AI Connector.

12.3. Integrate CI/CD and infrastructure tools to visualize pipelines and workloads

12.3.1. Integrate CI/CD and infrastructure tools to visualize pipelines and workloads

TODO: Replace this placeholder with an overview of Integrate CI/CD and infrastructure tools to visualize pipelines and workloads.

Chapter 13. Optimize

13.1. Optimize

TODO: Replace this placeholder with an overview of Optimize.

13.2. Scale system performance for growing traffic

13.2.1. Scale system performance for growing traffic

TODO: Replace this placeholder with an overview of Scale system performance for growing traffic.

13.2.2. Configure the dynamic plugins cache

13.2.2.1. Configure the dynamic plugins cache

TODO: Replace this placeholder with an overview of Configure the dynamic plugins cache.

Chapter 14. Extend

14.1. Extend

TODO: Replace this placeholder with an overview of Extend.

14.2. Manage the plugin ecosystem to add functionality without downtime

14.2.1. Manage the plugin ecosystem to add functionality without downtime

TODO: Replace this placeholder with an overview of Manage the plugin ecosystem to add functionality without downtime.

14.2.2. Install dynamic plugins

14.2.2.1. Install dynamic plugins

TODO: Replace this placeholder with an overview of Install dynamic plugins.

14.2.3. Browse and manage available plugins using the Extensions UI

14.2.3.1. Browse and manage available plugins using the Extensions UI

TODO: Replace this placeholder with an overview of Browse and manage available plugins using the Extensions UI.

14.2.4. Configure core front-end wiring for navigation and UI components

14.2.4.1. Configure core front-end wiring for navigation and UI components

TODO: Replace this placeholder with an overview of Configure core front-end wiring for navigation and UI components.

14.2.5. Configure route bindings and mount points for component integration

14.2.5.1. Configure route bindings and mount points for component integration

TODO: Replace this placeholder with an overview of Configure route bindings and mount points for component integration.

14.2.6. Configure specialized front-end extensions for APIs and features

14.2.6.1. Configure specialized front-end extensions for APIs and features

TODO: Replace this placeholder with an overview of Configure specialized front-end extensions for APIs and features.

14.2.7. Filter plugins by support badges

14.2.7.1. Filter plugins by support badges

TODO: Replace this placeholder with an overview of Filter plugins by support badges.

14.3. Develop custom dynamic plugins to support custom workflows

14.3.1. Develop custom dynamic plugins to support custom workflows

TODO: Replace this placeholder with an overview of Develop custom dynamic plugins to support custom workflows.

14.3.2. Package and deploy dynamic plugins as OCI images

14.3.2.1. Package and deploy dynamic plugins as OCI images

TODO: Replace this placeholder with an overview of Package and deploy dynamic plugins as OCI images.

14.4. Manage containerized plugins securely by migrating to OCI artifacts

14.4.1. Manage containerized plugins securely by migrating to OCI artifacts

TODO: Replace this placeholder with an overview of Manage containerized plugins securely by migrating to OCI artifacts.

14.4.2. Migrate community plugins to the GitHub Container Registry

14.4.2.1. Migrate community plugins to the GitHub Container Registry

TODO: Replace this placeholder with an overview of Migrate community plugins to the GitHub Container Registry.

Chapter 15. Troubleshoot

15.1. Troubleshoot

Diagnose and resolve issues with authentication, configuration, plugins, workflows, and AI integrations in Developer Hub.

15.2. Troubleshoot user access and authentication issues to restore user entry

15.2.1. Troubleshoot user access and authentication issues to restore user entry

Resolve authentication failures, session expiration issues, and configuration problems that prevent users from accessing Developer Hub.

15.2.2. Troubleshoot authentication issues

15.2.2.1. Troubleshoot authentication issues

Learn how to troubleshoot common authentication issues.

15.2.2.2. Reduce the size of issued tokens

If user identity tokens grow large and cause HTTP errors, you can use the omitIdentityTokenOwnershipClaim flag to remove the ent claim from the JWT payload and reduce token size.

Procedure

  • In the app-config.yaml file, set omitIdentityTokenOwnershipClaim to true as follows:

    auth:
      omitIdentityTokenOwnershipClaim: true

15.2.2.3. Troubleshoot unexpected session expiration

If sessions expire sooner than expected, check the following settings. The mechanism with the shortest timeout takes effect first.

Procedure

  1. Check the Identity Provider (IdP) session timeout: the IdP might have a shorter session lifetime than Developer Hub.
  2. Check the sessionDuration parameter for your authentication provider.
  3. Check the AutoLogout idleTimeoutMinutes setting, if auto-logout is enabled.

15.2.2.4. Troubleshoot missing session expiration warning

If users receive no warning before their session expires, auto-logout might not be enabled. Without auto-logout, sessions expire silently based on sessionDuration or IdP settings.

Procedure

  • To enable pre-expiration warnings, configure the auth.autologout settings in your app-config.yaml file.

15.2.2.5. Troubleshoot missing login redirect after session expiration

If users are not redirected to the login page after their session expires, verify the following.

Procedure

  1. Verify that your Developer Hub version includes the upstream session expiration fix.
  2. Verify that your authentication provider is correctly configured with valid metadataUrl, clientId, and clientSecret settings.

15.2.2.6. Troubleshoot login failed errors

When a user cannot sign in to Developer Hub, the sign-in page displays a "Login failed" error message. The following sections describe common login errors and their solutions.

15.2.2.6.1. Login failed: unable to resolve user identity
Login failed; caused by Error: Failed to sign-in, unable to resolve user identity. Please verify that your catalog contains the expected User entities that would match your configured sign-in resolver.

This error indicates that the user signing in does not match a user entity in the Developer Hub software catalog.

To resolve this issue:

  1. Check that the corresponding catalog provider plugin is set up correctly and is successfully syncing users and groups into the catalog.

    In the backend logs, look for a successful synchronization message such as:

    catalog info Read 114 GitHub users and 22 GitHub groups in 3.4 seconds. Committing...
    catalog info Committed 114 GitHub users and 22 GitHub groups in 0.0 seconds.
  2. If users and groups have been ingested into the catalog, verify that the sign-in resolver used (default or configured) matches the correct user attributes.
  3. Optionally, use guest login to look into the user entity in the catalog and verify the attributes.
15.2.2.6.2. Login failed: provider not configured to support sign-in
Login failed; caused by Error: The <providerId> provider is not configured to support sign-in.

This error indicates that the authentication provider has disableIdentityResolution set to true, meaning it is configured as an auxiliary provider, not for primary sign-in.

To resolve this issue:

  • In your app-config.yaml file, ensure that disableIdentityResolution is not set to true for your primary sign-in authentication provider.
15.2.2.6.3. Login failed: user profile does not contain an email
Login failed, user profile does not contain an email

This error indicates that the authentication client does not have permission to read the user’s email from the identity provider.

To resolve this issue:

  • Grant the necessary email-reading permissions to the authentication client in the identity provider.
  • Or, use a sign-in resolver that does not rely on email, such as preferredUsernameMatchingUserEntityName instead of emailMatchingUserEntityProfileEmail.

15.2.2.7. Diagnose specific login failures

Common login errors encountered during authentication and their solutions.

15.2.2.7.1. Login failed: unable to resolve user identity
Login failed; caused by Error: Failed to sign-in, unable to resolve user identity. Please verify that your catalog contains the expected User entities that would match your configured sign-in resolver.

This error indicates that the user signing in does not match a user entity in the Developer Hub software catalog.

To resolve this issue:

  1. Check that the corresponding catalog provider plugin is set up correctly and is successfully syncing users and groups into the catalog.

    In the backend logs, look for a successful synchronization message such as:

    catalog info Read 114 GitHub users and 22 GitHub groups in 3.4 seconds. Committing...
    catalog info Committed 114 GitHub users and 22 GitHub groups in 0.0 seconds.
  2. If users and groups have been ingested into the catalog, verify that the sign-in resolver used (default or configured) matches the correct user attributes.
  3. Optionally, use guest login to look into the user entity in the catalog and verify the attributes.
15.2.2.7.2. Login failed: provider not configured to support sign-in
Login failed; caused by Error: The <providerId> provider is not configured to support sign-in.

This error indicates that the authentication provider has disableIdentityResolution set to true, meaning it is configured as an auxiliary provider, not for primary sign-in.

To resolve this issue:

  • In your app-config.yaml file, ensure that disableIdentityResolution is not set to true for your primary sign-in authentication provider.
15.2.2.7.3. Login failed: user profile does not contain an email
Login failed, user profile does not contain an email

This error indicates that the authentication client does not have permission to read the user’s email from the identity provider.

To resolve this issue:

  • Grant the necessary email-reading permissions to the authentication client in the identity provider.
  • Or, use a sign-in resolver that does not rely on email, such as preferredUsernameMatchingUserEntityName instead of emailMatchingUserEntityProfileEmail.

15.2.2.8. Troubleshoot catalog provider errors

Catalog provider plugins can fail to ingest users and groups into the Developer Hub software catalog. The following sections describe common catalog provider errors visible in the backend logs and their solutions.

15.2.2.8.1. LDAP: Malformed entity envelope
LdapOrgEntityProvider:default refresh failed, TypeError: Malformed entity envelope, TypeError: /metadata/name must NOT have fewer than 1 characters - limit: 1

This error occurs when a user being ingested from LDAP has no value for the name field, which is mapped to the uid LDAP attribute by default.

To resolve this issue:

  • Add a filter to the LDAP users configuration to exclude users without a uid:

    catalog:
      providers:
        ldapOrg:
          default:
            users:
              - dn: OU=Users,DC=example,DC=com
                options:
                  filter: (uid=*)
15.2.2.8.2. GitHub: API rate limit exceeded
GithubMultiOrgEntityProvider:default refresh failed, HttpError: API rate limit exceeded

This error occurs when Developer Hub makes unauthenticated API calls to GitHub, which are limited to 60 requests per hour. Authenticated requests using a GitHub App get up to 5,000 requests per hour.

To resolve this issue:

  • Verify that the integrations.github section is configured in your app-config.yaml file with valid GitHub App credentials.
15.2.2.8.3. GitLab: API rate limit exceeded

This error occurs when Developer Hub makes unauthenticated API calls to GitLab, which are subject to rate limits.

To resolve this issue:

  • Verify that the integrations.gitlab section is configured in your app-config.yaml file with a valid GitLab personal access token.

15.2.2.9. Resolve malformed LDAP entity envelopes

This error occurs when a user being ingested from LDAP has no value for the name field, which is mapped to the uid LDAP attribute by default.

Prerequisites

  • You have configured LDAP user provisioning in Developer Hub.

Procedure

  • Add a filter to the LDAP users configuration to exclude users without a uid:

    catalog:
      providers:
        ldapOrg:
          default:
            users:
              - dn: OU=Users,DC=example,DC=com
                options:
                  filter: (uid=*)

Verification

  • Check the backend logs for successful LDAP synchronization without the malformed entity envelope error:

    LdapOrgEntityProvider:default refresh succeeded

15.2.3. Troubleshoot configuration issues

15.2.3.1. Troubleshoot configuration issues

Resolve common configuration issues in Developer Hub, such as Helm overwriting predefined array values.

15.2.3.2. Fix Helm overwriting predefined arrays

If you use Helm to install dynamic plugins, you might meet an issue where predefined values in fields with arrays are overwritten after you add new values. The issue affects fields such as:

  • extraEnvVars
  • extraVolumeMounts
  • extraVolumes

Fix this issue by duplicating the predefined values from RHDH Helm Chart’s values.yaml file into your own version of the file.

Procedure

  1. For extraEnvVars, add the following content to your values.yaml file:

    extraEnvVars:
          - name: BACKEND_SECRET
            valueFrom:
              secretKeyRef:
                key: backend-secret
                name: '{{ include "rhdh.backend-secret-name" $ }}'
          - name: POSTGRESQL_ADMIN_PASSWORD
            valueFrom:
              secretKeyRef:
                key: postgres-password
                name: '{{- include "rhdh.postgresql.secretName" . }}'
  2. For extraVolumeMounts, add the following content to your values.yaml file:

    extraVolumeMounts:
          - name: dynamic-plugins-root
            mountPath: /opt/app-root/src/dynamic-plugins-root
          - name: temp
            mountPath: /tmp
  3. For extraVolume, add the following content to your values.yaml file:

    extraVolumes:
          - name: dynamic-plugins-root
            ephemeral:
              volumeClaimTemplate:
                spec:
                  accessModes:
                    - ReadWriteOnce
                  resources:
                    requests:
                      storage: 5Gi

15.3. Troubleshoot plugin and workflow deployment errors to resume automation

15.3.1. Troubleshoot plugin and workflow deployment errors to resume automation

Diagnose and resolve pod startup failures and serverless workflow deployment issues in Developer Hub.

15.3.2. Troubleshoot a pod startup failure after enabling a plugin

If the RHDH pod fails to start after enabling a plugin, you can inspect the pod logs and configure the required environment variables.

Procedure

  1. Inspect your RHDH pod logs to identify if the plugin requires specific environment variables or additional configuration, for example:

    Plugin '<PLUGIN_NAME>' threw an error during startup, waiting for X other plugins to finish before shutting down the process. Plugin '<PLUGIN_NAME>' startup failed; caused by Error: Missing required config value at '<concretePluginRequiredVariable.name>' in 'app-config.local.yaml' type="initialization"
  2. Verify the required configuration by inspecting the dynamic-plugins.default.yaml file that lists the required environment variables for each plugin. The variables for each plugin are in the format of ${PLUGIN_VARIABLE_NAME}.
  3. If any required environment variables are missing, set the environment variables by using a secret. For example:

    kind: Secret
    apiVersion: v1
    metadata:
      name: rhdh-secrets
      labels:
        backstage.io/kubernetes-id: developer-hub
    data:
      PLUGIN_VARIABLE_NAME: 'dummy-value'
    type: Opaque
  4. Mount the secret:

    1. If you deployed RHDH by using the Operator, update your Backstage CR, as follows:

      spec:
        application:
          extraEnvs:
            secrets:
              - name: rhdh-secrets
    2. If you deployed RHDH by using the Helm chart, in the upstream.backstage key in your Helm chart values, enter the name of the Developer Hub rhdh-secrets secret as the value for the extraEnvVarsSecrets field. For example:

      upstream:
        backstage:
          extraEnvVarsSecrets:
            - rhdh-secrets

15.3.3. Diagnose serverless workflow issues

15.3.3.1. Diagnose serverless workflow issues

Troubleshoot HTTP error codes, deployment errors, cross-namespace configuration issues, and missing workflows in the Orchestrator plugin.

15.3.3.2. Troubleshoot workflow HTTP error codes

Workflow operations fail when a service endpoint returns an HTTP error code. The user interface displays the HTTP code and error message.

The following table lists common HTTP errors encountered during workflow execution:

HTTP codeDescriptionPossible cause

401

Unauthorized access

The token, password, or username provided for the endpoint might be incorrect or expired.

403

Forbidden

The server understood the request but refused to process it due to insufficient permissions to a resource or action.

409

Conflict

The workflow attempted to create or update a resource (for example, Kubernetes or OpenShift resources) that already exists.

Additional resources

15.3.3.3. Troubleshoot common workflow deployment errors

Use these steps to diagnose and resolve common workflow deployment, connectivity, or configuration failures.

Procedure

  1. If the workflow operation fails, examine the container log of the specific workflow instance to determine the cause by running the following command:

    $ oc logs my-workflow-xy73lj
  2. If the workflow fails to reach an HTTPS endpoint, check the pod log for an SSL certificate verification failure. This occurs if the target endpoint uses a Certificate Authority (CA) that the workflow cannot verify. The resulting error resembles the following:

    sun.security.provider.certpath.SunCertPathBuilderException - unable to find valid certification path to requested target
  3. To resolve the SSL certificate error, load the additional CA certificate into the running workflow container.

15.3.3.4. Troubleshoot cross-namespace SonataFlow configuration and deployment issues

Use this procedure to resolve configuration and deployment failures when SonataFlow workflows are installed in a namespace separate from the core services, or if the Data Index fails to connect to the PostgreSQL database.

Prerequisites

  • You have administrator privileges to access the OpenShift cluster.

Procedure

  1. Identify required namespaces.
  2. Retrieve the namespace value where RHDH is running using oc get backstage -A.
  3. Identify the SonataFlow Services Namespace by checking for either a sonataflowclusterplatform or sonataflowplatform instance.

    Note

    By default, the SonataFlow namespace must be the same as the RHDH namespace.

  4. If the workflow is deployed to a namespace outside the core SonataFlow services, configure network policies to permit the necessary inter-namespace traffic.

    # Example NetworkPolicy configuration to ingress traffic into the workflow namespace
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: {{ .Release.Name }}-allow-infra-ns-to-workflow-ns
      # SonataFlow and Workflows are using the RHDH target namespace.
      namespace: {{ .Release.Namespace | quote }}
    spec:
      podSelector: {}
      ingress:
        - from:
          - namespaceSelector:
              matchLabels:
                # Allow knative events to be delivered to workflows.
                kubernetes.io/metadata.name: knative-eventing
          - namespaceSelector:
              matchLabels:
                # Allow auxiliary knative function for workflow (such as m2k-save-transformation)
                kubernetes.io/metadata.name: knative-serving
          - namespaceSelector:
              matchLabels:
                # Allow communication between the serverless logic operator and the workflow namespace.
                kubernetes.io/metadata.name: openshift-serverless-logic
  5. Add SonataFlowClusterPlatform Custom Resource as shown in the following configuration:

    oc create -f - <<EOF
    apiVersion: sonataflow.org/v1alpha08
    kind: SonataFlowClusterPlatform
    metadata:
      name: cluster-platform
    spec:
      platformRef:
        name: sonataflow-platform
        namespace: $RHDH_NAMESPACE
  6. To allow communication between RHDH namespace and the workflow namespace, create the following network policies:

    1. Allow RHDH services to accept traffic from workflows. Create an additional network policy within the RHDH instance namespace as shown in the following configuration::

      oc create -f - <<EOF
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-external-workflows-to-rhdh
        # Namespace where network policies are deployed
        namespace: $RHDH_NAMESPACE
      spec:
        podSelector: {}
        ingress:
          - from:
            - namespaceSelector:
                matchLabels:
                  # Allow SonataFlow services to communicate with new/additional workflow namespace.
                  kubernetes.io/metadata.name: $ADDITIONAL_WORKFLOW_NAMESPACE
    2. Allow traffic from RHDH, SonataFlow and Knative. Create a network policy within the additional workflow namespace as shown in the following configuration:

      oc create -f - <<EOF
      apiVersion: networking.k8s.io/v1
      kind: NetworkPolicy
      metadata:
        name: allow-rhdh-and-knative-to-workflows
        namespace: $ADDITIONAL_WORKFLOW_NAMESPACE
      spec:
        podSelector: {}
        ingress:
          - from:
            - namespaceSelector:
                matchLabels:
                  # Allows traffic from pods in the RHDH namespace.
                  kubernetes.io/metadata.name: $RHDH_NAMESPACE
            - namespaceSelector:
                matchLabels:
                  # Allows traffic from pods in the Knative Eventing namespace.
                  kubernetes.io/metadata.name: knative-eventing
            - namespaceSelector:
                matchLabels:
                  # Allows traffic from pods in the Knative Serving namespace.
                  kubernetes.io/metadata.name: knative-serving
  7. (Optional) Create an allow-intra-namespace policy in the workflow namespace to enable unrestricted communication among all pods within that namespace.
  8. If workflow persistence is required, perform the following configuration steps:

    1. Create a dedicated PostgreSQL Secret containing database credentials within the workflow namespace as shown in the following configuration:

      oc get secret sonataflow-psql-postgresql -n <your_namespace> -o yaml > secret.yaml
      sed -i '/namespace: <your_namespace>/d' secret.yaml
      oc apply -f secret.yaml -n $ADDITIONAL_NAMESPACE
    2. Configure the workflow serviceRef property to correctly reference the PostgreSQL service namespace as shown in the following configuration:

      apiVersion: sonataflow.org/v1alpha08
      kind: SonataFlow
        ...
      spec:
        ...
        persistence:
          postgresql:
            secretRef:
              name: sonataflow-psql-postgresql
              passwordKey: postgres-password
              userKey: postgres-username
            serviceRef:
              databaseName: sonataflow
              databaseSchema: greeting
              name: sonataflow-psql-postgresql
              namespace: $POSTGRESQL_NAMESPACE
              port: 5432
      namespace
      Enter the namespace where the PostgreSQL server is deployed.
  9. If the sonataflow-platform-data-index-service cannot connect to the PostgreSQL database on startup, perform the following diagnostic checks:

    1. Verify that the PostgreSQL Pod has fully transitioned to a running and operational status. Allow additional time for database initialization before expecting related service pods (DataIndex, JobService) to establish a connection.
    2. If the PostgreSQL Server operates in a dedicated namespace (for example, outside RHDH), verify that network policies are configured to allow ingress traffic from the SonataFlow services namespace. Network policies might prevent the Data Index and Job Service pods from connecting to the database.

15.3.3.5. Troubleshoot workflows missing from the RHDH UI

You can perform the following checks to verify the workflow status and connectivity when the deployed workflow is missing from the RHDH Orchestrator UI.

Prerequisites

  • You have administrator privileges to access the OpenShift cluster where RHDH and SonataFlow services are running.

Procedure

  1. Verify if the workflow uses GitOps profile. The RHDH Orchestrator UI displays only the workflows that use this profile. Make sure the workflow definition and the SonataFlow manifests use the GitOps profile.
  2. Verify that the workflow pod has started and is ready. The readiness of a workflow pod depends on its successful registration with the Data Index. When a workflow initializes, it performs the following actions:

    1. It attempts to create its schema in the database (if persistence is active).
    2. It attempts to register itself to the Data Index. The workflow pod remains in an unready state until it successfully registers to the Data Index.

      Check the workflow deployment for additional status and error messages that might be unavailable in the pod log.

  3. Check if the workflow pod can reach the Data Index service. Connect to the workflows pod and send the following GraphQL request to the Data Index:

    curl -g -k  -X POST  -H "Content-Type: application/json" \
                        -d '{"query":"query{ ProcessDefinitions  { id, serviceUrl, endpoint } }"}' \
                        http://sonataflow-platform-data-index-service.<your_namespace>/graphql

    Use the Data Index service and namespace as defined in your environment. By default, this is the same namespace where RHDH is installed. If your SonataFlow resources are installed in a separate namespace, use <your_namespace>. Check if the RHDH pod can reach the workflow service by running the following command:

    curl http://<workflow_service>.<workflow_namespace>/management/processes
  4. Connect to the RHDH pod. Verify its connection to the Data Index service and inspect the RHDH pod logs for messages from the Orchestrator plugin.

    To inspect the logs, identify the RHDH pod and run the following oc logs command:

    oc get pods -n <your_namespace>
    oc logs <rhdh_pod_name> -n <your_namespace>

    You must find messages indicating it is attempting to fetch workflow information from the Data Index, similar to the following:

    {"level":"\u001b[32minfo\u001b[39m","message":"fetchWorkflowInfos() called: http://sonataflow-platform-data-index-service.<your_namespace>","plugin":"orchestrator","service":"backstage","span_id":"fca4ab29f0a7aef9","timestamp":"2025-08-04 17:58:26","trace_flags":"01","trace_id":"5408d4b06373ff8fb34769083ef771dd"}

    Notice the "plugin":"orchestrator" that can help to filter the messages.

  5. Make sure the Data Index properties are set in the -managed-props ConfigMap of the workflow as shown in the following configuration:

    kogito.data-index.health-enabled = true
    kogito.data-index.url = http://sonataflow-platform-data-index-service.<your_namespace>
    ...
    mp.messaging.outgoing.kogito-processdefinitions-events.url = http://sonataflow-platform-data-index-service.<your_namespace>/definitions
    mp.messaging.outgoing.kogito-processinstances-events.url = http://sonataflow-platform-data-index-service.<your_namespace>/processes
    Note

    The -managed-props ConfigMap is located in the same namespace as the workflow and is generated by the OpenShift Serverless Logic (OSL) Operator.

    These properties, along with similar settings for the Job Services, indicate that the (OSL) Operator successfully registered the Data Index service.

  6. Confirm that the workflow is registered in the Data Index database. Connect to the database used by the Data Index and run the following command from the PSQL instance pod:

    PGPASSWORD=<psql password> psql -h localhost -p 5432 -U < user> -d sonataflow

    Replace <psql password> and <user> with your database credentials.

    Run the following SQL commands to query the registered workflow definitions:

    sonataflow=# SET search_path TO "sonataflow-platform-data-index-service";
    sonataflow=# select id, name from definitions;

    You must see your workflows listed in the query results.

  7. Make sure you have enabled Data Index and Job Service in the SonataFlowPlatform custom resource (CR) as shown in the following configuration:

    services:
        dataIndex:
          enabled: true
        jobService:
          enabled: true

    If you fail to enable the Data Index and the Job Services in the SonataFlowPlatform custom resource (CR), the Orchestrator plugin fails to fetch the available workflows.

    Note

    You can also manually edit the SonataFlowPlatform CR instance to trigger the re-creation of workflow-related manifests.

  8. Configure role-based access control (RBAC) permissions to ensure workflows are visible in the Orchestrator UI.

    Note

    When the RBAC plugin is enabled, the Orchestrator UI does not display workflows by default. You must explicitly grant read permissions.

    1. Check your RHDH app-config.yaml file to confirm if the RBAC plugin is enabled.
    2. Confirm your user or role has the orchestrator.workflow permission with the read action.
    3. If this permission is missing, add the following to your RBAC CSV (rbac-policy.csv) file:

      p, role:default/workflowUser, orchestrator.workflow, read, allow
    4. Make sure policyFileReload is set to true in your configuration, or restart the RHDH application:

      permission:
        enabled: true
        rbac:
          policyFileReload: true

15.4. Troubleshoot AI and tool integrations to restore intelligent features

15.4.1. Troubleshoot AI and tool integrations to restore intelligent features

Diagnose and resolve issues with the OpenShift AI Connector and Model Context Protocol (MCP) server and client integrations.

15.4.2. Troubleshoot AI Connector functionality

15.4.2.1. Troubleshoot AI Connector functionality

The connector system consists of the two dynamic plugins and the three OpenShift AI Connector for RHDH sidecar containers. You must gather logs from these components and provide them to Red Hat Support for diagnostic analysis.

The actual contents of the diagnostic data are not part of any product guaranteed specification, and can change at any time.

Note

During startup, you might see non-critical log errors, such as in cluster config error: open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory, in the sidecar logs. This error is expected during the initial setup and does not indicate a failure, provided the container eventually becomes healthy.

15.4.2.2. Verify dynamic plugin status

Validate that the dynamic plugins have been successfully installed into your RHDH project Pod.

Procedure

  • Use the following command to check the installation logs:

    $ oc logs -c install-dynamic-plugins deployment/<your RHDH deployment>

Verification

In the install-dynamic-plugin logs, you can check the following installation logs for successful logs:

  1. red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog (Entity Provider)
  2. red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend (TechDoc URL Reader)

15.4.2.3. Inspect plugin logs

View the OpenShift AI Connector for Red Hat Developer Hub plugins in the backstage-backend container to diagnose issues.

Procedure

  1. Check the plugin logs for the following components:

    Plugin ComponentLogger Service TargetCommon Log Text

    Model Catalog Entity Provider

    ModelCatalogResourceEntityProvider

    Discovering ResourceEntities from Model Server…​

    Model Catalog TechDoc URL Reader

    ModelCatalogBridgeTechdocUrlReader

    ModelCatalogBridgeTechdocUrlReader.readUrl

  2. Optional: To enable debug logging, set the LOG_LEVEL environment variable to debug on the backstage-backend container.

Additional resources

15.4.2.4. Inspect the OpenShift AI Connector

The OpenShift AI Connector for RHDH sidecars manage the data fetching and storage. Use these steps to inspect their state and logs.

Procedure

  1. Check Cached Data (ConfigMap): The processed AI Model metadata is stored in a ConfigMap.

    $ oc get configmap bac-import-model -o json | jq -r '.binaryData | to_entries[] | "=== \(.key) ===\n" + (.value | @base64d | fromjson | .body | @base64d | fromjson | tostring)' | jq -R 'if startswith("=== ") then . else (. | fromjson) end'
  2. Check Location Service API: Confirm the location service is providing data to the RHDH Entity Provider.

    $ oc rsh -c backstage-backend deployment/<your RHDH deployment>
    $ curl http://localhost:9090/list
  3. Check Sidecar Container Logs:

    $ oc logs -c rhoai-normalizer deployment/<your {product-very-short} deployment>
    $ oc logs -c storage-rest deployment/<your {product-very-short} deployment>
    $ oc logs -c location deployment/<your {product-very-short} deployment>

15.4.2.5. Red Hat OpenShift AI model registry and model catalog queries

To access the same RHOAI data as the connector, use curl to query the RHOAI model registry and model catalog APIs, ensuring the ServiceAccount token has correct access control:

  • Example showing how to fetch registered models

    $ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/registered_models | jq
  • Example showing how to fetch model versions

    $ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/model_versions | jq
  • Example showing how to fetch model artifacts

    $ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/model_artifacts | jq
  • Example showing how to fetch inference services

    $ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/inference_services | jq
  • Example showing how to fetch serving environments

    $ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/serving_environments | jq
  • Example showing how to fetch catalog sources

    $ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_CATALOG_URL/api/model_catalog/v1alpha1/sources | jq

15.4.3. Troubleshoot MCP server and client problems

15.4.3.1. Troubleshoot MCP server and client problems

Diagnose and resolve common issues with MCP server installation, client configuration, and tool execution in Developer Hub.

15.4.3.2. Verify successful installation of MCP plugins

Verify MCP plugin installation by checking pod logs for successful plugin loading and MCP tool registration.

Procedure

  1. Log in to the OCP cluster running RHDH and go to your RHDH project using the following code:

    $ oc project my-rhdh-project
  2. Inspect the logs for the installation of the RHDH dynamic plugins using the following code:

    $ oc logs -c install-dynamic-plugins deployment/<my-product-deployment>

Verification

  1. You must see an entry for the MCP backend server plugin as shown in the following code:

    ..... prior logs ....
    ======= Installing dynamic plugin oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-mcp-actions-backend:<tag>
    	==> Copying image oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-mcp-actions-backend:<tag> to local filesystem
    	==> Successfully installed dynamic plugin oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-mcp-actions-backend:<tag>

    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:
  2. Find your Backstage version in the RHDH release notes preface.
  3. 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. You must see entries for any of the MCP tool plugins you installed as shown in the following code:

    ..... prior logs ....
    ======= Installing dynamic plugin oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool:<tag>
    	==> Copying image oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool:<tag> to local filesystem
    	==> Successfully installed dynamic plugin oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-tool:<tag>

    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:
  5. Find your Backstage version in the RHDH release notes preface.
  6. 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.

15.4.3.3. Check MCP tool logs for status and errors

Review Backstage LoggerService logs for MCP tool execution status and error messages.

The Backstage LoggerService target name starts with the name of the MCP tool (either software-catalog-mcp-tool or techdocs-mcp-tool). The MCP tools generate a log by default. For example:

`[backend]: 2025-09-25T16:24:22.660Z software-catalog-mcp-tool info fetch-catalog-entities: Fetching catalog entities with options: kind="Component"`

If any errors occur in the MCP tools, check the logs.

15.4.3.4. MCP tool error messages

MCP tools provide optional error messages that communicate issues including input validation errors encountered during tool use.

The MCP tools response provides an optional error message that communicates any issues encountered during the use of the tool, including potential input validation errors.

15.4.3.5. Resolve the Model does not support tool calling error

Resolve tool calling errors by confirming your AI model supports tool calls and switching to a compatible model if needed.

This error indicates that the model configured in your MCP client lacks the required functionality to handle tool calls. The error message appears similar to: Invalid request: model gemma3:27b does not support tool calls.

Procedure

  1. Consult your model documentation to confirm its support for tool calling.
  2. If the current model does not support tool calling, change the model that your MCP client uses to a tool-calling compatible model.

15.4.3.6. Resolve authentication issues when tools are not found

Verify authentication tokens and configuration settings when Model Context Protocol (MCP) clients connect to the server but do not display deployed tools.

If an MCP client connects to the server but cannot find deployed tools, verify the authentication status and endpoint resolution.

Procedure

  1. Check the token validation status in the Red Hat Developer Lightspeed for Red Hat Developer Hub interface:

    1. In the Red Hat Developer Lightspeed for Red Hat Developer Hub chat box, click the menu icon (Chatbot options) and select MCP settings.
    2. Locate the relevant server and check the status message displayed below the token field.
    3. If the status is Authorization failed. Try again, the token is incorrect, improperly formatted, or missing. You must verify the token value and ensure the server is enabled.
  2. Verify the authentication token configuration.

    1. Ensure a static token is configured for the RHDH MCP server.
    2. In your MCP client, verify that the token is set as the bearer token. The authorization header must use the Bearer <mcp_token> format.
  3. Check the MCP endpoint configuration.

    1. Confirm that the MCP server URL properly resolves correctly, particularly when using desktop clients.
    2. Use legacy SSE endpoint if your MCP client requires it instead of the Streamable endpoint. (For more details, see the Configuration topic).
  4. Verify the RHDH app-config.yaml file for formatting errors:

    1. Ensure there are no duplicate backend entries and that the YAML indentation is accurate.
    2. Confirm that the configuration for the static token and MCP plugin sources is nested under an existing backend field, if one is present. For a reference configuration, see Configure MCP in RHDH.

15.4.3.7. Resolve nonsensical MCP tool output

Improve MCP tool output quality by using larger models or models with larger context windows when nonsensical results occur.

Nonsensical output often occurs when smaller models or models with smaller context sizes cannot effectively manage repeated tool calls within the same context window.

Procedure

  1. Select an appropriate model for tool calling.

    1. Verify that the model has good support for tool calling.
    2. Make sure your model is not too small. We recommend a model with at least 7 billion parameters and a context window of 32k.
  2. Refine your queries.

    1. Use more well-defined queries that limit the amount of data returned in the response from the tool.
  3. If possible, increase the context window size of the model. We recommend at least 32k for these MCP tools.

Chapter 16. Reference

16.1. Reference

TODO: Replace this placeholder with an overview of Reference.

16.2. Dynamic plugin parameter reference for configuration paths

16.2.1. Dynamic plugin parameter reference for configuration paths

TODO: Replace this placeholder with an overview of Dynamic plugin parameter reference for configuration paths.

16.3. Permission policies and conditional rules reference for RBAC configurations

16.3.1. Permission policies and conditional rules reference for RBAC configurations

TODO: Replace this placeholder with an overview of Permission policies and conditional rules reference for RBAC configurations.

16.3.2. Permission policies

16.3.2.1. Permission policies

Reference information about permission policy types and available permissions for catalog, scaffolder, RBAC, Kubernetes, Extensions, and plugin resources.

Developer Hub supports permission policies for controlling access to resources and functionalities. The following reference modules describe the available permission types and permissions for each plugin category.

16.3.2.2. Permission policy types

Reference information about resource type and basic permission types in Developer Hub.

Permission policies in Red Hat Developer Hub are a set of rules to govern access to resources or functionalities. These policies state the authorization level that is granted to users based on their roles. The permission policies are implemented to keep security and confidentiality within a given environment.

You can define the following types of permissions in Developer Hub:

  • resource type
  • basic

The distinction between the two permission types depends on whether a permission includes a defined resource type.

You can define the resource type permission by using either the associated resource type or the permission name as shown in the following example:

p, role:default/myrole, catalog.entity.read, read, allow
g, user:default/myuser, role:default/myrole

p, role:default/another-role, catalog-entity, read, allow
g, user:default/another-user, role:default/another-role

You can define the basic permission in Developer Hub using the permission name as shown in the following example:

p, role:default/myrole, catalog.entity.create, create, allow
g, user:default/myuser, role:default/myrole

16.3.2.3. Catalog permissions

Reference information about available catalog permissions for reading, creating, updating, and deleting catalog entities and locations.

NameResource typePolicyDescription

catalog.entity.read

catalog-entity

read

Enables a user or role to read from the catalog

catalog.entity.create

 

create

Enables a user or role to create catalog entities, including registering an existing component in the catalog

catalog.entity.refresh

catalog-entity

update

Enables a user or role to refresh a single or multiple entities from the catalog

catalog.entity.delete

catalog-entity

delete

Enables a user or role to delete a single or multiple entities from the catalog

catalog.location.read

 

read

Enables a user or role to read a single or multiple locations from the catalog

catalog.location.create

 

create

Enables a user or role to create locations within the catalog

catalog.location.delete

 

delete

Enables a user or role to delete locations from the catalog

16.3.2.4. Bulk import permission

Reference information about the bulk import permission for accessing bulk import endpoints.

NameResource typePolicyDescription

bulk.import

bulk-import

use

Enables the user to access the bulk import endpoints, such as listing all repositories and organizations accessible by the signed-in user (using SCM OAuth) and managing the import requests. Repositories already present in the software catalog are automatically hidden from this list.

Important

bulk.import permissions will fail to list repositories if GitHub or GitLab OAuth providers are not explicitly configured for the instance.

16.3.2.5. Scaffolder permissions

Reference information about scaffolder permissions for executing actions, reading templates, and managing scaffolder tasks.

NameResource typePolicyDescription

scaffolder.action.execute

scaffolder-action

use

Enables the execution of an action from a template

scaffolder.template.parameter.read

scaffolder-template

read

Enables a user or role to read a single or multiple one parameters from a template

scaffolder.template.step.read

scaffolder-template

read

Enables a user or role to read a single or multiple steps from a template

scaffolder.task.create

 

create

Enables a user or role to trigger software templates which create new scaffolder tasks

scaffolder.task.cancel

 

use

Enables a user or role to cancel currently running scaffolder tasks

scaffolder.task.read

 

read

Enables a user or role to read all scaffolder tasks and their associated events and logs

scaffolder.template.management

 

use

Enables a user or role to access front-end template management features, including editing, previewing, and trying templates, forms, and custom fields.

16.3.2.6. RBAC permissions

Reference information about RBAC permissions for reading, creating, updating, and deleting permission policies and roles.

NameResource typePolicyDescription

policy.entity.read

policy-entity

read

Enables a user or role to read permission policies and roles

policy.entity.create

 

create

Enables a user or role to create a single or multiple permission policies and roles

policy.entity.update

policy-entity

update

Enables a user or role to update a single or multiple permission policies and roles

policy.entity.delete

policy-entity

delete

Enables a user or role to delete a single or multiple permission policies and roles

16.3.2.7. Kubernetes permissions

Reference information about Kubernetes permissions for reading cluster details and resources and accessing proxy endpoints.

NameResource typePolicyDescription

kubernetes.clusters.read

 

read

Enables a user to read Kubernetes cluster details under the /clusters path

kubernetes.resources.read

 

read

Enables a user to read information about Kubernetes resources located at /services/:serviceId and /resources

kubernetes.proxy

 

use

Enables a user or role to access the proxy endpoint

16.3.2.8. Topology permissions

Reference information about Topology plugin permissions for reading Kubernetes cluster details and accessing proxy endpoints.

Note

Topology plugin does not have its own defined permissions. Kubernetes permissions are used instead.

NameResource typePolicyDescription

kubernetes.clusters.read

 

read

Enables a user to read Kubernetes cluster details under the /clusters path

kubernetes.resources.read

 

read

Enables a user to read information about Kubernetes resources located at /services/:serviceId and /resources

kubernetes.proxy

 

use

Enables a user or role to access the proxy endpoint, allowing the user or role to read pod logs and events within RHDH

16.3.2.9. Tekton permissions

Reference information about Tekton plugin permissions for reading Kubernetes cluster details and accessing proxy endpoints.

Note

Tekton plugin does not have its own defined permissions. Kubernetes permissions are used instead.

NameResource typePolicyDescription

kubernetes.clusters.read

 

read

Enables a user to read Kubernetes cluster details under the /clusters path

kubernetes.resources.read

 

read

Enables a user to read information about Kubernetes resources located at /services/:serviceId and /resources

kubernetes.proxy

 

use

Enables a user or role to access the proxy endpoint, allowing the user or role to read pod logs and events within RHDH

16.3.2.10. ArgoCD permissions

Reference information about ArgoCD plugin permissions for reading ArgoCD resources.

NameResource typePolicyDescription

argocd.view.read

 

read

Enables a user to read from the ArgoCD plugin

16.3.2.11. Quay permissions

Reference information about Quay plugin permissions for reading Quay resources.

NameResource typePolicyDescription

quay.view.read

 

read

Enables a user to read from the Quay plugin

16.3.2.12. Extensions permissions

Reference information about available Extensions permissions for reading and writing plugin configurations.

NameResource typePolicyDescription

extensions.plugin.configuration.read

extensions-plugin

read

Enables a user or role to view plugin configurations in Extensions

extensions.plugin.configuration.write

extensions-plugin

create

Enables a user or role to install, update, enable, or disable plugins by using Extensions

16.3.3. Conditional policy aliases and schemas

16.3.3.1. Conditional policy aliases and schemas

Reference information about conditional policy rules, schemas, and examples for defining conditions with or without criteria.

You can access API endpoints for conditional policies in Red Hat Developer Hub. The RBAC backend API constructs a condition JSON object based on the condition schema. In Red Hat Developer Hub, you can define conditional policies with or without criteria.

16.3.3.2. Conditional policy API endpoints

Reference information about the conditional policy API endpoint for retrieving available conditional rules and schemas.

You can access API endpoints for conditional policies in Red Hat Developer Hub. For example, to retrieve the available conditional rules, which can help you define these policies, you can access the GET [api/plugins/condition-rules] endpoint.

The api/plugins/condition-rules returns the condition parameters schemas, for example:

[
   {
      "pluginId": "catalog",
      "rules": [
         {
            "name": "HAS_ANNOTATION",
            "description": "Allow entities with the specified annotation",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "annotation": {
                     "type": "string",
                     "description": "Name of the annotation to match on"
                  },
                  "value": {
                     "type": "string",
                     "description": "Value of the annotation to match on"
                  }
               },
               "required": [
                  "annotation"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "HAS_LABEL",
            "description": "Allow entities with the specified label",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "label": {
                     "type": "string",
                     "description": "Name of the label to match on"
                  }
               },
               "required": [
                  "label"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "HAS_METADATA",
            "description": "Allow entities with the specified metadata subfield",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "key": {
                     "type": "string",
                     "description": "Property within the entities metadata to match on"
                  },
                  "value": {
                     "type": "string",
                     "description": "Value of the given property to match on"
                  }
               },
               "required": [
                  "key"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "HAS_SPEC",
            "description": "Allow entities with the specified spec subfield",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "key": {
                     "type": "string",
                     "description": "Property within the entities spec to match on"
                  },
                  "value": {
                     "type": "string",
                     "description": "Value of the given property to match on"
                  }
               },
               "required": [
                  "key"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "IS_ENTITY_KIND",
            "description": "Allow entities matching a specified kind",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "kinds": {
                     "type": "array",
                     "items": {
                        "type": "string"
                     },
                     "description": "List of kinds to match at least one of"
                  }
               },
               "required": [
                  "kinds"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         },
         {
            "name": "IS_ENTITY_OWNER",
            "description": "Allow entities owned by a specified claim",
            "resourceType": "catalog-entity",
            "paramsSchema": {
               "type": "object",
               "properties": {
                  "claims": {
                     "type": "array",
                     "items": {
                        "type": "string"
                     },
                     "description": "List of claims to match at least one on within ownedBy"
                  }
               },
               "required": [
                  "claims"
               ],
               "additionalProperties": false,
               "$schema": "http://json-schema.org/draft-07/schema#"
            }
         }
      ]
   }
   ... <another plugin condition parameter schemas>
]

The RBAC backend API constructs a condition JSON object based on the previous condition schema.

16.3.3.3. Conditional policy without criteria

Reference information about defining conditional policies without criteria to control access based on a single rule.

Consider a condition without criteria displaying catalogs only if user is a member of the owner group. To add this condition, you can use the catalog plugin schema IS_ENTITY_OWNER as follows:

{
  "rule": "IS_ENTITY_OWNER",
  "resourceType": "catalog-entity",
  "params": {
    "claims": ["group:default/team-a"]
  }
}

In the previous example, the only conditional parameter used is claims, which contains a list of user or group entity references.

You can apply the previous example condition to the RBAC REST API by adding additional parameters as follows:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/test",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["read"],
  "conditions": {
    "rule": "IS_ENTITY_OWNER",
    "resourceType": "catalog-entity",
    "params": {
      "claims": ["group:default/team-a"]
    }
  }
}

16.3.3.4. Conditional policy with criteria

Reference information about defining conditional policies with criteria to control access based on multiple rules combined with logical operators.

Consider a condition with criteria, which displays catalogs only if user is a member of owner group OR displays list of all catalog user groups.

To add the criteria, you can add another rule as IS_ENTITY_KIND in the condition as follows:

{
  "anyOf": [
    {
      "rule": "IS_ENTITY_OWNER",
      "resourceType": "catalog-entity",
      "params": {
        "claims": ["group:default/team-a"]
      }
    },
    {
      "rule": "IS_ENTITY_KIND",
      "resourceType": "catalog-entity",
      "params": {
        "kinds": ["Group"]
      }
    }
  ]
}
Note

Running conditions in parallel during creation is not supported. Therefore, consider defining nested conditional policies based on the available criteria.

+ Example of nested conditions:

+

{
  "anyOf": [
    {
      "rule": "IS_ENTITY_OWNER",
      "resourceType": "catalog-entity",
      "params": {
        "claims": ["group:default/team-a"]
      }
    },
    {
      "rule": "IS_ENTITY_KIND",
      "resourceType": "catalog-entity",
      "params": {
        "kinds": ["Group"]
      }
    }
  ],
  "not": {
    "rule": "IS_ENTITY_KIND",
    "resourceType": "catalog-entity",
    "params": { "kinds": ["Api"] }
  }
}

You can apply the previous example condition to the RBAC REST API by adding additional parameters as follows:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/test",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["read"],
  "conditions": {
    "anyOf": [
      {
        "rule": "IS_ENTITY_OWNER",
        "resourceType": "catalog-entity",
        "params": {
          "claims": ["group:default/team-a"]
        }
      },
      {
        "rule": "IS_ENTITY_KIND",
        "resourceType": "catalog-entity",
        "params": {
          "kinds": ["Group"]
        }
      }
    ]
  }
}

16.3.3.5. Conditional policy plugin examples

Reference information about conditional policy examples for Keycloak, Quay, and Extensions plugins demonstrating access control patterns.

The following examples can be used with Developer Hub plugins. These examples can help you determine how to define conditional policies:

Conditional policy defined for Keycloak plugin:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/developer",
  "pluginId": "catalog",
  "resourceType": "catalog-entity",
  "permissionMapping": ["update", "delete"],
  "conditions": {
    "not": {
      "rule": "HAS_ANNOTATION",
      "resourceType": "catalog-entity",
      "params": { "annotation": "keycloak.org/realm", "value": "<YOUR_REALM>" }
    }
  }
}

The previous example of Keycloak plugin prevents users in the role:default/developer from updating or deleting users that are ingested into the catalog from the Keycloak plugin.

Note

In the previous example, the annotation keycloak.org/realm requires the value of <YOUR_REALM>.

Conditional policy defined for Quay plugin:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/developer",
  "pluginId": "scaffolder",
  "resourceType": "scaffolder-action",
  "permissionMapping": ["use"],
  "conditions": {
    "not": {
      "rule": "HAS_ACTION_ID",
      "resourceType": "scaffolder-action",
      "params": { "actionId": "quay:create-repository" }
    }
  }
}

The previous example of Quay plugin prevents the role role:default/developer from using the Quay scaffolder action. Note that permissionMapping contains use, signifying that scaffolder-action resource type permission does not have a permission policy.

Conditional policy defined for Extensions plugin:

{
  "result": "CONDITIONAL",
  "roleEntityRef": "role:default/extensions-admin",
  "pluginId": "extensions",
  "resourceType": "extensions-plugin",
  "permissionMapping": ["create"],
  "conditions": {
    "rule": "HAS_NAME",
    "resourceType": "extensions-plugin",
    "params": { "pluginNames": ["<your_plugin_name>"] }
  }
}

The previous example of Extensions plugin restricts users in the role:default/extensions-admin to only installing or updating the specified plugin.

16.4. Trace attributes and OpenTelemetry configurations

16.4.1. Trace attributes and OpenTelemetry configurations

TODO: Replace this placeholder with an overview of Trace attributes and OpenTelemetry configurations.

16.5. Helm chart configuration parameters to define advanced deployment

16.5.1. Helm chart configuration parameters to define advanced deployment

TODO: Replace this placeholder with an overview of Helm chart configuration parameters to define advanced deployment.

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.