Red Hat Developer Hub documentation
Complete documentation for Red Hat Developer Hub.
Abstract
- Preface
- 1. Discover
- 1.1. Discover
- 1.2. Evaluate RHDH capabilities
- 1.2.1. Evaluate RHDH capabilities
- 1.2.2. Why Internal developer platforms?
- 1.2.3. System architecture for deployment strategy planning
- 1.2.4. Developer Lightspeed AI virtual assistant capabilities
- 1.2.5. AI model evaluation data to select the right AI model
- 1.2.6. Build a private knowledge base with Developer Lightspeed for RHDH Notebooks
- 1.2.7. Platform integrations for toolchain connectivity
- 1.2.8. Supported platforms
- 1.2.9. Red Hat Developer Hub support
- 2. Get started
- 2.1. Get Started
- 2.2. Set up the first RHDH instance
- 2.2.1. Set up the first RHDH instance
- 2.2.2. Checklist to run your first Red Hat Developer Hub (RHDH) instance in production
- 2.2.3. Install the Operator
- 2.2.4. Prepare your external services
- 2.2.5. Provision your custom configuration
- 2.2.6. Enable initial authentication to verify user access
- 2.2.7. Use the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration
- 2.2.8. Configure the default theme mode
- 2.2.9. RBAC policy files
- 2.3. Navigate RHDH on your first day
- 2.3.1. Navigate RHDH on your first day
- 2.3.2. Red Hat Developer Hub capabilities and architecture
- 2.3.3. Log in to Red Hat Developer Hub
- 2.3.4. Find software components to discover assets
- 2.3.5. Import and use an existing software template for faster development
- 2.3.6. Search for relevant content
- 2.3.7. Access and navigate documentation
- 2.3.8. Review API contracts to verify service endpoints and schemas
- 2.3.9. Test API endpoints interactively
- 2.3.10. Select supported API specifications
- 2.3.11. Locate resources instantly
- 2.3.12. Filter and refine search results
- 2.3.13. Get AI-assisted help for your development tasks
- 2.3.14. Integrate and customize your daily tools using Extensions
- 2.3.15. Customize your interface settings and profile details
- 2.3.16. Star key components in the Software Catalog
- 3. Plan
- 4. Install
- 4.1. Install
- 4.2. 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
- 4.3.2. Install on Amazon Elastic Kubernetes Service (EKS) using the Operator
- 4.3.3. Deploy on Amazon EKS using the Helm chart
- 4.3.4. Install on Google Kubernetes Engine (GKE) using the Operator
- 4.3.5. Deploy on GKE using the Helm chart
- 4.3.6. Install on Microsoft Azure Kubernetes Service (AKS) using the Operator
- 4.3.7. Deploy on AKS using the Helm chart
- 4.3.8. Install on OpenShift Dedicated using the Operator
- 4.3.9. Deploy on OpenShift Dedicated using the Helm chart
- 4.4. Install in an air-gapped environment
- 4.4.1. Install in an air-gapped environment
- 4.4.2. Isolated network deployments for air-gapped environments
- 4.4.3. Install in an air-gapped environment using the Operator
- 4.4.4. Deploy on OpenShift using Helm in an air-gapped environment
- 4.4.5. Deploy on Kubernetes platforms using Helm in air-gapped environments
- 5. Upgrade
- 6. Migrate
- 6.1. Migrate
- 6.2. Migrate from a local database to an external PostgreSQL server
- 6.3. Migrate to the front-end system to use blueprint-based dynamic routing
- 6.3.1. Migrate to the front-end system to use blueprint-based dynamic routing
- 6.3.2. Customize platform appearance to reflect your brand identity
- 6.3.3. Update Global Header mount points to integrate securely with the new Blueprint architecture
- 6.3.4. Add navigation shortcuts to reduce clicks to frequently used resources
- 6.3.5. Add plugin-specific buttons to the toolbar for quick actions
- 6.3.6. Add plugin links to drop-down menus to organize navigation access
- 6.3.7. Reorganize or remove header items to align with your team priorities
- 6.3.8. Migrate the Homepage to function as a dynamic plugin loaded through blueprints
- 6.3.9. Enable guided tutorials to learn platform features
- 6.3.10. Preserve custom integrations when migrating to the front-end system
- 7. Administer
- 8. Develop
- 8.1. 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
- 8.2.2. Manage your software components
- 8.2.3. Define software components in the catalog
- 8.2.4. Define APIs in the catalog
- 8.2.5. Define resources in the catalog
- 8.2.6. Define locations in the catalog
- 8.2.7. Catalog entity descriptor reference
- 8.3. Project standardization with software templates
- 8.3.1. Project standardization with software templates
- 8.3.2. Create new Software Templates
- 8.3.3. Use sample templates
- 8.3.4. Publish template definitions to the catalog
- 8.3.5. Extend templates using conditional logic and external fetch capabilities
- 8.3.6. Version Software Templates to track template updates and dependencies
- 8.3.7. Track component provenance to map dependencies back to source templates
- 8.3.8. Automate template lifecycle management
- 8.3.9. Standardized project generation with software templates
- 8.4. Automate repository onboarding to the catalog
- 8.5. Orchestrate infrastructure tasks using workflows
- 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
- 8.6.2. About TechDocs
- 8.6.3. Import documentation into TechDocs from a remote repository
- 8.6.4. Search for relevant content
- 8.6.5. Access and navigate documentation
- 8.6.6. Make changes to project documentation in TechDocs
- 8.6.7. Add video content to enhance TechDocs
- 8.6.8. Configure TechDocs storage and CI/CD pipelines
- 8.6.9. Configuring CI/CD to generate and publish TechDocs sites
- 8.6.10. Install TechDocs add-ons
- 8.6.11. TechDocs add-ons
- 8.6.12. Create a TechDocs add-on
- 9. Configure
- 9.1. Configure
- 9.2. Configure core parameters to meet infrastructure requirements
- 9.2.1. Configure core parameters to meet infrastructure requirements
- 9.2.2. Default configurations to establish a deployment foundation
- 9.2.3. Provision custom config maps and secrets to define platform behavior
- 9.2.4. Customize your Red Hat Developer Hub base URL
- 9.2.5. Configure backend secrets to secure service-to-service communication
- 9.2.6. Customize Red Hat Developer Hub backend secret
- 9.2.7. Inject extra files and variables to secure external service connections
- 9.2.8. Configure mount paths to safely attach default secrets and storage
- 9.2.9. Mount secrets to specific containers to isolate sensitive data
- 9.2.10. Patch deployment resources to customize Operator pod specifications
- 9.2.11. Configure TLS connections to encrypt external platform traffic
- 9.2.12. Configure the base URL to route frontend and backend traffic
- 9.2.13. Configure HTTP server timeouts
- 9.2.14. Configure the dynamic plugins cache
- 9.2.15. Optimize Operator memory usage for large clusters
- 9.2.16. Fix 404 error after cached dynamic plugins configuration change
- 9.2.17. Configure corporate proxy settings to enable external network access
- 9.3. Customize the user interface to reflect organizational branding
- 9.3.1. Customize the user interface to reflect organizational branding
- 9.3.2. Customize your Red Hat Developer Hub title
- 9.3.3. Customize Learning Paths to integrate tailored e-learning content
- 9.3.4. Configure the global header for consistent top-level navigation
- 9.3.5. Customize the Quick Start to guide user onboarding
- 9.3.6. Customize the Tech Radar page to visualize technology adoption
- 9.3.7. Customize themes and branding to align with corporate standards
- 9.3.8. Customize sidebar navigation and tabs to organize essential tools
- 9.3.9. Customize the Home page layout to optimize developer workflows
- 9.3.10. Configure Quick access cards to surface frequently used links
- 9.3.11. Customize the RHDH Metadata card on the Settings page
- 9.4. Configure language localization to improve accessibility for global users
- 10. Secure
- 10.1. Secure
- 10.2. Configure authentication providers to verify user identities
- 10.2.1. Configure authentication providers to verify user identities
- 10.2.2. Authentication methods and identity provider selection
- 10.2.3. Configure guest access to securely test non-production environments
- 10.2.4. Share credentials with your identity provider to secure communications
- 10.2.5. Import users and groups to synchronize enterprise directory data
- 10.2.6. Enable authentication to verify identities against enterprise directories
- 10.2.7. Connect your platform to external identity providers and APIs
- 10.2.8. Configure session expiration and auto-logout policies
- 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
- 10.3.2. Role-based access control in Developer Hub
- 10.3.3. Enable the RBAC plugin
- 10.3.4. Determine your policy source
- 10.3.5. Design policy rules
- 10.3.6. Manage roles using the Web UI
- 10.3.7. Manage policies using the REST API
- 10.3.8. Define policies in external files to provision permissions during cluster deployment
- 10.3.9. Configure guest access
- 10.3.10. Permission policy parameters and definitions
- 10.3.11. Define conditional policies
- 10.3.12. Download user statistics
- 10.3.13. Manage Orchestrator plugin permissions using RBAC policies
- 10.3.14. Orchestrator plugin permissions
- 10.3.15. Delegate RBAC management to decentralize administration
- 11. Observe
- 11.1. Observe
- 11.2. Monitor system logs and application metrics to ensure platform availability
- 11.3. 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.5. Centralize workflow observability
- 11.6. Collect diagnostic data to troubleshoot platform issues
- 11.6.1. Diagnostic data collection overview
- 11.6.2. Run must-gather on OpenShift to collect diagnostic data
- 11.6.3. Collect heap dumps to diagnose memory issues
- 11.6.4. Diagnostic data types and collection scope
- 11.6.5. Configuration options for diagnostic collection
- 11.6.6. Diagnostic data output structure and organization
- 12. Integrate
- 12.1. Integrate
- 12.2. Enable AI assistance for developers
- 12.2.1. Enable AI assistance for developers
- 12.2.2. Developer Lightspeed for RHDH architecture
- 12.2.3. Build a private knowledge base with Lightspeed Notebooks
- 12.2.4. Large language model (LLM) requirements
- 12.2.5. OpenAI model integration for your deployment
- 12.2.6. Ollama model integration requirements
- 12.2.7. vLLM model integration for high-throughput inference
- 12.2.8. Vertex AI integration for Gemini models
- 12.2.9. Manage user data security
- 12.2.10. User feedback collection
- 12.2.11. Bring Your Own Model integration
- 12.2.12. Your compliance and data-sharing responsibility
- 12.2.13. Configure Model Context Protocol tools to enhance AI interactions with portal data
- 12.2.14. 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
- 12.3.2. Track deployment history and rollouts with Argo CD
- 12.3.3. Track build artifacts using the JFrog plugin
- 12.3.4. Manage identity data by integrating Keycloak
- 12.3.5. View build artifacts using Nexus Repository Manager
- 12.3.6. Monitor continuous integration pipelines with Tekton
- 12.3.7. Use the Tekton plugin
- 12.3.8. Visualize Kubernetes workloads and pod health with Topology
- 12.3.9. Configure the GitHub Events Module plugin
- 12.4. Extend software templates with Kubernetes custom actions
- 12.4.1. Kubernetes custom actions in Red Hat Developer Hub
- 12.4.2. Enable Kubernetes custom actions plugin in Red Hat Developer Hub
- 12.4.3. Use Kubernetes custom actions plugin in Red Hat Developer Hub
- 12.4.4. Create a template using Kubernetes custom actions in Red Hat Developer Hub
- 12.4.5. Supported Kubernetes custom actions in Red Hat Developer Hub
- 12.5. Integrate ServiceNow for incident management and scaffolder actions
- 12.5.1. ServiceNow custom actions in Red Hat Developer Hub
- 12.5.2. ServiceNow entity linking methods
- 12.5.3. Enable ServiceNow custom actions plugin in Red Hat Developer Hub
- 12.5.4. Configure the ServiceNow plugin in the ConfigMap
- 12.5.5. Link ServiceNow tickets to catalog entities
- 12.5.6. Use ServiceNow scaffolder actions in software templates
- 12.5.7. ServiceNow configuration parameters
- 12.5.8. Supported ServiceNow custom actions in Red Hat Developer Hub
- 12.6. Enable Ansible plugins for automation workflows
- 13. Optimize
- 14. Extend
- 14.1. Extend
- 14.2. Manage the plugin ecosystem to add functionality without downtime
- 14.2.1. Manage the plugin ecosystem to add functionality without downtime
- 14.2.2. Install dynamic plugins
- 14.2.3. Install plugins using custom certificates to secure private registry connections
- 14.2.4. Enable pre-loaded container plugins
- 14.2.5. Browse and manage available plugins using the Extensions UI
- 14.2.6. Configure core front-end wiring for navigation and UI components
- 14.2.7. Configure route bindings and mount points for component integration
- 14.2.8. Configure specialized front-end extensions for APIs and features
- 14.2.9. 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
- 14.3.2. Prepare your development environment to write custom plugins
- 14.3.3. Develop and test new plugin components locally
- 14.3.4. Convert standard plugins into dynamic plugins using the Plugin Factory
- 14.3.5. Package and deploy dynamic plugins as OCI images
- 14.3.6. Verify plugins locally
- 14.3.7. Export custom plugins in Red Hat Developer Hub
- 14.3.8. Override Core Backend Service Configuration
- 14.4. Manage containerized plugins securely by migrating to OCI artifacts
- 14.5. Enable and configure the Orchestrator extension
- 14.5.1. Enable and configure the Orchestrator extension
- 14.5.2. Understand Orchestrator architecture
- 14.5.3. Getting started with Orchestrator
- 14.5.4. Orchestrator plugin dependencies for Operator installation
- 14.5.5. Configure Orchestrator plugins
- 14.5.6. Enable the Orchestrator plugins using the Operator
- 14.5.7. Install components using the
RHDHhelper script - 14.5.8. Install Orchestrator components manually on OpenShift Container Platform
- 14.5.9. Install Orchestrator software templates
- 14.5.10. Configure Orchestrator to connect to existing PostgreSQL infrastructure
- 14.5.11. Configure Orchestrator to connect to existing PostgreSQL infrastructure using Helm
- 14.5.12. Compatibility guide for Orchestrator
- 14.5.13. Workflow review pages for your approval requirements
- 14.5.14. Build custom review pages for workflows
- 14.5.15. Custom review page API reference
- 15. Troubleshoot
- 15.1. Troubleshoot
- 15.2. Troubleshoot user access and authentication issues to restore user entry
- 15.3. Troubleshoot plugin and workflow deployment errors to resume automation
- 15.3.1. Troubleshoot plugin and workflow deployment errors to resume automation
- 15.3.2. Troubleshoot pod startup failures
- 15.3.3. Troubleshoot a pod startup failure after enabling a plugin
- 15.3.4. Restore workflow visibility by removing duplicate entries
- 15.3.5. Troubleshooting workflow deployments
- 15.3.6. Diagnose serverless workflow issues
- 15.4. Troubleshoot AI and tool integrations to restore intelligent features
- 16. Reference
- 16.1. Reference
- 16.2. Dynamic plugin parameter reference for configuration paths
- 16.2.1. Dynamic plugin parameter reference for configuration paths
- 16.2.2. Preinstalled dynamic plugins reference
- 16.2.3. Red Hat supported plugins and configuration paths reference
- 16.2.4. Technology Preview plugins
- 16.2.5. Deprecated plugins
- 16.2.6. Other installable plugins
- 16.2.7. Red Hat community supported plugins
- 16.3. Permission policies and conditional rules reference for RBAC configurations
- 16.4. Trace attributes and OpenTelemetry configurations
- 16.5. Helm chart configuration parameters to define advanced deployment
Preface
The complete Red Hat Developer Hub documentation, organized by category.
Chapter 1. Discover
1.1. Discover
Evaluate Red Hat Developer Hub capabilities, understand the system architecture, explore integrations, and assess the value proposition before deployment.
1.2. Evaluate RHDH capabilities
1.2.1. Evaluate RHDH capabilities
Assess internal developer platform benefits, review system architecture, explore AI assistant capabilities, understand platform integrations, and verify supported platforms before adoption.
1.2.2. Why Internal developer platforms?
1.2.2.1. Why Internal developer platforms?
Internal developer platforms (IDPs) provide a unified interface that enables developer self-service for provisioning environments, deploying code, and accessing APIs. By centralizing these tools, IDPs reduce complexity across development workflows.
- Why IDPs matter
- IDPs address the challenges of modern software delivery by enabling self-service, enforcing standards, and improving the developer experience.
- For organizations
- Scalability: RHDH enables consistent developer onboarding and application delivery across growing teams and environments.
- Security: Role-based access control (RBAC) and integration with enterprise systems ensure access is managed securely and in line with compliance requirements.
- Operational efficiency: By removing manual handoffs and centralizing key development workflows, RHDH improves time to value and increases return on engineering investment.
- For platform engineers
- Curated platforms: Platform teams can design reusable templates and integrations aligned with organizational policies and developer needs.
- Central configuration: Infrastructure and policies are defined as code and centrally managed, reducing drift and maintenance costs.
- Governance at scale: Policies and best practices are embedded into developer workflows using automation and templates, without adding friction to the process.
- For developers
- Faster onboarding: Developers can use learning paths, software templates, and software catalog to deploy compliant services within minutes, without depending on other teams for setup.
- Reduced cognitive load: Developers can find tools, documentation, and deployment environments in one place, eliminating the need to switch between systems or manage disconnected resources.
- Self-service workflows: Developers can create applications or environments on-demand, without raising tickets or waiting for approvals.
- Built-in standards: Developers can use preconfigured templates that enforce secure, compliant workflows without requiring manual setup.
- Cross-team visibility: Developers can discover shared service catalogs and documentation to improve reuse and reduce duplication.
- Higher productivity: Developers can dedicate more time to building features and less time to configuring infrastructure or resolving toolchain inconsistencies.
1.2.2.1.1. Key features
- Centralized dashboard
- Access development tools, CI/CD pipelines, APIs, monitoring tools, and documentation from a single interface. Integrate with systems such as Git, Red Hat OpenShift Container Platform, Kubernetes, and Jira.
- Learning paths
- Guide developers through structured tutorials and onboarding steps. Help teams build skills with internal and Red Hat training resources in one place.
- Plugins and integrations
- Extend RHDH with verified plugins that add new functionality without downtime. Dynamically integrate with supported tools such as Tekton for pipelines, GitOps for deployment automation, Nexus Repository for artifact storage, and JFrog Artifactory. RHDH also supports connecting to Red Hat OpenShift Container Platform, CI/CD systems, and security scanners through Red Hat-curated extensions.
- Role-based access control (RBAC)
- Manage user access with robust security permissions tailored to organizational needs.
- Software catalog
- Search, view, and manage services, APIs, and libraries from a central inventory. Track ownership, metadata, and component health in one place.
- Software templates
- Accelerate project setup by using preconfigured templates for CI/CD, runtime, and security. Standardize implementation while enabling developer autonomy.
- Tech docs
- Create, store, and view technical documentation alongside code. Make content searchable, consistently formatted, and accessible through the portal.
- Scalability
- Support growing teams and applications while maintaining access to the same tools and services.
1.2.2.2. Understanding internal developer platforms
Internal developer platforms (IDPs) provide a unified interface that enables developer self-service for provisioning environments, deploying code, and accessing APIs. By centralizing these tools, IDPs reduce complexity across development workflows.
- Why IDPs matter
- IDPs address the challenges of modern software delivery by enabling self-service, enforcing standards, and improving the developer experience.
- For organizations
- Scalability: RHDH enables consistent developer onboarding and application delivery across growing teams and environments.
- Security: Role-based access control (RBAC) and integration with enterprise systems ensure access is managed securely and in line with compliance requirements.
- Operational efficiency: By removing manual handoffs and centralizing key development workflows, RHDH improves time to value and increases return on engineering investment.
- For platform engineers
- Curated platforms: Platform teams can design reusable templates and integrations aligned with organizational policies and developer needs.
- Central configuration: Infrastructure and policies are defined as code and centrally managed, reducing drift and maintenance costs.
- Governance at scale: Policies and best practices are embedded into developer workflows using automation and templates, without adding friction to the process.
- For developers
- Faster onboarding: Developers can use learning paths, software templates, and software catalog to deploy compliant services within minutes, without depending on other teams for setup.
- Reduced cognitive load: Developers can find tools, documentation, and deployment environments in one place, eliminating the need to switch between systems or manage disconnected resources.
- Self-service workflows: Developers can create applications or environments on-demand, without raising tickets or waiting for approvals.
- Built-in standards: Developers can use preconfigured templates that enforce secure, compliant workflows without requiring manual setup.
- Cross-team visibility: Developers can discover shared service catalogs and documentation to improve reuse and reduce duplication.
- Higher productivity: Developers can dedicate more time to building features and less time to configuring infrastructure or resolving toolchain inconsistencies.
1.2.2.2.1. Key features
- Centralized dashboard
- Access development tools, CI/CD pipelines, APIs, monitoring tools, and documentation from a single interface. Integrate with systems such as Git, Red Hat OpenShift Container Platform, Kubernetes, and Jira.
- Learning paths
- Guide developers through structured tutorials and onboarding steps. Help teams build skills with internal and Red Hat training resources in one place.
- Plugins and integrations
- Extend RHDH with verified plugins that add new functionality without downtime. Dynamically integrate with supported tools such as Tekton for pipelines, GitOps for deployment automation, Nexus Repository for artifact storage, and JFrog Artifactory. RHDH also supports connecting to Red Hat OpenShift Container Platform, CI/CD systems, and security scanners through Red Hat-curated extensions.
- Role-based access control (RBAC)
- Manage user access with robust security permissions tailored to organizational needs.
- Software catalog
- Search, view, and manage services, APIs, and libraries from a central inventory. Track ownership, metadata, and component health in one place.
- Software templates
- Accelerate project setup by using preconfigured templates for CI/CD, runtime, and security. Standardize implementation while enabling developer autonomy.
- Tech docs
- Create, store, and view technical documentation alongside code. Make content searchable, consistently formatted, and accessible through the portal.
- Scalability
- Support growing teams and applications while maintaining access to the same tools and services.
1.2.3. System architecture for deployment strategy planning
1.2.3.1. System architecture for deployment strategy planning
Understanding Red Hat Developer Hub client-server architecture helps you plan deployments for horizontal scaling, high availability, and efficient data synchronization across the Software Catalog.
By understanding the RHDH architecture, you can perform the following planning tasks:
- Plan scalable deployments
- Deploy multiple backend instances behind a load balancer to manage increased load.
- Ensure high availability
- Configure database replication and cache clustering to eliminate single points of failure.
- Optimize resource allocation
- Assign infrastructure resources based on which components require persistent storage or high-performance memory.
The following diagram shows the RHDH internal architecture (frontend and backend) and its external dependencies, such as authentication providers, load balancers, and databases:

The RHDH architecture includes three primary layers. While the data layer (PostgreSQL and optional Redis cache) stores the indexed Software Catalog, the source of truth remains in external systems, such as Git repositories, CI/CD platforms, and other integrations. Catalog providers continuously scan these external systems and synchronize data to the database for fast querying.
1.2.3.1.1. Frontend (Client)
The frontend is a browser-based single-page application (SPA). Use the frontend interface to browse the Software Catalog, interact with plugins, and connect to external integrations. The frontend communicates with the backend exclusively using REST API calls.
1.2.3.1.2. Backend (Service Layer)
The backend provides REST API endpoints for the frontend. It manages the Software Catalog (an inventory of your organization’s software components, APIs, and resources) and handles authentication.
The stateless design allows you to scale the backend horizontally by running multiple instances behind a load balancer. The backend externalizes all persistent state to a PostgreSQL database, including:
- Catalog entities
- Task history
- Session data (managed through a database-backed session store)
1.2.3.1.3. External data dependencies
RHDH requires PostgreSQL for persistence. For production environments, use a logical cache to improve performance.
- PostgreSQL database
- Stores indexed Software Catalog entities (synchronized from external systems such as Git repositories and CI/CD platforms), profiles, authentication data, and backend state. You must configure PostgreSQL with high availability (HA) for production deployments.
- Redis Cache (Optional)
- Configure Redis as a shared logical cache across backend instances to improve performance for frequently accessed data, such as rendered TechDocs and catalog entities.
The default in-memory cache is suitable only for single-instance deployments. You must use Redis for production deployments with multiple backend instances to ensure cache consistency.
1.2.3.2. System architecture for deployment planning
Understanding Red Hat Developer Hub client-server architecture helps you plan deployments for horizontal scaling, high availability, and efficient data synchronization across the Software Catalog.
By understanding the RHDH architecture, you can perform the following planning tasks:
- Plan scalable deployments
- Deploy multiple backend instances behind a load balancer to manage increased load.
- Ensure high availability
- Configure database replication and cache clustering to eliminate single points of failure.
- Optimize resource allocation
- Assign infrastructure resources based on which components require persistent storage or high-performance memory.
The following diagram shows the RHDH internal architecture (frontend and backend) and its external dependencies, such as authentication providers, load balancers, and databases:

The RHDH architecture includes three primary layers. While the data layer (PostgreSQL and optional Redis cache) stores the indexed Software Catalog, the source of truth remains in external systems, such as Git repositories, CI/CD platforms, and other integrations. Catalog providers continuously scan these external systems and synchronize data to the database for fast querying.
1.2.3.2.1. Frontend (Client)
The frontend is a browser-based single-page application (SPA). Use the frontend interface to browse the Software Catalog, interact with plugins, and connect to external integrations. The frontend communicates with the backend exclusively using REST API calls.
1.2.3.2.2. Backend (Service Layer)
The backend provides REST API endpoints for the frontend. It manages the Software Catalog (an inventory of your organization’s software components, APIs, and resources) and handles authentication.
The stateless design allows you to scale the backend horizontally by running multiple instances behind a load balancer. The backend externalizes all persistent state to a PostgreSQL database, including:
- Catalog entities
- Task history
- Session data (managed through a database-backed session store)
1.2.3.2.3. External data dependencies
RHDH requires PostgreSQL for persistence. For production environments, use a logical cache to improve performance.
- PostgreSQL database
- Stores indexed Software Catalog entities (synchronized from external systems such as Git repositories and CI/CD platforms), profiles, authentication data, and backend state. You must configure PostgreSQL with high availability (HA) for production deployments.
- Redis Cache (Optional)
- Configure Redis as a shared logical cache across backend instances to improve performance for frequently accessed data, such as rendered TechDocs and catalog entities.
The default in-memory cache is suitable only for single-instance deployments. You must use Redis for production deployments with multiple backend instances to ensure cache consistency.
1.2.3.3. Deploy multiple stateless instances
Achieving high availability in Red Hat Developer Hub requires implementing redundancy and failover for both the backend service and its data dependencies. This is accomplished through horizontal scaling, database replication, and shared caching to ensure continuous operation during component failures.
1.2.3.3.1. Deploy multiple stateless instances
RHDH backend uses a stateless design to support horizontal scaling. PostgreSQL stores persistent data and the database manages sessions, allowing multiple backend instances to serve any request simultaneously. To improve performance, you can configure an optional logical cache by using Redis.
To maintain backend availability, observe the following architectural requirements:
- Deploy multiple backend instances
- Run at least two backend instances for basic HA.
- Configure a load balancer
- Use platform-provided load balancing, such as OpenShift Routes, Kubernetes Ingress, or cloud provider load balancers.
- Enable health checks
- Configure the load balancer to probe backend health and remove failed instances from rotation.
- Disable session affinity (sticky sessions)
- Database-backed sessions allow any instance to serve any request.
1.2.3.3.2. Implement database HA
RHDH operations rely on PostgreSQL for persistence. A database outage renders the deployment non-functional until the database is restored. For production deployments, you must configure PostgreSQL with high availability (primary-replica replication) to minimize downtime.
If you use catalog providers exclusively, the database acts as an indexed cache. You do not require disaster recovery backups because you can repopulate catalog data from external sources of truth, such as Git repositories, CI/CD platforms, and monitoring tools.
1.2.3.3.3. Implement cache HA
Configuring Redis as a shared logical cache improves production performance by sharing cached data across multiple backend instances. A shared cache makes sure that all instances access the same processed data, such as rendered TechDocs.
If the logical cache fails, the platform remains functional, but you might experience the following symptoms:
- Slower response times due to cache misses.
- Increased database load because the backend must fetch data from PostgreSQL.
- No impact on authentication or core functionality.
For maximum performance stability in production, configure Redis with high availability using Redis Sentinel for small deployments or Redis Cluster for larger deployments.
1.2.4. Developer Lightspeed AI virtual assistant capabilities
1.2.4.1. Developer Lightspeed AI virtual assistant capabilities
Understand the Red Hat Developer Lightspeed for Red Hat Developer Hub AI assistant architecture and system design to plan backend deployment and integration with Red Hat Developer Hub.
1.2.4.2. Chat assistance with Developer Lightspeed for RHDH
Use Developer Lightspeed for RHDH to find product information, discover features, and resolve technical questions using natural language prompts directly within the RHDH console.
Developer Lightspeed for RHDH uses a button (provided by the Lightspeed plugin) instead of a sidebar navigation item. If your environment uses another button in the same position from another plugin, you must move the existing button or disable it to prevent interface elements from overlapping. In your dynamic plugin configuration file, make the following update:
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import
disabled: true
pluginConfig:
dynamicPlugins:
frontend:
red-hat-developer-hub.backstage-plugin-bulk-import:
mountPoints:
- mountPoint: global.floatingactionbutton/config
importName: BulkImportPage # Example
config:
slot: 'bottom-left'
icon: BulkImportIcon
label: 'Bulk import'
toolTip: 'Register multiple repositories in bulk'
to: /bulk-import
translationResources:
- importName: bulkImportTranslations
module: Alpha
ref: bulkImportTranslationRef
appIcons:
- name: bulkImportIcon
importName: BulkImportIcon
dynamicRoutes:
- path: /bulk-import
importName: BulkImportPage
menuItem:
icon: bulkImportIcon
text: Bulk import
textKey: menuItem.bulkImport
1.2.4.3. AI response monitoring and context management
Developer Lightspeed for RHDH provides features to track the AI reasoning process and keep the context of your development tasks.
- Thinking cards
- An expandable thinking card is displayed while the AI processes a query. A pulse animation indicates the reasoning phase. You can expand the card to view detailed reasoning or collapse it to minimize screen clutter.
- Tool call transparency
- An expandable card displays details for Model Context Protocol (MCP) tool calls, which you can use to monitor background processes.
- Context-aware citations
- Retrieval-Augmented Generation (RAG) citations appear only when the AI uses internal documentation. This makes sure that general knowledge responses remain concise.
- Context preservation during model changes
- When you select a different AI model, Developer Lightspeed for RHDH starts a new conversation. This keeps your earlier chats available in your history.
- Structural readability
- The interface formats headings and bullet points automatically to make sure responses are scannable.
1.2.4.4. AI reference and tool-calling capabilities through Lightspeed Core Service
Review the core components managed by the Lightspeed Core Service(LCORE) sidecar container to plan integrations with large language models (LLM) and tool runtime providers.
The LCORE container deploys as a sidecar to extend RHDH functionality. The container integrates and manages the following core architectural components:
- Large language model (LLM) inference providers
Model Context Protocol (MCP) or Retrieval Augmented Generation (RAG) tool runtime providers
ImportantVerify that your model supports tool calling before you enable MCP features. Using an incompatible model results in error messages.
- Safety providers
- Vector database settings
LCORE also manages critical operational configuration and key data, specifically:
- User feedback collection
- MCP server configuration
- Chat history
Developer Lightspeed for RHDH sends prompts and receives LLM responses through the LCORE sidecar.
1.2.4.5. Red Hat Developer Lightspeed for Red Hat Developer Hub architecture for your AI backend deployment
Review the Developer Lightspeed for RHDH component architecture to plan your system layout and coordinate connections with your artificial intelligence (AI) backend deployment.
The architecture relies on the Lightspeed Core Service (LCORE) container, which operates as the primary intermediary layer to manage Developer Lightspeed for RHDH functionality and console user interactions. By default, the interface appears as a button on all platforms that host RHDH.
Additional resources
1.2.4.6. Configure safety guards in Red Hat Developer Hub
To protect users from insecure or harmful AI model outputs, Red Hat Developer Hub (RHDH) uses Llama Guard as a default safety shield. You must configure these guards to align with your organization’s security policies.
Default safety guard configuration-
The system uses Llama Guard as the default safety shield. Override these settings in the
run.yamlfile.
The external_providers_dir parameter defaults to null and is no longer required in your configuration.
Overriding safety guards-
To implement custom security layers or different safety shields, you must define a new safety provider within a custom
run.yamlfile. Disabling safety guards-
To run RHDH without safety guards, you must use the
run-no-guard.yamlconfiguration file.
Running without safety guards increases the risk of invalid model output. Only use this configuration in secure development environments.
Applying the no-guard configuration- To run the system without a safety guard, perform these steps:
Procedure
Add the following YAML file as a config map to your namespace:
version: 2 image_name: redhat-ai-dev-llama-stack-no-guard apis: - agents - inference - safety - tool_runtime - vector_io - files container_image: external_providers_dir: providers: agents: - config: persistence: agent_state: namespace: agents backend: kv_default responses: table_name: responses backend: sql_default provider_id: meta-reference provider_type: inline::meta-reference inference: - provider_id: ${env.ENABLE_VLLM:+vllm} provider_type: remote::vllm config: url: ${env.VLLM_URL:=} api_token: ${env.VLLM_API_KEY:=} max_tokens: ${env.VLLM_MAX_TOKENS:=4096} tls_verify: ${env.VLLM_TLS_VERIFY:=true} - provider_id: ${env.ENABLE_OLLAMA:+ollama} provider_type: remote::ollama config: url: ${env.OLLAMA_URL:=http://localhost:11434} - provider_id: ${env.ENABLE_OPENAI:+openai} provider_type: remote::openai config: api_key: ${env.OPENAI_API_KEY:=} - provider_id: ${env.ENABLE_VERTEX_AI:+vertexai} provider_type: remote::vertexai config: project: ${env.VERTEX_AI_PROJECT:=} location: ${env.VERTEX_AI_LOCATION:=us-central1} - provider_id: sentence-transformers provider_type: inline::sentence-transformers config: {} tool_runtime: - provider_id: model-context-protocol provider_type: remote::model-context-protocol config: {} - provider_id: rag-runtime provider_type: inline::rag-runtime config: {} vector_io: - provider_id: faiss provider_type: inline::faiss config: persistence: namespace: vector_io::faiss backend: faiss_kv files: - provider_id: localfs provider_type: inline::localfs config: storage_dir: /tmp/llama-stack-files metadata_store: table_name: files_metadata backend: sql_files storage: backends: kv_default: type: kv_sqlite db_path: /tmp/kvstore.db sql_default: type: sql_sqlite db_path: /tmp/sql_store.db sql_files: type: sql_sqlite db_path: /rag-content/vector_db/rhdh_product_docs/1.9/files_metadata.db faiss_kv: type: kv_sqlite db_path: /rag-content/vector_db/rhdh_product_docs/1.9/faiss_store.db stores: metadata: namespace: registry backend: faiss_kv inference: table_name: inference_store backend: sql_default max_write_queue_size: 10000 num_writers: 4 conversations: table_name: openai_conversations backend: sql_default registered_resources: models: - model_id: sentence-transformers/all-mpnet-base-v2 metadata: embedding_dimension: 768 model_type: embedding provider_id: sentence-transformers provider_model_id: /rag-content/embeddings_model tool_groups: - provider_id: rag-runtime toolgroup_id: builtin::rag vector_dbs: - vector_db_id: rhdh-product-docs-1_8 embedding_model: sentence-transformers/all-mpnet-base-v2 embedding_dimension: 768 provider_id: faiss server: auth: host: port: 8321 quota: tls_cafile: tls_certfile: tls_keyfile:Mount the config map to your Llama Stack container at
/app-root/run.yamlto make sure it overrides the default image file:name: llama-stack volumeMounts: - mountPath: /app-root/run.yaml subPath: run.yaml name: llama-stack-config
Configure the required volume:
volumes: - name: llama-stack-config configMap: name: llama-stack-configwhere:
llama-stack-config- The config map where you added the new no-guard configuration file.
- Restart the deployment if it does not trigger an automatic rollout.
1.2.4.7. Manage chats
Manage your chat history and configuration in RHDH to organize your workspace, resume earlier tasks, or find past solutions.

Prerequisites
- You have configured the Developer Lightspeed for RHDH plugin in Red Hat Developer Hub.
- You have logged in to the portal.
Procedure
- Click the Lightspeed button at the lower right of the screen to open the chat overlay.
Optional: Configure the interface display and server settings:
- Click the Chatbot options icon (⋮) to view chat history or start a new chat.
Click the Display mode icon and select any of the following views:

Overlay: A floating window is displayed over the current page content.

Dock to window: A panel attaches to the right side of the screen. Activating this mode automatically closes the quick start panel if it is already open.

Fullscreen: A dedicated page opens for intensive chat sessions. This mode displays a revised header containing the Lightspeed logo and a horizontal tab bar, which replaces the previous main menu. Bookmark the URL in your browser to save a direct link to the chat interface.

- Optional: Toggle Enable pinned chats/Disable pinned chats to enable or hide the pinned chats. The system enables this option by default.
Available only if MCP is configured: Manage Model Context Protocol connections.

Start a chat or load an earlier session:
- Enter a prompt: Type a query in the Enter a prompt for Lightspeed chat field and press Enter.
- Use a sample: Click a prompt tile.
Change the AI model: Select a model from the model selector dropdown menu inside the prompt bar.

Attach a file: Click the (
+) icon on the left of the prompt bar to upload a.yaml,.json, or.txtfile. Descriptive text clarifies the function of the icon.- Click the file name to open the preview model.
View or edit the content of the file:

- Use voice: Click the Use microphone icon. The microphone and send buttons are located on the right side of the prompt bar.
Control AI generation: Use the control buttons on the right side of the prompt bar. Click the start/send (
>) button to submit queries, or click the stop ([]) button to halt AI generation.
- Resume a chat: Select a title from the Recent list.
Organize your chat history:
Start a new topic: Click New chat to reset the assistant’s context. When the history panel is collapsed, you must click the Edit square icon to create a new chat.

- Search history: Enter a keyword in the Search field.
Rename a session: Click Options next to a chat title, select Rename, and enter a new name.

- Pin a chat: Click Options next to a chat title and select Pin. The chat moves to the Pinned group.
Sort chats: Click Sort control and choose a sorting criteria, such as Date (Newest first).

Delete a chat: Click Options next to a chat title and select Delete.

Expand or collapse the panel: Click the Expand/collapse icon to toggle the history panel.
NoteThe expanded panel is resizable up to a defined maximum width.
- Optional: To hide the interface, if you are in the Overlay or Dock to window mode, click the Close Lightspeed icon (X) to hide the window. If you are in Fullscreen mode, revert to the other modes and click the Close Lightspeed icon (X). The system preserves your active query and history.
- Optional: In Fullscreen mode, bookmark the URL in your browser to save a direct link to the chat interface.
Verification
- The main window displays the active chat or selected history.
- The chat history list reflects renamed, pinned, or deleted entries.
1.2.4.8. Best results for assistant queries
To resolve technical blockers and accelerate development tasks, you must structure your queries to give specific context to the AI assistant. Using precise prompts makes sure that Developer Lightspeed for RHDH generates relevant code snippets, architectural advice, or platform-specific instructions.
Use the following strategies to improve the accuracy of the assistant’s output during your development workflow:
- Specify technologies
- Instead of asking "How do I use templates?", ask "How do I create a Software Template that scaffolds a Node.js service with a CI/CD pipeline".
- Give context
- Include details about your environment, such as "I am deploying to OpenShift; how do I set up my catalog-info.yaml to show pod health?".
- Use conversation context
- Ask follow-up questions to refine an earlier answer. For example, if the assistant gives a code snippet, you can ask "Now rewrite that using TypeScript interfaces."
- Validate with citations
- Check the provided documentation links and citations in the response to verify that the generated advice aligns with your organization’s official standards.
- Improve assistant accuracy
- Rate the utility of responses by selecting the Thumbs up or Thumbs down icons. This feedback helps tune the model for your organization’s specific requirements.
To keep your data secure, do not include sensitive personal information, plain text credentials, or confidential business data in your queries.
1.2.5. AI model evaluation data to select the right AI model
1.2.5.1. AI model evaluation data to select the right AI model
Use the Red Hat Developer Lightspeed for Red Hat Developer Hub evaluation framework to validate the performance, accuracy, and reliability of Developer Lightspeed for RHDH.
With this automated toolset, you can measure how effectively various large language models (LLMs) answer questions based on Red Hat Developer Hub documentation.
Table 1.1. Components of the evaluation framework
| Component | Description |
|---|---|
|
Evaluation framework |
Contains the core logic and scripts used to run evaluations. |
|
Datasets |
Includes the input files used to test the model. |
|
Evaluation metrics integration |
Provides scoring through various metrics, including Ragas, DeepEval, and custom metrics. Ragas is the primary metric used to validate Developer Lightspeed for RHDH performance. |
1.2.5.2. Configure the evaluation environment to validate model accuracy
Set up the evaluation environment to validate the performance and accuracy of Developer Lightspeed for RHDH. Configure this evaluation to ensure the model correctly interprets documentation and provides dependable answers.
Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
By performing these evaluations, you minimize the risk of the model delivering incorrect or hallucinated information to users in production.
Prerequisites
- Install uv for Python package management (Python 3.11 or later).
Procedure
Clone the evaluation repository and navigate to the directory:
git clone https://github.com/lightspeed-core/lightspeed-evaluation cd lightspeed-evaluation
Synchronize the environment and install dependencies:
uv sync
Configure the environment variables for the judge LLM. You can create a
.envfile in the root directory or export the keys directly to your terminal.If you use Gemini, you must set the Gemini API key:
export GEMINI_API_KEY="your-google-api-key"
If you use OpenAI, you must set the OpenAI API key:
export OPENAI_API_KEY="your-key"
Optional: If you test with a live service, set your Developer Lightspeed for RHDH service API key:
export API_KEY="your-lightspeed-service-key"
Verification
Verify that the environment is synchronized and the virtual environment is active:
uv run python --version
The output must return Python 3.11 or later.
1.2.5.3. Prepare evaluation datasets to verify AI-generated responses
Prepare evaluation data sets to test the performance of Developer Lightspeed for RHDH. You can use pre-generated AI data sets for specific Red Hat Developer Hub releases or generate custom AI data sets from your own documentation.
Prerequisites
- You must clone the evaluation repository to your local machine.
Procedure
Download pre-generated data sets: Use this method to test the performance of specific RHDH releases. These data sets are generated using Ragas testset generation for RAG.
- In your terminal, navigate to the /dataset folder in the evaluation repository.
-
Locate the
.evaluation_dataset_yamlfiles. These files are pre-configured for the evaluation tool. To test a historical release, switch to the corresponding branch.
For example, to access the Red Hat Developer Hub 1.8 data set, switch to the
1.8branch.ImportantThe
mainbranch contains work-in-progress (WIP) data sets. Avoid using this branch for stable evaluations.
Generate custom data sets: Use this method to create a new test set from your own technical documentation.
- Generate a diverse set of question-and-answer (Q&A) pairs by following the Ragas test data generation documentation.
- Ensure your Q&A pairs match the required format by reviewing the evaluation data structure configuration.
Verification
- Verify that your custom data set matches the required schema before you start the evaluation run.
1.2.5.4. Run performance tests to ensure AI response reliability
Use the evaluation framework to run performance tests in either static mode to evaluate pre-recorded responses or dynamic mode to call a live service.
These evaluations identify performance gaps, allow you to compare different large language models (LLMs), and ensure that Developer Lightspeed for RHDH provides reliable information to users.
Prerequisites
- You must install and configure the evaluation environment.
- You must prepare an evaluation data set.
Procedure
-
Download the
system.yamlconfiguration template from the repository. Configure the parameters in the
system.yamlfile based on your evaluation mode:Field Description llmDefines the judge LLM that scores the responses, such as
gemini-2.5-pro.api.enabledSet to
falsefor static mode to use pre-filled data. Set totruefor dynamic mode to call a live service.api.api_base(Required for dynamic mode only) Provide the URL of your Developer Lightspeed for RHDH service.
api.endpoint_typeSpecify the service configuration type:
streamingorquery.Execute the evaluation by using the
lightspeed-evalcommand:lightspeed-eval \ --system-config config/system.yaml \ --eval-data config/evaluation_data.yaml \ --output-dir ./my_evaluation_results
Verification
- Navigate to the specified output directory and verify that the generated reports contain the model performance scores.
1.2.5.5. Analyze evaluation results to identify performance gaps
Determine the performance of Developer Lightspeed for RHDH and identify documentation areas that require model improvement by analyzing evaluation results in the repository. You can use these reports to compare performance across different large language models (LLMs) and topics.
Prerequisites
-
You must have access to the
developer-lightspeed-evaluationrepository.
Procedure
-
In the root of the repository, navigate to the version-specific folder within the
/evaluation-resultdirectory. Open the following files to evaluate performance:
- Model Pass Rate: Compare the overall performance between different LLMs.
- Topic Pass Rate: Identify performance trends and gaps within specific documentation areas.
Verification
- Verify that the reports display data visualizations or metrics consistent with your recent evaluation run.
1.2.5.6. Evaluation metrics and historical data reference
Use the available metrics to evaluate the performance of Developer Lightspeed for RHDH at the conversation turn level.
These metrics provide a standardized way to measure the accuracy and reliability of the generated responses and the retrieved content.
| Metric | Description |
|---|---|
|
|
Measures how well the answer is derived solely from the retrieved context. |
|
|
Measures whether the retrieved context contains all information required to answer the question. |
|
|
Verifies if the retrieved documentation chunks are relevant to the user query. |
|
|
Measures the ratio of useful information within the retrieved documentation chunks. |
|
|
Compares the generated response against the expected ground-truth response. This custom metric is implemented in the evaluation tool. |
1.2.5.7. Release report and historical data
Use the latest Q&A data set and evaluation results to monitor the current performance of Developer Lightspeed for RHDH.
Access version-specific branches that contain the data sets and evaluation results required to track improvements or regressions across product releases.
The main branch contains work-in-progress data for versions currently under development. For stable evaluations or historical tracking, you must switch to the branch associated with a specific release.
| Release version | Branch name | Data included |
|---|---|---|
|
Latest stable |
Most recent version branch |
The current question and answer (Q&A) data set and evaluation results. |
|
Historical |
Previous version branches |
Data sets and evaluation results for previous releases to track regressions. |
1.2.6. Build a private knowledge base with Developer Lightspeed for RHDH Notebooks
1.2.6.1. Build a private knowledge base with Developer Lightspeed for RHDH Notebooks
Use Developer Lightspeed for RHDH notebooks to create isolated research environments. These workspaces allow you to analyze project data securely by using a large language model (LLM) grounded in your specific documentation.
Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
1.2.6.2. Create isolated research workspaces
Organize your work into individual notebook sessions to keep research topics separate and private.

Procedure
- In the RHDH interface, click the Lightspeed button.
- In your Developer Lightspeed for RHDH page, select the Notebooks tab.
- Click Create a new notebook to start a new workspace.
Optional: To manage your workspaces, click the More options icon on a notebook card to Rename, Delete, or add Tags to the session.



Verification
- Confirm the new notebook card appears on the My Notebooks dashboard.
1.2.6.3. Provide project context to the AI
To receive answers tailored to your project, upload and manage relevant source material in your active session.
Procedure
- Open a Notebook card from the dashboard.
Add resources by using one of the following methods:
- In the sidebar, click the Add (+) icon.
In the main user interface, click Upload a resource.

-
Select and upload your local files. Supported formats include
.txt,.md,.pdf,.docx,.log,.yaml, and.json. Adhere to the following constraints:
File size- Individual files or URL content must be 20MB or smaller.
Notebook Capacity- The total token count per session must not exceed 100k.
Unsupported content- Avoid scanned PDF images without text, audio, video, and general image files.
Persistence requirement- The internal SQL and KV stores must be mapped to a persistent backend to maintain the 100k token context across sessions.
- Wait for the system to process and vectorize the files. This might take several seconds for larger PDFs.
Verification
-
Ensure the uploaded files appear in the Resources list in the sidebar with a
Processedstatus.
1.2.6.4. Extract and verify document-based insights
After providing context, use the AI to perform reasoning across your files and verify the accuracy of the responses.

Prerequisites
You have uploaded documents or URLs to the active chat session to establish context.
NoteIf no documents are uploaded, you cannot communicate with the AI.
Procedure
- Enter a question in the prompt bar at the bottom of the screen.
- Analyze the response. The AI identifies relationships across all uploaded documents and URLs in the session.
- To verify accuracy, click the Sources chip to view the specific document excerpts used to generate the answer.
- Manage your workflow by using the history panel in the sidebar to expand or collapse previous interactions.
Verification
- Confirm that the Sources panel displays the correct filenames and text snippets corresponding to the AI’s response.
1.2.7. Platform integrations for toolchain connectivity
1.2.7.1. Platform integrations for toolchain connectivity
Red Hat Developer Hub integrates seamlessly with Red Hat OpenShift Container Platform and other tools, enabling comprehensive development and deployment workflows across enterprise.
1.2.7.1.1. Integration with Red Hat OpenShift Container Platform
Red Hat Developer Hub is fully integrated with Red Hat OpenShift Container Platform, offering:
- Operators to manage application lifecycle.
- Access to advanced OpenShift capabilities such as service mesh, serverless functions, GitOps, and distributed tracing.
- Pipelines and GitOps plugins for streamlined cloud-native workflows.
1.2.7.1.2. Integration with Red Hat Advanced Developer Suite - secure supply chain
Red Hat Advanced Developer Suite - secure supply chain (RHADS - ssc) enhances Red Hat Developer Hub by providing secure CI/CD capabilities that integrate security measures into every stage of the development process.
While Red Hat Developer Hub focuses on the inner loop (code, build, and test), RHADS - ssc manages the outer loop, automating:
- Code scanning
- Image building
- Vulnerability detection
- Deployment
RHADS - ssc includes tools such as Red Hat Trusted Artifact Signer (TAS) for code integrity, Red Hat Trusted Profile Analyzer (TPA) for automated Software build of Materials (SBOM) creation, and Red Hat Advanced Cluster Security (ACS) for vulnerability scanning.
1.2.7.1.3. Extending Backstage with Red Hat Developer Hub
Red Hat Developer Hub which is a fully supported, enterprise-grade productized version of upstream Backstage extends the upstream project by adding:
- Enhanced search capabilities that aggregate data from CI/CD pipelines, cloud providers, source control, and more.
- A centralized software catalog for locating applications, APIs, and resources.
- Automation through open-source plugins that expand the Backstage core functionality.
- Simplified technical documentation using Markdown and GitHub, with integrated search for easy navigation.
1.2.7.2. Integrations in Red Hat Developer Hub
Red Hat Developer Hub integrates seamlessly with Red Hat OpenShift Container Platform and other tools, enabling comprehensive development and deployment workflows across enterprise.
1.2.7.2.1. Integration with Red Hat OpenShift Container Platform
Red Hat Developer Hub is fully integrated with Red Hat OpenShift Container Platform, offering:
- Operators to manage application lifecycle.
- Access to advanced OpenShift capabilities such as service mesh, serverless functions, GitOps, and distributed tracing.
- Pipelines and GitOps plugins for streamlined cloud-native workflows.
1.2.7.2.2. Integration with Red Hat Advanced Developer Suite - secure supply chain
Red Hat Advanced Developer Suite - secure supply chain (RHADS - ssc) enhances Red Hat Developer Hub by providing secure CI/CD capabilities that integrate security measures into every stage of the development process.
While Red Hat Developer Hub focuses on the inner loop (code, build, and test), RHADS - ssc manages the outer loop, automating:
- Code scanning
- Image building
- Vulnerability detection
- Deployment
RHADS - ssc includes tools such as Red Hat Trusted Artifact Signer (TAS) for code integrity, Red Hat Trusted Profile Analyzer (TPA) for automated Software build of Materials (SBOM) creation, and Red Hat Advanced Cluster Security (ACS) for vulnerability scanning.
1.2.7.2.3. Extending Backstage with Red Hat Developer Hub
Red Hat Developer Hub which is a fully supported, enterprise-grade productized version of upstream Backstage extends the upstream project by adding:
- Enhanced search capabilities that aggregate data from CI/CD pipelines, cloud providers, source control, and more.
- A centralized software catalog for locating applications, APIs, and resources.
- Automation through open-source plugins that expand the Backstage core functionality.
- Simplified technical documentation using Markdown and GitHub, with integrated search for easy navigation.
1.2.8. Supported platforms
Verify platform compatibility and life cycle support for Red Hat Developer Hub versions to plan deployments and ensure continued product support.
Additional resources
1.2.9. Red Hat Developer Hub support
The Red Hat Customer Portal provides resources to help you troubleshoot issues and get support for Red Hat Developer Hub. You can use the Red Hat Customer Portal for the following purposes:
- To search or browse through the Red Hat Knowledgebase of technical support articles about Red Hat products.
- To create a support case for Red Hat Global Support Services (GSS), select Red Hat Developer Hub as the product and select the appropriate product version.
1.2.9.1. Collect diagnostic data for support cases
When opening a support case for RHDH deployment, configuration, or runtime issues, providing comprehensive diagnostic data accelerates troubleshooting and reduces time to resolution.
The RHDH must-gather tool collects diagnostic data from RHDH deployments in a single operation.
This tool gathers platform information, deployment configurations, application logs, routes or ingress configurations, and namespace state in a standardized format optimized for support analysis.
The RHDH must-gather tool is available on Red Hat OpenShift Container Platform (OpenShift Container Platform) 4.18 and later using the oc adm must-gather command, and on Kubernetes platforms including Microsoft Azure Kubernetes Service, Amazon Elastic Kubernetes Service, and Google Kubernetes Engine using a Helm chart deployment.
To collect and attach diagnostic data to your support case, see Collect diagnostic data to streamline support resolution.
Chapter 2. Get started
2.1. Get Started
Set up your first Red Hat Developer Hub instance, configure authentication, and navigate the platform interface to start using developer portal capabilities.
2.2. Set up the first RHDH instance
2.2.1. Set up the first RHDH instance
Install the operator, prepare external services, provision custom configuration, enable authentication, and start your instance for production workloads.
2.2.2. Checklist to run your first Red Hat Developer Hub (RHDH) instance in production
With the default configuration, Developer Hub runs with a minimal feature set that does not require secure connection to external services such as an identity provider, a Git provider, and external PostgreSQL and Redis databases.
Using critical features requires the following additional configuration:
- For resiliency
- Use an external PostgreSQL database.
- Enable high-availability.
- For performance
- Enable assets caching to an external Redis database.
- For security
- Use secure connections to your external services.
- Provision users and enable authentication.
- Enable role-based access control, and configure the permission policy by using the Web UI.
- For adapting to your environment
- Enable GitHub repository discovery.
- Customize Developer Hub appearance with your logo.
2.2.3. Install the Operator
As an administrator, you can install the Red Hat Developer Hub Operator. Authorized users can use the Operator to install Red Hat Developer Hub on Red Hat OpenShift Container Platform (OpenShift Container Platform) and supported Kubernetes platforms.
For more information about supported platforms and versions, see the Red Hat Developer Hub Life Cycle page.
Containers are available for the following CPU architectures:
-
AMD64 and Intel 64 (
x86_64)
Prerequisites
- You have logged in as an administrator on the OpenShift Container Platform web console.
- You have configured the appropriate roles and permissions within your project to create or access an application. For more information, see the Red Hat OpenShift Container Platform documentation on Building applications.
- You have installed Red Hat OpenShift Container Platform 4.18 to 4.21.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
You can upgrade Red Hat Developer Hub directly from any earlier version to the latest release without installing intermediate versions. However, you must review the release notes for every skipped version to identify breaking changes or required migration steps. For example, if upgrading from version 1.5 to 1.7, check the release notes for both 1.6 and 1.7.
Procedure
In the OpenShift Container Platform web console, find and install the Red Hat Developer Hub Operator from the software catalog.
For the detailed console steps, see Installing from the software catalog by using the web console in the Red Hat OpenShift Container Platform documentation.
On the Install Operator page, configure the following options:
From the Update channel drop-down menu, select fast or fast-1.10.
ImportantThe fast channel includes all of the updates available for a particular version. Any update might introduce unexpected changes in your Red Hat Developer Hub deployment. Check the release notes for details about any potentially breaking changes.
The fast-1.10 channel only provides z-stream updates, for example, updating from version 1.10.1 to 1.10.2. If you want to update the Red Hat Developer Hub y-version in the future, for example, updating from 1.10 to 2.1, you must switch to the fast-2.1 channel manually.
- From the Version drop-down menu, select the version of the Red Hat Developer Hub Operator that you want to install.
For Installation mode, keep the default All namespaces on the cluster option.
NoteThe Specific namespace on the cluster option is not currently supported.
For Installed Namespace, select Operator recommended Namespace to use the default rhdh-operator namespace.
ImportantFor enhanced security, better control over the Operator lifecycle, and preventing potential privilege escalation, install the Red Hat Developer Hub Operator in a dedicated default
rhdh-operatornamespace. You can restrict other users' access to the Operator resources through role bindings or cluster role bindings.You can also install the Operator in another namespace by creating the necessary resources, such as an Operator group. For more information, see Installing global Operators in custom namespaces.
However, if the Red Hat Developer Hub Operator shares a namespace with other Operators, then it shares the same update policy as well, preventing the customization of the update policy. For example, if one Operator is set to manual updates, the Red Hat Developer Hub Operator update policy is also set to manual. For more information, see Colocation of Operators in a namespace.
- Select the Update approval method and click Install.
Verification
- Navigate to Ecosystem > Installed Operators and verify that the Red Hat Developer Hub Operator status is Succeeded.
2.2.4. Prepare your external services
Red Hat Developer Hub relies on external services for production use, including a PostgreSQL database, Redis cache, GitHub API access, and an identity provider.
- PostgreSQL database
- Developer Hub stores data in a PostgreSQL database. Use an external database for resiliency and include it in your disaster recovery plan.
- Redis cache
- For efficiency, Developer Hub caches plugin and TechDocs assets when you provide a Redis cache server.
- GitHub API access
- Provide credentials to a GitHub app to enable access to the GitHub API for repository discovery.
- Connection to your identity provider
- Provide credentials to your identity provider to enable user provisioning and authentication.
Procedure
Get your external PostgreSQL database connection strings and certificates.
- postgres-host
- Your PostgreSQL instance Domain Name System (DNS) or IP address.
- postgres-port
- Your PostgreSQL instance port number, such as 5432.
- postres-username
- The user name to connect to your PostgreSQL instance.
- postgres-password
- The password to connect to your PostgreSQL instance.
- postgres-ca.pem, postgres-key.key, postgres-crt.pem
- For security, use TLS certificates to secure the connection to the database.
-
Get your Redis cache server connection string, such as
rediss://user:pass@cache.example.com:6379. For security, consider using aredisssecure server connection. Create a GitHub App to allow Developer Hub to access the GitHub API for repository. Opt for a GitHub App instead of an OAuth app to use fine-grained permissions, gain more control over which repositories the application can access, and use short-lived tokens.
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>. - Authorization callback URL
-
Enter your Developer Hub authentication backend URL:
https://<my_developer_hub_domain>/api/auth/github/handler/frame. - Webhook
- Clear "Active", as this is not needed for authentication and catalog providers.
- App permissions
Select permissions to define the level of access for the app. Adapt permissions to your needs:
- Reading software components
- Contents
-
Read-only - Commit statuses
-
Read-only
- Reading organization data
- Members
-
Read-only
- Publishing software templates
Set permissions if you intend to use the same GitHub App for software templates.
- Administration
-
Read & write(for creating repositories) - Contents
-
Read & write - Metadata
-
Read-only - Pull requests
-
Read & write - Issues
-
Read & write - Workflows
-
Read & write(if templates include GitHub workflows) - Variables
-
Read & write(if templates include GitHub Action Repository Variables) - Secrets
-
Read & write(if templates include GitHub Action Repository Secrets) - Environments
-
Read & write(if templates include GitHub Environments)
- Organization permissions
- Members
-
Read-only
- Where can this GitHub App be installed?
-
Select
Only on this account.
- In the General → Clients secrets section, click Generate a new client secret.
- In the General → Private keys section, click Generate a private key.
- In the Install App tab, choose an account to install your GitHub App on.
- Save the following values for the next step:
- App ID
- Client ID
- Client secret
- Private key
2.2.5. Provision your custom configuration
Provision custom config maps and secrets on Red Hat OpenShift Container Platform (RHOCP) to configure Red Hat Developer Hub before running the application.
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
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.txtfile, with one secret per line inKEY=valueform.Author your custom
app-config.yamlfile. This is the main Developer Hub configuration file. You need a customapp-config.yamlfile to avoid the Developer Hub installer to revert user edits during upgrades. When your customapp-config.yamlfile 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.yamlfile 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 arebaseUrlin theappandbackendsections, andoriginin thebackend.corssubsection:Configuring the
baseUrlinapp-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:
Author your custom
dynamic-plugins.yamlfile 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.yamlincludes: - 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: falseProvision your custom configuration files to your OpenShift Container Platform cluster.
Create the <my-rhdh-project> project aimed at containing your Developer Hub instance.
$ oc create namespace my-rhdh-project
Create config maps for your
app-config.yamlanddynamic-plugins.yamlfiles 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.
Provision your
secrets.txtfile to themy-rhdh-secretssecret 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.
2.2.6. Enable initial authentication to verify user access
2.2.6.1. Enable initial authentication to verify user access
Configure authentication methods, set up guest access for testing, and integrate your identity provider to verify user access.
2.2.6.2. Authentication methods and identity provider selection
2.2.6.2.1. Authentication methods and identity provider selection
Review available authentication methods and identity provider options to select the appropriate approach for your organization.
2.2.6.3. Configure guest access to safely test early deployments
2.2.6.3.1. Configure guest access to safely test early deployments
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.
Guest access is not recommended for production.
2.2.6.4. Integrate your chosen identity provider
2.2.6.4.1. Integrate your chosen identity provider
Enable authentication with your main identity provider to allow users to sign in to Red Hat Developer Hub using their organizational credentials.
2.2.7. Use the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration
Use the Developer Hub Operator to run Red Hat Developer Hub with your custom configuration by creating a Backstage custom resource (CR).
The custom resource can mount files from your custom config maps and inject environment variables from your custom 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. - Section 2.2.3, “Install the Operator”
- Section 2.2.5, “Provision your custom configuration”
Procedure
Author your Backstage CR in a
my-rhdh-custom-resource.yamlfile to use your custom config maps and secrets.my-rhdh-custom-resource.yamlcustom 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: 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' secrets: - name: my-rhdh-secrets extraFiles: mountPath: /opt/app-root/src secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem, postgres-ca.pem, postgres-key.key replicas: 2 database: enableLocalDb: falseapplicationappConfig-
Register your
my-rhdh-app-configandrbac-policiesconfig maps. dynamicPluginsConfigMapName-
Register your
dynamic-plugins-rhdhconfig map. extraEnvsenv- Enter your proxy environment variables.
secrets-
Register your
<my_product_secrets>andmy-rhdh-database-secretssecrets.
extraFilessecrets-
Register the
postgres-crt.pem,postgres-ca.pem, andpostgres-key.keyfiles contained in themy-rhdh-database-certificates-secretssecret.
replicas- Enable high availability (HA) by increasing the replicas count to a value higher or equal to 2.
databaseenableLocalDb- Use your external PostgreSQL database rather than the internal PostgreSQL database.
Apply your Backstage CR to start or update your Developer Hub instance.
$ oc apply --filename=my-rhdh-custom-resource.yaml --namespace=my-rhdh-project
2.2.8. Configure the default theme mode
You can switch the RHDH interface between light, dark, or auto mode (which matches your system preference).
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
- From the Developer Hub web console, click Settings.
From the Appearance panel, select Light, Dark, or Auto to change the theme mode.

Verification
- The interface immediately updates to reflect the selected theme.
2.2.9. RBAC policy files
Developer Hub uses external policy files to define role-based access control (RBAC) rules. Two files work together to control permissions: a CSV file for standard policies and a YAML file for conditional policies.
rbac-policy.csvUses Casbin syntax with two entry types:
-
pentries define policy rules (p, role, resource, action, effect). -
gentries define role assignments (g, user, role).
-
rbac-conditional-policies.yaml- Defines conditional policies with criteria-based filtering for fine-grained access control.
Provisioning
Both files are provisioned together in a single config map, such as, rbac-policies. Reference the files from app-config.yaml by using the following fields:
-
permission.rbac.policies-csv-filefor the CSV path. -
permission.rbac.conditionalPoliciesFilefor the conditional policies YAML path.
Additional resources
Chapter 3. Plan
3.1. Plan
Evaluate deployment methods, sizing requirements, and scaling benchmarks to provision the right infrastructure for Red Hat Developer Hub. Planning decisions made before installation define long-term platform performance, operational cost, and upgrade flexibility.
3.2. Plan your deployment architecture and scale
3.2.1. Plan your deployment architecture and scale
Choose the right deployment method, assign compute and storage resources, and establish performance baselines before installing Red Hat Developer Hub. Architecture decisions made during planning affect cluster resource use, database resilience, and future scaling capacity.
3.2.2. Sizing requirements for cluster resource provisioning
3.2.2.1. Sizing requirements for cluster resource provisioning
Find the CPU, memory, and storage requirements for Red Hat Developer Hub application pods, databases, and Operator components. Correct resource provisioning prevents out-of-memory failures and ensures the platform meets target response times under expected user loads.
3.2.2.2. Compute and storage resource guidelines
Plan infrastructure resources for Red Hat Developer Hub deployments using sizing requirements for the application, database, and Operator.
Table 1 lists the sizing requirements for installing and running Red Hat Developer Hub, including Developer Hub application, database components, and Operator. Table 2 lists recommended sizing requirements for external PostgreSQL deployment based on the deployment scale.
| Components | Red Hat Developer Hub application | Red Hat Developer Hub database | Red Hat Developer Hub Operator |
|---|---|---|---|
|
Central Processing Unit (CPU) |
4 vCPU |
2 vCPU |
1 vCPU |
|
Memory |
16 GB |
8 GB |
1500 Mi |
|
Storage size |
2 GB |
20 GB |
50 Mi |
|
Replicas |
2 or more |
3 or more |
1 or more |
| Sizing legend | Small-scale | Mid-scale | Large-scale | Enterprise-scale |
|---|---|---|---|---|
|
Application usage |
up to 5 thousand entities, up to 50 concurrent users |
5–20 thousand entities, 50–150 concurrent users |
20–50 thousand entities, 150–400 concurrent users |
50–150 thousand entities, 400–800 concurrent users |
|
vCPU |
2 |
4 |
8 |
16 |
|
Memory |
8 GiB |
16 GiB |
32 GiB |
64 GiB |
|
Storage |
50 GiB |
100 GiB |
200 GiB |
500 GiB |
|
Number of replicas |
1 |
2 |
2-3 |
3+ |
|
PostgreSQL Database HA |
1 primary |
1 primary, 1 standby |
1 primary, 1 synchronous standby |
1 primary, 1 synchronous standby, 1 asynchronous replica |
Table 3 lists recommended PostgreSQL performance tuning parameters based on the deployment scale for an external PostgreSQL deployment. Set shared_buffers to approximately 1/4 of the allocated database memory and effective_cache_size to approximately 1/2 of the allocated database memory. For more information, see the PostgreSQL tuning guide.
| Sizing legend | Memory | shared_buffers | effective_cache_size |
|---|---|---|---|
|
Small-scale |
8 GiB |
2 GB |
4 GB |
|
Mid-scale |
16 GiB |
4 GB |
8 GB |
|
Large-scale |
32 GiB |
8 GB |
16 GB |
|
Enterprise-scale |
64 GiB |
16 GB |
32 GB |
Using an external PostgreSQL instance is recommended for production deployments.
3.2.3. Compare the Helm chart and Operator deployment methods
3.2.3.1. Compare the Helm chart and Operator deployment methods
Evaluate the Helm chart and Operator installation methods to select the approach that matches your platform capabilities and operational model. The deployment method determines how you manage upgrades, configure high availability, and integrate with cluster lifecycle tools.
3.2.3.2. Pros and cons of each deployment method
When planning your Red Hat Developer Hub deployment, you must choose between the Helm chart and Operator installation methods. Use the following table to choose the method that aligns with your operational model and team capabilities:
| Helm chart | Operator |
|---|---|
|
Platform requirements
|
Platform requirements
|
|
Setup and deployment priorities
|
Setup and deployment priorities
|
|
Update preferences
|
Update preferences
|
|
Team capabilities
|
Team capabilities
|
|
Control and customization needs
|
Control and customization needs
|
Both installation methods are fully supported by Red Hat. Choose the method that best matches your operational priorities, platform requirements, and team expertise.
For detailed installation instructions, see Installing Red Hat Developer Hub on OpenShift Container Platform.
3.2.4. Scale your deployment using enterprise performance benchmarks
3.2.4.1. Scale your deployment using enterprise performance benchmarks
Apply enterprise-scale benchmarks to plan resource allocation for growing catalog sizes and concurrent user loads. Benchmark data enables capacity planning that matches infrastructure investment to actual usage patterns and growth projections.
Chapter 4. Install
4.1. Install
Deploy Red Hat Developer Hub on OpenShift Container Platform, managed hyperscaler environments, or air-gapped infrastructure to establish your developer portal.
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
Install Red Hat Developer Hub on Red Hat OpenShift Container Platform by using either the Red Hat Developer Hub Operator or the Helm chart.
4.2.2. Compare the Helm chart and Operator deployment methods
You can install Red Hat Developer Hub on OpenShift Container Platform by using one of the following installers:
- The Red Hat Developer Hub Operator
- Ready for immediate use in OpenShift Container Platform after an administrator installs it with OperatorHub
- Uses Operator Lifecycle Management (OLM) to manage automated subscription updates on OpenShift Container Platform
- Requires preinstallation of Operator Lifecycle Management (OLM) to manage automated subscription updates on Kubernetes
- The Red Hat Developer Hub Helm chart
- Ready for immediate use in both OpenShift Container Platform and Kubernetes
- Requires manual installation and management
For guidance on choosing between the Helm chart and Operator based on your operational requirements and team capabilities, see Compare the Helm chart and Operator to choose the optimal deployment method.
You must set the baseUrl in app-config.yaml to match the external URL of your Developer Hub instance, such as https://<my_developer_hub_domain>. This value is required for the Red Hat Developer Hub to function correctly. If it is not set, front-end and back-end services cannot communicate properly, and features might not work as expected.
4.2.3. Install on OpenShift Container Platform using the Operator
4.2.3.1. Install on OpenShift Container Platform using the Operator
You can install Red Hat Developer Hub on OpenShift Container Platform by using the Red Hat Developer Hub Operator in the OpenShift Container Platform console.
4.2.3.2. Install the Operator
As an administrator, you can install the Red Hat Developer Hub Operator. Authorized users can use the Operator to install Red Hat Developer Hub on Red Hat OpenShift Container Platform (OpenShift Container Platform) and supported Kubernetes platforms.
For more information about supported platforms and versions, see the Red Hat Developer Hub Life Cycle page.
Containers are available for the following CPU architectures:
-
AMD64 and Intel 64 (
x86_64)
Prerequisites
- You have logged in as an administrator on the OpenShift Container Platform web console.
- You have configured the appropriate roles and permissions within your project to create or access an application. For more information, see the Red Hat OpenShift Container Platform documentation on Building applications.
- You have installed Red Hat OpenShift Container Platform 4.18 to 4.21.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
You can upgrade Red Hat Developer Hub directly from any earlier version to the latest release without installing intermediate versions. However, you must review the release notes for every skipped version to identify breaking changes or required migration steps. For example, if upgrading from version 1.5 to 1.7, check the release notes for both 1.6 and 1.7.
Procedure
In the OpenShift Container Platform web console, find and install the Red Hat Developer Hub Operator from the software catalog.
For the detailed console steps, see Installing from the software catalog by using the web console in the Red Hat OpenShift Container Platform documentation.
On the Install Operator page, configure the following options:
From the Update channel drop-down menu, select fast or fast-1.10.
ImportantThe fast channel includes all of the updates available for a particular version. Any update might introduce unexpected changes in your Red Hat Developer Hub deployment. Check the release notes for details about any potentially breaking changes.
The fast-1.10 channel only provides z-stream updates, for example, updating from version 1.10.1 to 1.10.2. If you want to update the Red Hat Developer Hub y-version in the future, for example, updating from 1.10 to 2.1, you must switch to the fast-2.1 channel manually.
- From the Version drop-down menu, select the version of the Red Hat Developer Hub Operator that you want to install.
For Installation mode, keep the default All namespaces on the cluster option.
NoteThe Specific namespace on the cluster option is not currently supported.
For Installed Namespace, select Operator recommended Namespace to use the default rhdh-operator namespace.
ImportantFor enhanced security, better control over the Operator lifecycle, and preventing potential privilege escalation, install the Red Hat Developer Hub Operator in a dedicated default
rhdh-operatornamespace. You can restrict other users' access to the Operator resources through role bindings or cluster role bindings.You can also install the Operator in another namespace by creating the necessary resources, such as an Operator group. For more information, see Installing global Operators in custom namespaces.
However, if the Red Hat Developer Hub Operator shares a namespace with other Operators, then it shares the same update policy as well, preventing the customization of the update policy. For example, if one Operator is set to manual updates, the Red Hat Developer Hub Operator update policy is also set to manual. For more information, see Colocation of Operators in a namespace.
- Select the Update approval method and click Install.
Verification
- Navigate to Ecosystem > Installed Operators and verify that the Red Hat Developer Hub Operator status is Succeeded.
4.2.3.3. Provision your custom configuration
Provision custom config maps and secrets on Red Hat OpenShift Container Platform (RHOCP) to configure Red Hat Developer Hub before running the application.
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
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.txtfile, with one secret per line inKEY=valueform.Author your custom
app-config.yamlfile. This is the main Developer Hub configuration file. You need a customapp-config.yamlfile to avoid the Developer Hub installer to revert user edits during upgrades. When your customapp-config.yamlfile 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.yamlfile 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 arebaseUrlin theappandbackendsections, andoriginin thebackend.corssubsection:Configuring the
baseUrlinapp-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:
Author your custom
dynamic-plugins.yamlfile 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.yamlincludes: - 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: falseProvision your custom configuration files to your OpenShift Container Platform cluster.
Create the <my-rhdh-project> project aimed at containing your Developer Hub instance.
$ oc create namespace my-rhdh-project
Create config maps for your
app-config.yamlanddynamic-plugins.yamlfiles 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.
Provision your
secrets.txtfile to themy-rhdh-secretssecret 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.
4.2.4. Install on OpenShift Container Platform using the Helm chart
4.2.4.1. Install on OpenShift Container Platform using the Helm chart
You can install Red Hat Developer Hub on OpenShift Container Platform by using the Helm chart with one of the following methods:
- The OpenShift Container Platform console
- The Helm CLI
4.2.4.2. Deploy from the web console
You can use a Helm chart to install Developer Hub on the Red Hat OpenShift Container Platform web console.
Helm is a package manager on OpenShift Container Platform that provides the following features:
- Applies regular application updates using custom hooks
- Manages the installation of complex applications
- Provides charts that you can host on public and private servers
- Supports rolling back to earlier application versions
The Red Hat Developer Hub Helm chart is available in the Helm catalog on OpenShift Dedicated and OpenShift Container Platform.
Prerequisites
- You have logged in to your OpenShift Container Platform account.
-
A user with the OpenShift Container Platform
adminrole has configured the appropriate roles and permissions within your project to create an application. For more information about OpenShift Container Platform roles, see Using RBAC to define and apply permissions. - You have created a project in OpenShift Container Platform. For more information about creating a project in OpenShift Container Platform, see Red Hat OpenShift Container Platform documentation.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
- From the Developer perspective on the Developer Hub web console, click +Add.
- From the Developer Catalog panel, click Helm Chart.
- In the Filter by keyword box, enter Developer Hub and click the Red Hat Developer Hub card.
- From the Red Hat Developer Hub page, click Create.
-
From your cluster, copy the OpenShift Container Platform router host (for example:
apps.<clusterName>.com). Select the radio button to configure the Developer Hub instance with either the form view or YAML view. The Form view is selected by default.
Using Form view
- To configure the instance with the Form view, go to Root Schema → global → Enable service authentication within Red Hat Developer Hub instance and paste your OpenShift Container Platform router host into the field on the form.
Using YAML view
To configure the instance with the YAML view, paste your OpenShift Container Platform router hostname in the
global.clusterRouterBaseparameter value as shown in the following example:global: auth: backend: enabled: true clusterRouterBase: apps.<clusterName>.com
- Edit the other values if needed.
- Click Create and wait for the database and Developer Hub to start.
Click the Open URL icon to start using the Developer Hub platform.
NoteThe host information is copied and can be accessed by the Developer Hub backend.
When an OpenShift Container Platform route is generated automatically, the host value for the route is inferred and the same host information is sent to the Developer Hub. Also, if the Developer Hub is present on a custom domain by setting the host manually using values, the custom host takes precedence.
Troubleshooting
Your
developer-hubpod might be in aCrashLoopBackOffstate if the Developer Hub container cannot access the configuration files. This error is indicated by the following log:Loaded config from app-config-from-configmap.yaml, env ... 2023-07-24T19:44:46.223Z auth info Configuring "database" as KeyStore provider type=plugin Backend failed to start up Error: Missing required config value at 'backend.database.client'
To resolve the error, verify the configuration files.
4.2.4.3. Deploy with the Helm CLI
You can use the Helm CLI to install Red Hat Developer Hub on Red Hat OpenShift Container Platform.
Prerequisites
-
You have installed the OpenShift CLI (
oc) on your workstation. - You have logged in to your OpenShift Container Platform account.
- A user with the OpenShift Container Platform admin role has configured the appropriate roles and permissions within your project to create an application. For more information about OpenShift Container Platform roles, see Using RBAC to define and apply permissions.
- You have created a project in OpenShift Container Platform. For more information about creating a project in OpenShift Container Platform, see Red Hat OpenShift Container Platform documentation.
- You have installed the Helm CLI tool.
Procedure
Create and activate the <my-rhdh-project> OpenShift Container Platform project:
NAMESPACE=<emphasis><rhdh></emphasis> oc new-project ${NAMESPACE} || oc project ${NAMESPACE}Install the Red Hat Developer Hub Helm chart:
helm upgrade redhat-developer-hub -i https://github.com/openshift-helm-charts/charts/releases/download/redhat-redhat-developer-hub-1.10.1/redhat-developer-hub-1.10.1.tgz
Configure your Developer Hub Helm chart instance with the Developer Hub database password and router base URL values from your OpenShift Container Platform cluster:
PASSWORD=$(oc get secret redhat-developer-hub-postgresql -o jsonpath="{.data.password}" | base64 -d) CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') helm upgrade redhat-developer-hub -i "https://github.com/openshift-helm-charts/charts/releases/download/redhat-redhat-developer-hub-1.10.1/redhat-developer-hub-1.10.1.tgz" \ --set global.clusterRouterBase="$CLUSTER_ROUTER_BASE" \ --set global.postgresql.auth.password="$PASSWORD"Display the running Developer Hub instance URL:
echo "https://redhat-developer-hub-$NAMESPACE.$CLUSTER_ROUTER_BASE"
Verification
- Open the running Developer Hub instance URL in your browser to use Developer Hub.
Additional resources
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
Install Red Hat Developer Hub on managed cloud Kubernetes platforms by following a clear installation path for your specific hyperscaler environment, so you can get Developer Hub running on EKS, GKE, AKS, or OpenShift Dedicated without having to adapt generic instructions.
4.3.2. Install on Amazon Elastic Kubernetes Service (EKS) using the Operator
4.3.2.1. Install on Amazon Elastic Kubernetes Service (EKS) using the Operator
Install Red Hat Developer Hub on EKS by using the Red Hat Developer Hub Operator with the Operator Lifecycle Manager (OLM) framework for over-the-air updates and catalogs.
To benefit from over-the-air updates and catalogs provided by Operator-based applications distributed with the Operator Lifecycle Manager (OLM) framework, consider installing Red Hat Developer Hub by using the Red Hat Developer Hub Operator distributed in the Red Hat Container Registry.
On EKS, the most notable differences over an OpenShift-based installation are:
- The OLM framework and the Red Hat Container Registry are not built-in.
- The Red Hat Container Registry pull-secret is not managed globally.
- To expose the application, Ingresses replace OpenShift Routes.
For clarity, sections highlight these platform-specific additional steps.
4.3.2.2. Install the Operator using OLM to automate deployments
Install the Red Hat Developer Hub Operator on EKS by using the Operator Lifecycle Manager (OLM) framework.
The Red Hat Container Registry (registry.redhat.io), based on the Operator Lifecycle Manager (OLM) framework, has a distribution of the Red Hat Developer Hub Operator, aimed at managing your Red Hat Developer Hub instance lifecycle.
However, on Amazon Elastic Kubernetes Service (EKS):
- The Operator Lifecycle Manager (OLM) framework and the Red Hat Container Registry are not built-in.
- The Red Hat Container Registry pull-secret is not managed globally.
Therefore, install the OLM framework, the Red Hat Container Registry, and provision your Red Hat Container Registry pull secret to install Developer Hub Operator.
Prerequisites
-
You have installed the
kubectlCLI on your local environment. - Your system meets the sizing requirements for Red Hat Developer Hub.
- You have installed the Operator Lifecycle Manager (OLM).
Your credentials to the Red Hat Container Registry:
- <redhat_user_name>
- <redhat_password>
- <email>
-
You have set the context to the EKS cluster in your current
kubeconfig. For more information, see Creating or updating akubeconfigfile for an Amazon EKS cluster.
Procedure
Create the
rhdh-operatornamespace to contain the Red Hat Developer Hub Operator:$ kubectl create namespace rhdh-operator
Create a pull secret using your Red Hat credentials to pull the container images from the protected Red Hat Container Registry (registry.redhat.io):
$ kubectl -n rhdh-operator create secret docker-registry rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>Create a catalog source that has the Red Hat operators:
$ cat <<EOF | kubectl -n rhdh-operator apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: redhat-catalog spec: sourceType: grpc image: registry.redhat.io/redhat/redhat-operator-index:v4.21 secrets: - "rhdh-pull-secret" displayName: Red Hat Operators EOF
Create an operator group to manage your operator subscriptions:
$ cat <<EOF | kubectl apply -n rhdh-operator -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: rhdh-operator-group EOF
Create a subscription to install the Red Hat Developer Hub Operator:
$ cat <<EOF | kubectl apply -n rhdh-operator -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: rhdh namespace: rhdh-operator spec: channel: fast installPlanApproval: Automatic name: rhdh source: redhat-catalog sourceNamespace: rhdh-operator startingCSV: rhdh-operator.v1.10.1 EOF
To wait until the Operator deployment finishes to be able to run the next step, run:
$ until kubectl -n rhdh-operator get deployment rhdh-operator &>/dev/null; do echo -n . sleep 3 done echo "RHDH Operator Deployment created"
Include your pull secret name in the Operator deployment manifest, to avoid
ImagePullBackOfferrors:$ kubectl -n rhdh-operator patch deployment \ rhdh-operator --patch '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"rhdh-pull-secret"}]}}}}' \ --type=merge
Verification
Verify the deployment name:
$ kubectl get deployment -n rhdh-operator
4.3.2.3. Provision your custom configuration
Provision custom config maps and secrets on Amazon Elastic Kubernetes Service (EKS) to configure Red Hat Developer Hub before running the application.
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 Kubernetes CLI ('kubectl'), you have access, with developer permissions, to the OpenShift cluster aimed at containing your Developer Hub instance.
Procedure
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.txtfile, with one secret per line inKEY=valueform.Author your custom
app-config.yamlfile. This is the main Developer Hub configuration file. You need a customapp-config.yamlfile to avoid the Developer Hub installer to revert user edits during upgrades. When your customapp-config.yamlfile 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.yamlfile 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 arebaseUrlin theappandbackendsections, andoriginin thebackend.corssubsection:Configuring the
baseUrlinapp-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:
Author your custom
dynamic-plugins.yamlfile 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.yamlincludes: - 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: falseProvision your custom configuration files to your EKS cluster.
Create the <my-rhdh-project> namespace aimed at containing your Developer Hub instance.
$ oc create namespace my-rhdh-project
Create config maps for your
app-config.yamlanddynamic-plugins.yamlfiles 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.
Provision your
secrets.txtfile to themy-rhdh-secretssecret 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.
4.3.2.4. Provision a pull secret to access the container registry
On Amazon Elastic Kubernetes Service (EKS), provision your Red Hat Container Registry pull secret in your Red Hat Developer Hub instance namespace because the pull secret is not managed globally.
On Amazon Elastic Kubernetes Service (EKS), the Red Hat Container Registry pull-secret is not managed globally. Therefore add your pull-secret in your Red Hat Developer Hub instance namespace.
Prerequisites
Your credentials to the Red Hat Container Registry:
- <redhat_user_name>
- <redhat_password>
- <email>
-
You created the
{my-rhdh-project}namespace on EKS to host your Developer Hub instance.
Procedure
Create a pull secret using your Red Hat credentials to pull the container images from the protected Red Hat Container Registry (registry.redhat.io):
$ kubectl -n {my-rhdh-namespace} create secret docker-registry my-rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>To enable pulling Developer Hub images from the Red Hat Container Registry, add the image pull secret in the default service account within the namespace where the Developer Hub instance is being deployed:
$ kubectl patch serviceaccount default \ -p '{"imagePullSecrets": [{"name": "my-rhdh-pull-secret"}]}' \ -n {my-rhdh-namespace}
4.3.2.5. Deploy a custom configuration using an Operator
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 Kubernetes CLI ('kubectl'), you have access, with developer permissions, to the EKS 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
Author your Backstage CR in a
my-rhdh-custom-resource.yamlfile to use your custom config maps and secrets.Minimal
my-rhdh-custom-resource.yamlcustom 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: truemy-rhdh-custom-resource.yamlcustom 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-configconfig map:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-configMount files in the
my-rhdh-app-configandrbac-policiesconfig maps:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-config - name: rbac-policiesspec.application.extraEnvs.envsOptionally, enter your additional environment variables that are not secrets, such as your proxy environment variables.
Inject your
HTTP_PROXY,HTTPS_PROXYandNO_PROXYenvironment 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.secretsEnter 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-secretssecrets:spec: application: extraEnvs: secrets: - name: <my_product_secrets> - name: my-rhdh-database-secretsNote<my_product_secrets>is your preferred Developer Hub secret name, specifying the identifier for your secret configuration within Developer Hub.spec.application.extraFiles.secretsEnter your certificates files secret name and files list.
Mount the
postgres-crt.pem,postgres-ca.pem, andpostgres-key.keyfiles contained in themy-rhdh-database-certificates-secretssecret:spec: application: extraFiles: mountPath: /opt/app-root/src secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem, postgres-ca.pem, postgres-key.keyspec.database.enableLocalDbEnable or disable the local PostgreSQL database.
Disable the local PostgreSQL database generation to use an external postgreSQL database:
spec: database: enableLocalDb: falseOn a development environment, use the local PostgreSQL database:
spec: database: enableLocalDb: truespec.deployment- Optionally, enter your deployment configuration.
Apply your Backstage CR to start or update your Developer Hub instance:
$ oc apply --filename=my-rhdh-custom-resource.yaml --namespace=my-rhdh-project
4.3.2.6. Expose your Operator instance using an Ingress resource
On Amazon Elastic Kubernetes Service (EKS), Kubernetes ingresses replace OpenShift Container Platform routes. The Red Hat Developer Hub Operator does not create ingresses. Therefore, to access your Developer Hub instance via a domain name, create the required ingresses on EKS and point your domain name to it.
Prerequisites
- You have installed Red Hat Developer Hub by using the Red Hat Developer Hub Operator.
- You have an EKS cluster with AWS Application Load Balancer (ALB) add-on installed. For more information, see Application load balancing on Amazon Elastic Kubernetes Service and Installing the AWS Load Balancer Controller add-on.
- You have configured a domain name for your Developer Hub instance. The domain name can be a hosted zone entry on Route 53 or managed outside of AWS. For more information, see Configuring Amazon Route 53 as your DNS service documentation.
- You have an entry in the AWS Certificate Manager for your preferred domain name. Make sure to keep a record of your Certificate Amazon Resource Name (ARN).
-
You have set the context to the EKS cluster in your current
kubeconfig. For more information, see Creating or updating akubeconfigfile for an Amazon EKS cluster.
Procedure
Create an Ingress manifest file, named
rhdh-ingress.yaml, specifying your Developer Hub service name as follows:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-rhdh-ingress annotations: alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip # TODO: Using an ALB HTTPS Listener requires a certificate for your own domain. Fill in the ARN of your certificate, e.g.: alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:us-xxx:xxxx:certificate/xxxxxx alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' alb.ingress.kubernetes.io/ssl-redirect: '443' external-dns.alpha.kubernetes.io/hostname: <my_developer_hub_domain> spec: ingressClassName: alb rules: - host: <my_developer_hub_domain> http: paths: - path: / pathType: Prefix backend: service: name: my-rhdh-custom-resource port: name: http-backend EOFReplace <my_developer_hub_domain> with your Developer Hub domain name and update the value of
alb.ingress.kubernetes.io/certificate-arnwith your certificate ARN.- Update your required domain name, (for example, in Route 53 or your external DNS service) to point to the provisioned IP address. Elastic Kubernetes Service provisions an Application Load Balancer (ALB) with a corresponding IP address.
To deploy the created Ingress, run:
$ kubectl -n my-rhdh-project apply -f rhdh-ingress.yaml
Verification
- Wait until the DNS name is responsive, indicating that your Developer Hub instance is ready for use.
4.3.3. Deploy on Amazon EKS using the Helm chart
Deploy Developer Hub on EKS by using the Helm chart for building, testing, and deploying applications.
When you install the Developer Hub Helm chart in Elastic Kubernetes Service (EKS), it orchestrates the deployment of a Developer Hub instance, which provides a robust developer platform within the AWS ecosystem.
Prerequisites
- You have an EKS cluster with AWS Application Load Balancer (ALB) add-on installed. For more information, see Application load balancing on Amazon Developer Hub and Installing the AWS Load Balancer Controller add-on.
- You have configured a domain name for your Developer Hub instance. The domain name can be a hosted zone entry on Route 53 or managed outside of AWS. For more information, see Configuring Amazon Route 53 as your DNS service documentation.
- You have an entry in the AWS Certificate Manager for your preferred domain name. Make sure to keep a record of your Certificate Amazon Resource Name (ARN).
- You have subscribed to Red Hat Container Registry (registry.redhat.io). For more information, see Red Hat Container Registry Authentication.
-
You have set the context to the EKS cluster in your current
kubeconfig. For more information, see Creating or updating akubeconfigfile for an Amazon EKS cluster. -
You have installed
kubectl. For more information, see Installing or updating thekubectltool. - You have installed Helm 3 or the latest. For more information, see Using Helm with Amazon EKS.
- You have a working default storage class, such as the Elastic Block Store (EBS) storage add-on, configured in your EKS cluster.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
Go to your terminal and run the following command to add the Helm chart repository containing the Developer Hub chart to your local Helm registry:
$ helm repo add openshift-helm-charts https://charts.openshift.io/
Create a pull secret using the following command:
$ kubectl create secret docker-registry rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<user_name> \ --docker-password=<password> \ --docker-email=<email>+ Replace
<user_name>with your username,<password>with your password, and<email>with your email address.The created pull secret pulls the Developer Hub images from the Red Hat Container Registry.
Create a file named
values.yamlusing the following template:global: # TODO: Set your application domain name. host: <your Developer Hub domain name> route: enabled: false upstream: service: # NodePort is required for the ALB to route to the Service type: NodePort ingress: enabled: true annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing # TODO: Using an ALB HTTPS Listener requires a certificate for your own domain. Fill in the ARN of your certificate, e.g.: alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:xxx:xxxx:certificate/xxxxxx alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' alb.ingress.kubernetes.io/ssl-redirect: '443' # TODO: Set your application domain name. external-dns.alpha.kubernetes.io/hostname: <your rhdh domain name> backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: # you can assign any random value as fsGroup fsGroup: 2000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true # you can assign any random value as fsGroup fsGroup: 3000 volumePermissions: enabled: true- Update your required domain name, (for example, in Route 53 or your external DNS service) to point to the provisioned IP address. Elastic Kubernetes Service provisions an Application Load Balancer (ALB) with a corresponding IP address.
Run the following command in your terminal to deploy Developer Hub using the latest version of Helm Chart and using the values.yaml file created in the earlier step:
$ helm install rhdh \ openshift-helm-charts/redhat-developer-hub \ [--version 1.10.1] \ --values /path/to/values.yaml
NoteFor the latest chart version, see https://github.com/openshift-helm-charts/charts/tree/main/charts/redhat/redhat/redhat-developer-hub
Verification
Wait until the DNS name is responsive, indicating that your Developer Hub instance is ready for use.
4.3.4. Install on Google Kubernetes Engine (GKE) using the Operator
4.3.4.1. Install on Google Kubernetes Engine (GKE) using the Operator
Install Red Hat Developer Hub on GKE by using the Red Hat Developer Hub Operator with the Operator Lifecycle Manager (OLM) framework for over-the-air updates and catalogs.
To benefit from over-the-air updates and catalogs provided by Operator-based applications distributed with the Operator Lifecycle Manager (OLM) framework, consider installing Red Hat Developer Hub by using the Red Hat Developer Hub Operator distributed in the Red Hat Container Registry.
On GKE, the most notable differences over an OpenShift-based installation are:
- The OLM framework and the Red Hat Container Registry are not built-in.
- The Red Hat Container Registry pull-secret is not managed globally.
- To expose the application, Ingresses replace OpenShift Routes.
For clarity, sections highlight these platform-specific additional steps.
4.3.4.2. Install the Operator using OLM to automate deployments
Install the Red Hat Developer Hub Operator on GKE by using the Operator Lifecycle Manager (OLM) framework.
The Red Hat Container Registry (registry.redhat.io), based on the Operator Lifecycle Manager (OLM) framework, has a distribution of the Red Hat Developer Hub Operator, aimed at managing your Red Hat Developer Hub instance lifecycle.
However, on Google Kubernetes Engine (GKE):
- The Operator Lifecycle Manager (OLM) framework and the Red Hat Container Registry are not built-in.
- The Red Hat Container Registry pull-secret is not managed globally.
Therefore, install the OLM framework, the Red Hat Container Registry, and provision your Red Hat Container Registry pull secret to install Developer Hub Operator.
Prerequisites
-
You have installed the
kubectlCLI on your local environment. - Your system meets the sizing requirements for Red Hat Developer Hub.
- You have installed the Operator Lifecycle Manager (OLM).
Your credentials to the Red Hat Container Registry:
- <redhat_user_name>
- <redhat_password>
- <email>
- You have logged in to your Google account and created a GKE Autopilot or GKE Standard cluster.
Procedure
Connect to your GKE cluster:
$ gcloud container clusters get-credentials <cluster_name> --location=<cluster_location>
- <cluster_name>
- Enter your GKE cluster name.
- <cluster_location>
Enter your GKE cluster location.
Create the
rhdh-operatornamespace to contain the Red Hat Developer Hub Operator:$ kubectl create namespace rhdh-operator
Create a pull secret using your Red Hat credentials to pull the container images from the protected Red Hat Container Registry (registry.redhat.io):
$ kubectl -n rhdh-operator create secret docker-registry rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>Create a catalog source that has the Red Hat operators:
$ cat <<EOF | kubectl -n rhdh-operator apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: redhat-catalog spec: sourceType: grpc image: registry.redhat.io/redhat/redhat-operator-index:v4.21 secrets: - "rhdh-pull-secret" displayName: Red Hat Operators EOF
Create an operator group to manage your operator subscriptions:
$ cat <<EOF | kubectl apply -n rhdh-operator -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: rhdh-operator-group EOF
Create a subscription to install the Red Hat Developer Hub Operator:
$ cat <<EOF | kubectl apply -n rhdh-operator -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: rhdh namespace: rhdh-operator spec: channel: fast installPlanApproval: Automatic name: rhdh source: redhat-catalog sourceNamespace: rhdh-operator startingCSV: rhdh-operator.v1.10.1 EOF
To wait until the Operator deployment finishes to be able to run the next step, run:
$ until kubectl -n rhdh-operator get deployment rhdh-operator &>/dev/null; do echo -n . sleep 3 done echo "RHDH Operator Deployment created"
Include your pull secret name in the Operator deployment manifest, to avoid
ImagePullBackOfferrors:$ kubectl -n rhdh-operator patch deployment \ rhdh-operator --patch '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"rhdh-pull-secret"}]}}}}' \ --type=merge
Verification
Verify the deployment name:
$ kubectl get deployment -n rhdh-operator
4.3.4.3. Provision your custom configuration
Provision custom config maps and secrets on Google Kubernetes Engine (GKE) to configure Red Hat Developer Hub before running the application.
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 Kubernetes CLI ('kubectl'), you have access, with developer permissions, to the OpenShift cluster aimed at containing your Developer Hub instance.
Procedure
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.txtfile, with one secret per line inKEY=valueform.Author your custom
app-config.yamlfile. This is the main Developer Hub configuration file. You need a customapp-config.yamlfile to avoid the Developer Hub installer to revert user edits during upgrades. When your customapp-config.yamlfile 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.yamlfile 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 arebaseUrlin theappandbackendsections, andoriginin thebackend.corssubsection:Configuring the
baseUrlinapp-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:
Author your custom
dynamic-plugins.yamlfile 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.yamlincludes: - 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: falseProvision your custom configuration files to your GKE cluster.
Create the <my-rhdh-project> namespace aimed at containing your Developer Hub instance.
$ oc create namespace my-rhdh-project
Create config maps for your
app-config.yamlanddynamic-plugins.yamlfiles 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.
Provision your
secrets.txtfile to themy-rhdh-secretssecret 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.
4.3.4.4. Provision a pull secret to access the container registry
On Google Kubernetes Engine (GKE), provision your Red Hat Container Registry pull secret in your Red Hat Developer Hub instance namespace because the pull secret is not managed globally.
On Google Kubernetes Engine (GKE), the Red Hat Container Registry pull-secret is not managed globally. Therefore add your pull-secret in your Red Hat Developer Hub instance namespace.
Prerequisites
Your credentials to the Red Hat Container Registry:
- <redhat_user_name>
- <redhat_password>
- <email>
-
You created the
{my-rhdh-project}namespace on GKE to host your Developer Hub instance.
Procedure
Create a pull secret using your Red Hat credentials to pull the container images from the protected Red Hat Container Registry (registry.redhat.io):
$ kubectl -n {my-rhdh-namespace} create secret docker-registry my-rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>To enable pulling Developer Hub images from the Red Hat Container Registry, add the image pull secret in the default service account within the namespace where the Developer Hub instance is being deployed:
$ kubectl patch serviceaccount default \ -p '{"imagePullSecrets": [{"name": "my-rhdh-pull-secret"}]}' \ -n {my-rhdh-namespace}
4.3.4.5. Deploy a custom configuration using an Operator
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 Kubernetes CLI ('kubectl'), you have access, with developer permissions, to the GKE 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
Author your Backstage CR in a
my-rhdh-custom-resource.yamlfile to use your custom config maps and secrets.Minimal
my-rhdh-custom-resource.yamlcustom 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: truemy-rhdh-custom-resource.yamlcustom 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-configconfig map:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-configMount files in the
my-rhdh-app-configandrbac-policiesconfig maps:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-config - name: rbac-policiesspec.application.extraEnvs.envsOptionally, enter your additional environment variables that are not secrets, such as your proxy environment variables.
Inject your
HTTP_PROXY,HTTPS_PROXYandNO_PROXYenvironment 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.secretsEnter 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-secretssecrets:spec: application: extraEnvs: secrets: - name: <my_product_secrets> - name: my-rhdh-database-secretsNote<my_product_secrets>is your preferred Developer Hub secret name, specifying the identifier for your secret configuration within Developer Hub.spec.application.extraFiles.secretsEnter your certificates files secret name and files list.
Mount the
postgres-crt.pem,postgres-ca.pem, andpostgres-key.keyfiles contained in themy-rhdh-database-certificates-secretssecret:spec: application: extraFiles: mountPath: /opt/app-root/src secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem, postgres-ca.pem, postgres-key.keyspec.database.enableLocalDbEnable or disable the local PostgreSQL database.
Disable the local PostgreSQL database generation to use an external postgreSQL database:
spec: database: enableLocalDb: falseOn a development environment, use the local PostgreSQL database:
spec: database: enableLocalDb: truespec.deployment- Optionally, enter your deployment configuration.
Apply your Backstage CR to start or update your Developer Hub instance:
$ oc apply --filename=my-rhdh-custom-resource.yaml --namespace=my-rhdh-project
4.3.4.6. Expose your Operator instance using an Ingress resource
On Google Kubernetes Engine (GKE), Kubernetes ingresses replace OpenShift Container Platform routes. The Red Hat Developer Hub Operator does not create ingresses. Therefore, to access your Developer Hub instance via a domain name, create the required ingresses on GKE and point your domain name to it.
Prerequisites
- You have installed Red Hat Developer Hub by using the Red Hat Developer Hub Operator.
- You have configured a domain name for your Developer Hub instance.
- You have reserved a static external Premium IPv4 Global IP address that is not attached to any virtual machine (VM). For more information see Reserve a new static external IP address
You have configured the DNS records for your domain name to point to the IP address that you reserved.
NoteYou need to create an
Arecord with the value equal to the IP address. This process can take up to one hour to propagate.
Procedure
Create a Google-managed certificate manifest file, named
managed-certificate.yaml:apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: my-rhdh-certificate-name spec: domains: - <my_developer_hub_domain>For more information about setting up a Google-managed certificate, see Setting up a Google-managed certificate.
Deploy the managed certificate:
$ kubectl -n my-rhdh-project apply -f managed-certificate.yaml
Create a front-end config manifest file, named
frontend-config.yaml, to set a policy for redirecting to HTTPS.apiVersion: networking.gke.io/v1beta1 kind: FrontendConfig metadata: name: my-ingress_security_config spec: sslPolicy: gke-ingress-ssl-policy-https redirectToHttps: enabled: trueFor more information about setting a policy to redirect to HTTPS, see HTTP to HTTPS redirects.
Deploy the front-end config:
$ kubectl -n my-rhdh-project apply -f frontend-config.yaml
Create an ingress manifest file, named
rhdh-ingress.yaml, specifying your Developer Hub service name, and using your managed certificate and your front-end config:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-rhdh-ingress annotations: kubernetes.io/ingress.class: "gce" kubernetes.io/ingress.global-static-ip-name: <ADDRESS_NAME> networking.gke.io/managed-certificates: my-rhdh-certificate-name networking.gke.io/v1beta1.FrontendConfig: my-ingress_security_config spec: ingressClassName: gce rules: - host: <my_developer_hub_domain> http: paths: - path: / pathType: Prefix backend: service: name: my-rhdh-custom-resource port: name: http-backendDeploy the ingress:
$ kubectl -n my-rhdh-project apply -f rhdh-ingress.yaml
Verification
-
Wait for the system to provision the
ManagedCertificate. This process can take a couple of hours. -
Access RHDH with
https://<my_developer_hub_domain>.
Additional resources
4.3.5. Deploy on GKE using the Helm chart
Deploy Developer Hub on GKE by using the Helm chart for building, testing, and deploying applications.
When you install the Developer Hub Helm chart in Google Kubernetes Engine (GKE), it orchestrates the deployment of a Developer Hub instance, which provides a robust developer platform within the GKE ecosystem.
Prerequisites
- You have subscribed to the Red Hat Container Registry (registry.redhat.io). For more information, see Red Hat Container Registry Authentication.
-
You have installed
kubectl. For more information, see Install thekubectltool. -
You have installed the Google Cloud CLI. For more information, see Install the
gcloudCLI. - You have logged in to your Google account and created a GKE Autopilot or GKE Standard cluster.
- You have configured a domain name for your Developer Hub instance.
- You have reserved a static external Premium IPv4 Global IP address that is not attached to any VM. For more information see Reserve a new static external IP address
- You have configured the DNS records for your domain name to point to the IP address that you reserved.
Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
NoteYou need to create an
Arecord with the value equal to the IP address. This process can take up to one hour to propagate.- You have installed Helm 3 or the latest. For more information, see Installing Helm.
Procedure
Go to your terminal and run the following command to add the Helm chart repository containing the Developer Hub chart to your local Helm registry:
helm repo add openshift-helm-charts https://charts.openshift.io/
Create a pull secret using the following command:
$ kubectl -n <your_namespace> create secret docker-registry rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<user_name> \ --docker-password=<password> \ --docker-email=<email>+ Replace
<your_namespace>with your GKE namespace,<user_name>with your username,<password>with your password, and<email>with your email address.The created pull secret pulls the Developer Hub images from the Red Hat Container Registry.
Set up a Google-managed certificate by creating a
ManagedCertificateobject that you must attach to the ingress:apiVersion: networking.gke.io/v1 kind: ManagedCertificate metadata: name: <rhdh_certificate_name> spec: domains: - <rhdh_domain_name>For more information about setting up a Google-managed certificate, see Setting up a Google-managed certificate.
Create a
FrontendConfigobject to set a policy for redirecting to HTTPS. You must attach this policy to the ingress:apiVersion: networking.gke.io/v1beta1 kind: FrontendConfig metadata: name: <ingress_security_config> spec: sslPolicy: gke-ingress-ssl-policy-https redirectToHttps: enabled: trueFor more information about setting a policy to redirect to HTTPS, see HTTP to HTTPS redirects.
Create a file named
values.yamlusing the following template:Example
values.yamlfile:global: host: <rhdh_domain_name> route: enabled: false upstream: service: type: NodePort ingress: enabled: true annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.global-static-ip-name: <ADDRESS_NAME> networking.gke.io/managed-certificates: <rhdh_certificate_name> networking.gke.io/v1beta1.FrontendConfig: <ingress_security_config> className: gce backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: fsGroup: 2000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true fsGroup: 3000 volumePermissions: enabled: trueRun the following command in your terminal to deploy Developer Hub using the latest version of Helm Chart and using the
values.yamlfile:$ helm -n <your_namespace> install -f values.yaml <your_deploy_name> \ openshift-helm-charts/redhat-developer-hub \ --version 1.10.1
For the latest Helm Chart version, see this Helm Charts repository.
Verification
Confirm that the deployment is complete.
$ kubectl get deploy <your_deploy_name>-developer-hub -n <your_namespace>
Verify that the deployment created the service and ingress:
$ kubectl get service -n <your_namespace> $ kubectl get ingress -n <your_namespace>
NoteWait for the system to provision the
ManagedCertificate. This process can take a couple of hours.-
Access RHDH with
https://<my_developer_hub_domain>. To upgrade your deployment, use the following command:
$ helm -n <your_namespace> upgrade -f values.yaml <your_deploy_name> openshift-helm-charts/redhat-developer-hub --version <UPGRADE_CHART_VERSION>
To delete your deployment, use the following command:
$ helm -n <your_namespace> delete <your_deploy_name>
4.3.6. Install on Microsoft Azure Kubernetes Service (AKS) using the Operator
4.3.6.1. Install on Microsoft Azure Kubernetes Service (AKS) using the Operator
Install Red Hat Developer Hub on AKS by using the Red Hat Developer Hub Operator with the Operator Lifecycle Manager (OLM) framework for over-the-air updates and catalogs.
To benefit from over-the-air updates and catalogs provided by Operator-based applications distributed with the Operator Lifecycle Manager (OLM) framework, consider installing Red Hat Developer Hub by using the Red Hat Developer Hub Operator distributed in the Red Hat Container Registry.
On AKS, the most notable differences over an OpenShift-based installation are:
- The OLM framework and the Red Hat Container Registry are not built-in.
- The Red Hat Container Registry pull-secret is not managed globally.
- To expose the application, Ingresses replace OpenShift Routes.
For clarity, sections highlight these platform-specific additional steps.
4.3.6.2. Install the Operator using OLM to automate deployments
Install the Red Hat Developer Hub Operator on AKS by using the Operator Lifecycle Manager (OLM) framework.
The Red Hat Container Registry (registry.redhat.io), based on the Operator Lifecycle Manager (OLM) framework, has a distribution of the Red Hat Developer Hub Operator, aimed at managing your Red Hat Developer Hub instance lifecycle.
However, on Microsoft Azure Kubernetes Service (AKS):
- The Operator Lifecycle Manager (OLM) framework and the Red Hat Container Registry are not built-in.
- The Red Hat Container Registry pull-secret is not managed globally.
Therefore, install the OLM framework, the Red Hat Container Registry, and provision your Red Hat Container Registry pull secret to install Developer Hub Operator.
Prerequisites
-
You have installed the
kubectlCLI on your local environment. - Your system meets the sizing requirements for Red Hat Developer Hub.
- You have installed the Operator Lifecycle Manager (OLM).
Your credentials to the Red Hat Container Registry:
- <redhat_user_name>
- <redhat_password>
- <email>
Procedure
Create the
rhdh-operatornamespace to contain the Red Hat Developer Hub Operator:$ kubectl create namespace rhdh-operator
Create a pull secret using your Red Hat credentials to pull the container images from the protected Red Hat Container Registry (registry.redhat.io):
$ kubectl -n rhdh-operator create secret docker-registry rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>Create a catalog source that has the Red Hat operators:
$ cat <<EOF | kubectl -n rhdh-operator apply -f - apiVersion: operators.coreos.com/v1alpha1 kind: CatalogSource metadata: name: redhat-catalog spec: sourceType: grpc image: registry.redhat.io/redhat/redhat-operator-index:v4.21 secrets: - "rhdh-pull-secret" displayName: Red Hat Operators EOF
Create an operator group to manage your operator subscriptions:
$ cat <<EOF | kubectl apply -n rhdh-operator -f - apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: rhdh-operator-group EOF
Create a subscription to install the Red Hat Developer Hub Operator:
$ cat <<EOF | kubectl apply -n rhdh-operator -f - apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: rhdh namespace: rhdh-operator spec: channel: fast installPlanApproval: Automatic name: rhdh source: redhat-catalog sourceNamespace: rhdh-operator startingCSV: rhdh-operator.v1.10.1 EOF
To wait until the Operator deployment finishes to be able to run the next step, run:
$ until kubectl -n rhdh-operator get deployment rhdh-operator &>/dev/null; do echo -n . sleep 3 done echo "RHDH Operator Deployment created"
Include your pull secret name in the Operator deployment manifest, to avoid
ImagePullBackOfferrors:$ kubectl -n rhdh-operator patch deployment \ rhdh-operator --patch '{"spec":{"template":{"spec":{"imagePullSecrets":[{"name":"rhdh-pull-secret"}]}}}}' \ --type=merge
Verification
Verify the deployment name:
$ kubectl get deployment -n rhdh-operator
4.3.6.3. Provision your custom configuration
Provision custom config maps and secrets on Microsoft Azure Kubernetes Service (AKS) to configure Red Hat Developer Hub before running the application.
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 Kubernetes CLI ('kubectl'), you have access, with developer permissions, to the OpenShift cluster aimed at containing your Developer Hub instance.
Procedure
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.txtfile, with one secret per line inKEY=valueform.Author your custom
app-config.yamlfile. This is the main Developer Hub configuration file. You need a customapp-config.yamlfile to avoid the Developer Hub installer to revert user edits during upgrades. When your customapp-config.yamlfile 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.yamlfile 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 arebaseUrlin theappandbackendsections, andoriginin thebackend.corssubsection:Configuring the
baseUrlinapp-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:
Author your custom
dynamic-plugins.yamlfile 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.yamlincludes: - 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: falseProvision your custom configuration files to your AKS cluster.
Create the <my-rhdh-project> namespace aimed at containing your Developer Hub instance.
$ oc create namespace my-rhdh-project
Create config maps for your
app-config.yamlanddynamic-plugins.yamlfiles 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.
Provision your
secrets.txtfile to themy-rhdh-secretssecret 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.
4.3.6.4. Provision a pull secret to access the container registry
On Microsoft Azure Kubernetes Service (AKS), provision your Red Hat Container Registry pull secret in your Red Hat Developer Hub instance namespace because the pull secret is not managed globally.
On Microsoft Azure Kubernetes Service (AKS), the Red Hat Container Registry pull-secret is not managed globally. Therefore add your pull-secret in your Red Hat Developer Hub instance namespace.
Prerequisites
Your credentials to the Red Hat Container Registry:
- <redhat_user_name>
- <redhat_password>
- <email>
-
You created the
{my-rhdh-project}namespace on AKS to host your Developer Hub instance.
Procedure
Create a pull secret using your Red Hat credentials to pull the container images from the protected Red Hat Container Registry (registry.redhat.io):
$ kubectl -n {my-rhdh-namespace} create secret docker-registry my-rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>To enable pulling Developer Hub images from the Red Hat Container Registry, add the image pull secret in the default service account within the namespace where the Developer Hub instance is being deployed:
$ kubectl patch serviceaccount default \ -p '{"imagePullSecrets": [{"name": "my-rhdh-pull-secret"}]}' \ -n {my-rhdh-namespace}
4.3.6.5. Deploy a custom configuration using an Operator
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 Kubernetes CLI ('kubectl'), you have access, with developer permissions, to the AKS 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
Author your Backstage CR in a
my-rhdh-custom-resource.yamlfile to use your custom config maps and secrets.Minimal
my-rhdh-custom-resource.yamlcustom 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: truemy-rhdh-custom-resource.yamlcustom 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-configconfig map:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-configMount files in the
my-rhdh-app-configandrbac-policiesconfig maps:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-config - name: rbac-policiesspec.application.extraEnvs.envsOptionally, enter your additional environment variables that are not secrets, such as your proxy environment variables.
Inject your
HTTP_PROXY,HTTPS_PROXYandNO_PROXYenvironment 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.secretsEnter 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-secretssecrets:spec: application: extraEnvs: secrets: - name: <my_product_secrets> - name: my-rhdh-database-secretsNote<my_product_secrets>is your preferred Developer Hub secret name, specifying the identifier for your secret configuration within Developer Hub.spec.application.extraFiles.secretsEnter your certificates files secret name and files list.
Mount the
postgres-crt.pem,postgres-ca.pem, andpostgres-key.keyfiles contained in themy-rhdh-database-certificates-secretssecret:spec: application: extraFiles: mountPath: /opt/app-root/src secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem, postgres-ca.pem, postgres-key.keyspec.database.enableLocalDbEnable or disable the local PostgreSQL database.
Disable the local PostgreSQL database generation to use an external postgreSQL database:
spec: database: enableLocalDb: falseOn a development environment, use the local PostgreSQL database:
spec: database: enableLocalDb: truespec.deployment- Optionally, enter your deployment configuration.
Apply your Backstage CR to start or update your Developer Hub instance:
$ oc apply --filename=my-rhdh-custom-resource.yaml --namespace=my-rhdh-project
4.3.6.6. Expose your Operator instance using an Ingress resource
On Microsoft Azure Kubernetes Service (AKS), Kubernetes ingresses replace OpenShift Container Platform routes. The Red Hat Developer Hub Operator does not create ingresses. Therefore, to access your Developer Hub instance via a domain name, create the required ingresses on AKS and point your domain name to it.
Prerequisites
- You have installed Red Hat Developer Hub by using the Red Hat Developer Hub Operator.
Procedure
Create an Ingress manifest file, named
rhdh-ingress.yaml, specifying your Developer Hub service name as follows:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-rhdh-ingress namespace: my-rhdh-project spec: ingressClassName: webapprouting.kubernetes.azure.com rules: - http: paths: - path: / pathType: Prefix backend: service: name: my-rhdh-custom-resource port: name: http-backendTo deploy the created Ingress, run the following command:
$ kubectl -n my-rhdh-project apply -f rhdh-ingress.yaml
Verification
-
Access the deployed Developer Hub using the URL:
https://<app_address>, where <app_address> is the Ingress address obtained earlier (for example,https://108.141.70.228).
4.3.7. Deploy on AKS using the Helm chart
Deploy Developer Hub on AKS by using the Helm chart for building, testing, and deploying applications.
You can deploy your Developer Hub application on Azure Kubernetes Service (AKS) to access a comprehensive solution for building, testing, and deploying applications.
When deploying on AKS, be aware of the following platform-specific considerations:
- Permissions
-
Developer Hub containers might meet permission-related errors, such as
Permission deniedwhen attempting certain operations. Address this error by adjusting thefsGroupin thePodSpec.securityContext. - Ingress configuration
Configuring ingress is essential for accessing the installed Developer Hub instance. You must enable the Routing add-on, an NGINX-based Ingress Controller, using the following command:
$ az aks approuting enable --resource-group <your_ResourceGroup> --name <your_ClusterName>
TipYou might need to install the Azure CLI extension
aks-preview. If the extension is not installed automatically, you might need to install it manually using the following command:$ az extension add --upgrade -n aks-preview --allow-preview true
NoteAfter you install the Ingress Controller, the system deploys the
app-routing-systemnamespace with the Ingress Controller in your cluster. Note the address of your Developer Hub application from the installed Ingress Controller (for example, 108.141.70.228) for later access to the Developer Hub application, later referenced as<app_address>.$ kubectl get svc nginx --namespace app-routing-system -o jsonpath='{.status.loadBalancer.ingress[0].ip}'- Namespace management
You can create a dedicated namespace for Developer Hub deployment by using the following command:
$ kubectl create namespace <your_namespace>
Prerequisites
- You have a Microsoft Azure account with active subscription.
- You have installed the Azure CLI.
-
You have installed the
kubectlCLI. -
You have logged into your cluster using
kubectl, and havedeveloperoradminpermissions. - You have installed Helm 3 or the latest.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
Log in to AKS by running the following command:
$ az login [--tenant=<optional_directory_name>]
Create a resource group by running the following command:
$ az group create --name <resource_group_name> --location <location>
TipYou can list available regions by running the following command:
$ az account list-locations -o table
Create an AKS cluster by running the following command:
$ az aks create \ --resource-group <resource_group_name> \ --name <cluster_name> \ --enable-managed-identity \ --generate-ssh-keys
You can see
--helpfor additional options.Connect to your cluster by running the following command:
$ az aks get-credentials --resource-group <resource_group_name> --name <cluster_name>
The earlier command configures the Kubernetes client and sets the current context in the
kubeconfigto point to your AKS cluster.Open terminal and run the following command to add the Helm chart repository:
$ helm repo add openshift-helm-charts https://charts.openshift.io/
Create and activate the <my-rhdh-project> namespace:
DEPLOYMENT_NAME=<redhat-developer-hub> NAMESPACE=<rhdh> kubectl create namespace ${NAMESPACE} kubectl config set-context --current --namespace=${NAMESPACE}Create a pull secret to pull the Developer Hub images from the Red Hat Container Registry by running the following command:
$ kubectl -n $NAMESPACE create secret docker-registry rhdh-pull-secret \ --docker-server=registry.redhat.io \ --docker-username=<redhat_user_name> \ --docker-password=<redhat_password> \ --docker-email=<email>Create a file named
values.yamlusing the following template:global: host: <app_address> route: enabled: false upstream: ingress: enabled: true className: webapprouting.kubernetes.azure.com host: backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: fsGroup: 3000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true fsGroup: 3000 volumePermissions: enabled: trueTo install Developer Hub by using the Helm chart, run the following command:
$ helm -n $NAMESPACE install -f values.yaml $DEPLOYMENT_NAME openshift-helm-charts/redhat-developer-hub --version 1.10.1
Verify the deployment status:
$ kubectl get deploy $DEPLOYMENT_NAME -n $NAMESPACE
Configure your Developer Hub Helm chart instance with the Developer Hub database password and router base URL values from your cluster:
PASSWORD=$(kubectl get secret redhat-developer-hub-postgresql -o jsonpath="{.data.password}" | base64 -d) CLUSTER_ROUTER_BASE=$(kubectl get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/^[^.]*\.//') helm upgrade $DEPLOYMENT_NAME -i "https://github.com/openshift-helm-charts/charts/releases/download/redhat-redhat-developer-hub-1.10.1/redhat-developer-hub-1.10.1.tgz" \ --set global.clusterRouterBase="$CLUSTER_ROUTER_BASE" \ --set global.postgresql.auth.password="$PASSWORD"Display the running Developer Hub instance URL, by running the following command:
$ echo "https://$DEPLOYMENT_NAME-$NAMESPACE.$CLUSTER_ROUTER_BASE"
Verification
- Open the running Developer Hub instance URL in your browser to use Developer Hub.
4.3.8. Install on OpenShift Dedicated using the Operator
Deploy Developer Hub on OpenShift Dedicated on Google Cloud using the Operator for centralized lifecycle management and automated updates.
Prerequisites
- You have a valid Google Cloud account.
- Your OpenShift Dedicated cluster is running on Google Cloud. For more information, seeCreating a cluster on GCP in Red Hat OpenShift Dedicated documentation.
- You have administrator access to OpenShift Dedicated cluster and Google Cloud project.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
- In the OpenShift Container Platform web console menu, go to Operators > OperatorHub.
- In the Filter by keyword field, enter Developer Hub and click the Red Hat Developer Hub Operator card.
- On the Red Hat Developer Hub Operator page, click Install.
- After the installation completes, navigate to Installed Operators and select Red Hat Developer Hub Operator.
Provision your custom configuration:
apiVersion: v1 kind: ConfigMap metadata: name: app-config-rhdh data: "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>__You must create a config map named
app-config-rhdhand a Kubernetes Secret containing theBACKEND_SECRET. These resources are used by the Developer Hub instance for authentication and application settings.For further steps, see Provisioning your custom Red Hat Developer Hub configuration.
Create a config map named
app-config-rhdhthat includes yourapp-config.yamlas shown:apiVersion: v1 kind: ConfigMap metadata: name: app-config-rhdh data: "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>__Create a secret named
my-rhdh-secretsand add a key namedBACKEND_SECRETwith aBase64-encodedstring as value:apiVersion: v1 kind: Secret metadata: name: my-rhdh-secrets stringData: # TODO: Add the necessary auth secrets for service-to-service auth setup BACKEND_SECRET: "xxx" # Replace with your
Base64-encodedsecret- Return to the Developer Hub Operator page and click Create New Instance.
- Specify the name and target namespace for the Developer Hub deployment.
- Configure required options such as Git integration, secrets, and user permissions.
- Review the configuration, select deployment options, and click Create.
Verification
- To access the Developer Hub, navigate to the Developer Hub URL provided in the OpenShift Container Platform web console.
Additional resources
4.3.9. Deploy on OpenShift Dedicated using the Helm chart
Deploy Developer Hub on OpenShift Dedicated on Google Cloud using Helm for flexible, customizable configuration management.
Prerequisites
- You have a valid Google Cloud account.
- Your OpenShift Dedicated cluster is running on Google Cloud. For more information, seeCreating a cluster on Google Cloud in Red Hat OpenShift Dedicated documentation.
- You have installed Helm 3 or the latest.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
- From the Developer perspective on the Developer Hub web console, click +Add.
- From the Developer Catalog panel, click Helm Chart.
- In the Filter by keyword box, enter Developer Hub and click the Red Hat Developer Hub card.
- From the Red Hat Developer Hub page, click Create.
-
From your cluster, copy the OpenShift Container Platform router host (for example:
apps.<clusterName>.com). Select the radio button to configure the Developer Hub instance with either the form view or YAML view.
ImportantBefore deploying Developer Hub using the Helm chart, you must define custom configuration settings such as the public
baseUrlfor your instance. Without settingbaseUrl, the application cannot function correctly. You can define this configuration either through the Form view or the YAML view in the Helm install wizard.To configure the
baseUrl, set the following values in your Helm configuration:global: app: baseUrl: https://<your-developer-hub-link> backend: baseUrl: https://<your-developer-hub-link> cors: origin: https://<your-developer-hub-link>You can also define additional secrets, plugins, and advanced configuration in your
values.yamlfile. For full instructions, see: Provisioning your custom Red Hat Developer Hub configuration.The Form view is selected by default.
Using Form view
- To configure the instance with the Form view, go to Root Schema → global → Enable service authentication within Backstage instance and paste your OpenShift Container Platform router host into the field on the form.
Using YAML view
To configure the instance with the YAML view, paste your OpenShift Container Platform router hostname in the
global.clusterRouterBaseparameter value as shown in the following example:global: auth: backend: enabled: true clusterRouterBase: apps.<clusterName>.com # other Red Hat Developer Hub Helm Chart configurations
- Edit the other values if needed, then click Create and wait for the database and Developer Hub to start.
Verification
- To access Developer Hub, click the Open URL icon.
Additional resources
4.4. Install in an air-gapped environment
4.4.1. Install in an air-gapped environment
Install Red Hat Developer Hub in a restricted network environment by following a clear installation path that accounts for fully or partially disconnected infrastructure, so you can get Developer Hub running securely without requiring direct internet access.
4.4.2. Isolated network deployments for air-gapped environments
An air-gapped environment ensures security by physically segregating systems from external networks.
Also known as an air-gapped network or isolated network, this isolation prevents unauthorized access, data transfer, or communication between the air-gapped system and external sources.
You can install the Red Hat Developer Hub in an air-gapped environment to ensure security and meet specific regulatory requirements.
Air-gapped environments fall into two types:
- Fully disconnected environment
- In environments without internet access, a fully disconnected installation ensures that Red Hat Developer Hub can run reliably without external dependencies. This method requires mirroring images to disk and transferring them manually to the air-gapped environment.
- Partially disconnected environment
-
In a partially disconnected environment, the cluster cannot access external registries, for example,
registry.redhat.io, but it can access an internal mirror registry. This method requires direct access to an internal mirror registry from the cluster.
4.4.3. Install in an air-gapped environment using the Operator
4.4.3.1. Install in an air-gapped environment using the Operator
Install Red Hat Developer Hub in fully or partially disconnected environments by using the Operator.
4.4.3.2. Mirror Operator images to deploy in fully disconnected networks
Mirror Operator images to disk and transfer them to a fully disconnected environment without internet access.
In environments without internet access (whether for security, compliance, or operational reasons), a fully disconnected installation ensures that Red Hat Developer Hub can run reliably without external dependencies.
If your network has access to the registry through a bastion host, you can use the helper script to install Red Hat Developer Hub.
Prerequisites
-
You have installed GNU
sed, GNUtar1.35 or later,jq1.7 or later, theoc-mirrortool (recommended on OpenShift Container Platform), theopmCLI tool, Podman 5.3 or later, Skopeo 1.20 or later, theumociCLI tool, andyq4.44 or later on your workstation. -
You have an active
oc registry,podman, orskopeosession to the Red Hat Container Registry (registry.redhat.io). - Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
Download the mirroring script to disk by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/prepare-restricted-environment.sh
Run the mirroring script by using the
bashcommand with the appropriate set of options:$ bash prepare-restricted-environment.sh --filter-versions "1.10" --to-dir <my_pulled_image_location> [--use-oc-mirror true]where:
--to-dir <my_pulled_image_location>-
Enter the absolute path to a directory where you want to pull all of the necessary images, for example,
/home/user/rhdh-operator-mirror-dir. --use-oc-mirror true(Recommended on OpenShift Container Platform) Use the
oc-mirrorOpenShift Container Platform CLI plugin to mirror images.NoteThe script can take several minutes to complete as it copies many images to the mirror registry.
-
Transfer the directory specified by the
--to-diroption to your disconnected environment. From a machine in your disconnected environment that has access to both the cluster and the target mirror registry, run the mirroring script by using the
bashcommand with the appropriate set of options:$ bash <my_pulled_image_location>/install.sh --from-dir <my_pulled_image_location> [--to-registry <my.registry.example.com>] [--use-oc-mirror true]
where:
<my_pulled_image_location>/install.sh- Enter the downloaded installation script and the absolute path to the directory where you stored it on your system.
--from-dir <my_pulled_image_location>- Enter the directory where you want to pull all of the necessary images.
--to-registry- (Optional) Enter the URL for the target mirror registry where you want to mirror the images.
--use-oc-mirror trueRecommended on OpenShift Container Platform: Use the
oc mirrorOpenShift Container Platform CLI plugin to mirror images.ImportantIf you used
oc mirrorto mirror the images to disk, you must also useoc mirrorto mirror the images from disk due to the folder layout thatoc mirroruses.NoteThe script can take several minutes to complete as it automatically installs the Red Hat Developer Hub Operator.
If deploying on OpenShift Container Platform, update the cluster pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ oc get secret pull-secret -n openshift-config -o json | \ jq -r '.data.".dockerconfigjson"' | base64 -d | \ jq --arg registry "<mirror_registry>" \ --arg auth "$(echo -n '<username>:<password>' | base64)" \ '.auths[$registry] = {"auth": $auth}' | \ oc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjson=/dev/stdinwhere:
<mirror_registry>-
Enter the hostname and port of your mirror registry, for example,
registry.example.com:5000. <username>:<password>Enter the credentials for authenticating to your mirror registry.
NoteWait for all machine config pools to finish updating before proceeding.
If deploying on a supported Kubernetes platform, create a pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ kubectl create secret docker-registry rhdh-pull-secret \ --docker-server=<mirror_registry> \ --docker-username=<username> \ --docker-password=<password> \ --namespace=<target_namespace> $ kubectl patch serviceaccount default \ --namespace=<target_namespace> \ --type='json' \ --patch='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"rhdh-pull-secret"}}]'where:
<mirror_registry>- Enter the hostname and port of your mirror registry.
<username>- Enter the username for authenticating to your mirror registry.
<password>- Enter the password for authenticating to your mirror registry.
<target_namespace>-
Enter the namespace where the Operator will deploy Red Hat Developer Hub instances, for example,
rhdh.
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Export the plugin catalog index and all referenced plugin OCI artifacts to disk by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-dir <my_plugin_mirror_dir>where:
<my_plugin_mirror_dir>Enter the absolute path to a directory where you want to export the plugin artifacts, for example,
/home/user/rhdh-plugins-mirror.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
-
Transfer the directory specified by the
--to-diroption to your disconnected environment. From a machine in your disconnected environment that has access to the target mirror registry, import the plugin artifacts by running the following command:
$ bash mirror-plugins.sh \ --from-dir <my_plugin_mirror_dir> \ --to-registry <target_registry>
where:
<my_plugin_mirror_dir>- Enter the path to the directory containing the exported plugin artifacts.
<target_registry>-
Enter the URL of the target mirror registry, for example,
registry.example.com.
Create a config map containing a
registries.conffile that redirects theinstall-dynamic-pluginsinit container to your mirror registry:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-plugin-mirror-conf data: rhdh-registries.conf: | [[registry]] prefix = "registry.access.redhat.com/rhdh" location = "<target_registry>/rhdh" [[registry]] prefix = "quay.io/rhdh" location = "<target_registry>/rhdh"where:
<target_registry>-
Enter the URL of your mirror registry, for example,
registry.example.com.
Mount the config map in the
install-dynamic-pluginsinit container by adding the following to yourBackstageCR:spec: application: extraFiles: configMaps: - name: rhdh-plugin-mirror-conf key: rhdh-registries.conf mountPath: /etc/containers/registries.conf.d containers: - install-dynamic-pluginsNoteCluster-level mirroring resources such as
ImageDigestMirrorSetorImageContentSourcePolicydo not apply to theinstall-dynamic-pluginsinit container because it usesskopeodirectly to pull plugin artifacts.Optional: To enforce signature verification in production environments, create a
policy.jsonconfig map and mount it in theinstall-dynamic-pluginsinit container:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-mirror-policy data: policy.json: | { "transports": { "docker": { "<target_registry>/<namespace>": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "<path_to_gpg_key>" } ] } } }Then add the following to the
extraFiles.configMapslist in yourBackstageCR:- name: rhdh-mirror-policy key: policy.json mountPath: /etc/containers containers: - install-dynamic-pluginsFor a full example CR showing how to configure plugin mirroring when using the Operator, see plugin-mirroring.yaml.
Verification
- If you are using Red Hat OpenShift Container Platform, the Red Hat Developer Hub Operator is in the Installed Operators list in the web console.
If you are using a supported Kubernetes platform, you can check the list of pods running in the
rhdh-operatornamespace by running the following command in your terminal:kubectl -n rhdh-operator get pods
Next steps
Use the Operator to create a Red Hat Developer Hub instance on a supported platform. For more information, see the following documentation for the platform that you want to use:
4.4.3.3. Mirror Operator images to local registries for partially disconnected networks
Mirror Operator images directly to a target registry in a partially disconnected environment.
On an OpenShift Container Platform cluster operating on a restricted network, public resources are not available. However, deploying the Red Hat Developer Hub Operator and running Developer Hub requires the following public resources:
- Operator images (bundle, operator, catalog)
- Operands images (RHDH, PostgreSQL)
To make these resources available, replace them with their equal resources in a mirror registry accessible to your cluster.
You can use a helper script that mirrors the necessary images and provides the necessary configuration to ensure the system uses those images when installing the Red Hat Developer Hub Operator and creating Developer Hub instances. This script requires a target mirror registry. You likely have a target mirror registry if your cluster is already operating on a disconnected network. If you do not already have a target registry, and if you have an OpenShift Container Platform cluster, you might want to expose and use the internal cluster registry.
When connected to a OpenShift Container Platform cluster, the helper script detects it and automatically exposes the cluster registry. If connected to a Kubernetes cluster, you can manually specify the target registry to mirror the images.
Prerequisites
-
You have installed GNU
sed, GNUtar1.35 or later,jq1.7 or later, theopmCLI tool, Podman 5.3 or later, Skopeo 1.20 or later, theumociCLI tool, andyq4.44 or later on your workstation. -
You have an active
oc registry,podman, orskopeosession to the Red Hat Container Registry (registry.redhat.io). -
You have an active
Skopeosession with administrative access to the target mirror registry. If you are using an OpenShift Container Platform cluster, you have the following prerequisites:
-
Recommended: You have installed the
oc-mirrortool, with a version corresponding to the version of your OpenShift Container Platform cluster.
-
Recommended: You have installed the
If you are using a supported Kubernetes cluster, you have the following prerequisites:
- You have installed the Operator Lifecycle Manager (OLM) on the disconnected cluster.
- You have a mirror registry that is reachable from the disconnected cluster.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
- In your terminal, navigate to the directory where you want to save the mirroring script.
Download the mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/prepare-restricted-environment.sh
Run the mirroring script by using the
bashcommand with the appropriate set of options:$ bash prepare-restricted-environment.sh \ --filter-versions "1.10" \ [--to-registry <my.registry.example.com>] \ [--use-oc-mirror true]where:
--to-registry _<my.registry.example.com>- Enter the URL for the target mirror registry where you want to mirror the images.
--use-oc-mirror trueOptional: Use the
oc mirrorOpenShift Container Platform CLI plugin to mirror images.NoteThe script can take several minutes to complete as it copies many images to the mirror registry.
If deploying on OpenShift Container Platform, update the cluster pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ oc get secret pull-secret -n openshift-config -o json | \ jq -r '.data.".dockerconfigjson"' | base64 -d | \ jq --arg registry "<mirror_registry>" \ --arg auth "$(echo -n '<username>:<password>' | base64)" \ '.auths[$registry] = {"auth": $auth}' | \ oc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjson=/dev/stdinwhere:
<mirror_registry>-
Enter the hostname and port of your mirror registry, for example,
registry.example.com:5000. <username>:<password>Enter the credentials for authenticating to your mirror registry.
NoteWait for all machine config pools to finish updating before proceeding.
If deploying on a supported Kubernetes platform, create a pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ kubectl create secret docker-registry rhdh-pull-secret \ --docker-server=<mirror_registry> \ --docker-username=<username> \ --docker-password=<password> \ --namespace=<target_namespace> $ kubectl patch serviceaccount default \ --namespace=<target_namespace> \ --type='json' \ --patch='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"rhdh-pull-secret"}}]'where:
<mirror_registry>- Enter the hostname and port of your mirror registry.
<username>- Enter the username for authenticating to your mirror registry.
<password>- Enter the password for authenticating to your mirror registry.
<target_namespace>-
Enter the namespace where the Operator will deploy Red Hat Developer Hub instances, for example,
rhdh.
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Mirror the plugin catalog index and all referenced plugin OCI artifacts to your target registry by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-registry <target_registry>where:
<target_registry>Enter the URL of the target mirror registry, such as,
registry.example.com.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
Create a config map containing a
registries.conffile that redirects theinstall-dynamic-pluginsinit container to your mirror registry:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-plugin-mirror-conf data: rhdh-registries.conf: | [[registry]] prefix = "registry.access.redhat.com/rhdh" location = "<target_registry>/rhdh" [[registry]] prefix = "quay.io/rhdh" location = "<target_registry>/rhdh"where:
<target_registry>-
Enter the URL of your mirror registry, for example,
registry.example.com.
Mount the config map in the
install-dynamic-pluginsinit container by adding the following to yourBackstageCR:spec: application: extraFiles: configMaps: - name: rhdh-plugin-mirror-conf key: rhdh-registries.conf mountPath: /etc/containers/registries.conf.d containers: - install-dynamic-pluginsNoteCluster-level mirroring resources such as
ImageDigestMirrorSetorImageContentSourcePolicydo not apply to theinstall-dynamic-pluginsinit container because it usesskopeodirectly to pull plugin artifacts.Optional: To enforce signature verification in production environments, create a
policy.jsonconfig map and mount it in theinstall-dynamic-pluginsinit container:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-mirror-policy data: policy.json: | { "transports": { "docker": { "<target_registry>/<namespace>": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "<path_to_gpg_key>" } ] } } }Then add the following to the
extraFiles.configMapslist in yourBackstageCR:- name: rhdh-mirror-policy key: policy.json mountPath: /etc/containers containers: - install-dynamic-pluginsFor a full example CR showing how to configure plugin mirroring when using the Operator, see plugin-mirroring.yaml.
Verification
- If you are using Red Hat OpenShift Container Platform, the Red Hat Developer Hub Operator is in the Installed Operators list in the web console.
If you are using a supported Kubernetes platform, you can check the list of pods running in the
rhdh-operatornamespace by running the following command in your terminal:$ kubectl -n rhdh-operator get pods
Next steps
Use the Operator to create a Red Hat Developer Hub instance on a supported platform. For more information, see the following documentation for the platform that you want to use:
4.4.4. Deploy on OpenShift using Helm in an air-gapped environment
4.4.4.1. Deploy on OpenShift using Helm in an air-gapped environment
Install Red Hat Developer Hub on OpenShift Container Platform in fully or partially disconnected environments by using the Helm chart.
4.4.4.2. Mirror Helm images to deploy in fully disconnected OpenShift networks
Mirror Helm chart images to disk and transfer them to a fully disconnected OpenShift Container Platform environment.
If your network has access to the registry through a bastion host, you can use the Helm chart to install Red Hat Developer Hub.
Prerequisites
You have set up your workstation.
- You have an account in Red Hat Developer portal.
- You have access to the charts.openshift.io Helm chart repository.
-
You have installed GNU
tar1.35 or later,jq1.7 or later, the OpenShift CLI (oc), theoc-mirrorOpenShift CLI plugin v2, and Skopeo 1.20 or later on your workstation.
You have set up your intermediary host.
- Your host has access to the Red Hat Container Registry (registry.redhat.io).
- Your host has access to image registry on the destination host. For more information, see the Exposing the registry topic in the OpenShift Container Platform documentation.
You have set up your destination host.
- You have installed Red Hat OpenShift Container Platform 4.18 or later.
- Your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
Create an
ImageSetConfigurationfile to specify the resources that you want to mirror. For example:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: helm: repositories: - name: openshift-charts url: https://charts.openshift.io charts: - name: redhat-developer-hub version: "1.10"where:
version: "1.10"- Enter the Red Hat Developer Hub version to mirror.
Mirror the resources specified in the
ImageSetConfiguration.yamlfile by running theoc mirrorcommand. For example:$ oc mirror --v2 -c <mirror_config_directory>/ImageSetConfiguration.yaml file://<mirror_archive_directory>/
where:
<mirror_config_directory>-
Enter the location of your image set configuration file on your system, for example,
.user. <mirror_archive_directory>-
Enter the location of your directory where the system creates the mirror archive, for example,
file://.user.
Note-
The
--v2flag is required for OpenShift Container Platform 4.21 and later. -
Running the
oc mirrorcommand generates a local workspace containing the mirror archive file, the Helm chart,ImageDigestMirrorSet(IDMS) andImageTagMirrorSet(ITMS) manifests. The IDMS and ITMS manifests contain files that you must apply against the cluster in a later step.
Example output:
Creating archive /path/to/mirror-archive/mirror_seq1_000000.tar
-
Transfer the generated archive file (for example,
mirror_seq1_000000.tar) to the air-gapped environment. - Connect to your air-gapped environment and make sure that you are also connected to the following objects:
- The local target registry
- The target OpenShift Container Platform cluster
From your air-gapped environment, mirror the resources from the archive to the target registry by running the
oc mirrorcommand. For example:$ oc mirror --v2 -c <image_set_config> --from file://<mirror_archive_directory> docker://<target_registry>
where:
<mirror_archive_file>-
Enter the name of the file containing the resources that you want to mirror, for example,
mirror_seq1_0000.tar. <target_registry>-
Enter the name of the target registry that you want to push the mirrored images to, for example,
docker://registry.localhost:5000.
In your workspace, locate the IDMS and ITMS files by running the following command. For example:
$ ls <workspace_directory>/working-dir/cluster-resources/where:
<workspace_directory>-
Specifies the name of your workspace directory, for example,
oc-mirror-workspace. <results_directory>-
Specifies the name of your results directory, for example,
results-1738070846.
To mirror the Helm chart, deploy the IDMS and ITMS files in the disconnected cluster by running the
oc applycommand. For example:$ oc apply -f <workspace_directory>/working-dir/cluster-resources
where:
<workspace_directory>-
Enter the name of your workspace directory, for example,
oc-mirror-workspace. <results_directory>-
Enter the name of your results directory, for example,
results-1738070846.
Update the cluster pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ oc get secret pull-secret -n openshift-config -o json | \ jq -r '.data.".dockerconfigjson"' | base64 -d | \ jq --arg registry "<mirror_registry>" \ --arg auth "$(echo -n '<username>:<password>' | base64)" \ '.auths[$registry] = {"auth": $auth}' | \ oc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjson=/dev/stdinwhere:
<mirror_registry>-
Enter the hostname and port of your mirror registry, for example,
registry.example.com:5000. <username>:<password>Enter the credentials for authenticating to your mirror registry.
NoteWait for all machine config pools to finish updating before proceeding.
In your air-gapped environment, deploy the Helm chart to the namespace that you want to use by running the
helm installcommand withnamespaceandsetoptions. For example:CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/[.]*\.//') helm install <rhdh_instance> <workspace_directory>/working-dir/helm/charts/<archive_file> --namespace <your_namespace> --create-namespace \ --set global.clusterRouterBase="$CLUSTER_ROUTER_BASE"where:
<rhdh_instance>-
Enter the name of your Red Hat Developer Hub instance, for example,
my-rhdh-project. <workspace_directory>-
Enter the name of your workspace directory, for example,
oc-mirror-workspace. <results_directory>-
Enter the name of your results directory, for example,
results-1738070846. <archive_file>-
Enter the name of the archive file containing the resources that you want to mirror, for example,
redhat-developer-hub-1.4.1.tgz. <your_namespace>-
Enter the namespace that you want to deploy the Helm chart to, for example,
my-rhdh-project.
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Export the plugin catalog index and all referenced plugin OCI artifacts to disk by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-dir <my_plugin_mirror_dir>where:
<my_plugin_mirror_dir>Enter the absolute path to a directory where you want to export the plugin artifacts, for example,
/home/user/rhdh-plugins-mirror.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
-
Transfer the directory specified by the
--to-diroption to your disconnected environment. From a machine in your disconnected environment that has access to the target mirror registry, import the plugin artifacts by running the following command:
$ bash mirror-plugins.sh \ --from-dir <my_plugin_mirror_dir> \ --to-registry <target_registry>
where:
<my_plugin_mirror_dir>- Enter the path to the directory containing the exported plugin artifacts.
<target_registry>-
Enter the URL of the target mirror registry, for example,
registry.example.com.
Create a config map containing a
registries.conffile that redirects theinstall-dynamic-pluginsinit container to your mirror registry:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-plugin-mirror-conf data: rhdh-registries.conf: | [[registry]] prefix = "registry.access.redhat.com/rhdh" location = "<target_registry>/rhdh" [[registry]] prefix = "quay.io/rhdh" location = "<target_registry>/rhdh"where:
<target_registry>-
Enter the URL of your mirror registry, for example,
registry.example.com.
Mount the config map in the
install-dynamic-pluginsinit container by adding the following to your Helm values file:upstream: backstage: extraVolumes: - name: rhdh-plugin-mirror-conf configMap: name: rhdh-plugin-mirror-conf initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-plugin-mirror-conf mountPath: /etc/containers/registries.conf.d/rhdh-registries.conf subPath: rhdh-registries.conf readOnly: trueImportantBecause of Helm merge limitations, you must include all existing default volumes, volume mounts, and init container fields from the Red Hat Developer Hub Helm chart alongside your additions. Omitting the defaults overwrites them and can break the deployment.
NoteCluster-level mirroring resources, such as
ImageDigestMirrorSetorImageContentSourcePolicy, do not apply to theinstall-dynamic-pluginsinit container because it usesskopeodirectly to pull plugin artifacts.Optional: To enforce signature verification in production environments, create a
policy.jsonconfig map and mount it in theinstall-dynamic-pluginsinit container:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-mirror-policy data: policy.json: | { "transports": { "docker": { "<target_registry>/<namespace>": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "<path_to_gpg_key>" } ] } } }Then add the following volumes and volume mount entries to your Helm values file:
upstream: backstage: extraVolumes: - name: rhdh-mirror-policy configMap: name: rhdh-mirror-policy initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-mirror-policy mountPath: /etc/containers/policy.json subPath: policy.json readOnly: true
4.4.4.3. Mirror Helm images to local registries for partially disconnected networks
Mirror Helm chart images directly to a target registry in a partially disconnected OpenShift Container Platform environment.
If your network has access to the registry.redhat.io registry and the charts.openshift.io Helm chart repository, you can deploy your Red Hat Developer Hub instance in your partially disconnected environment.
Prerequisites
- You have installed Red Hat OpenShift Container Platform 4.18 or later.
-
You have access to the
charts.openshift.ioHelm chart repository. -
You have access to the
registry.redhat.io. - You have access to a mirror registry that the disconnected cluster can reach, for example, the OpenShift Container Platform image registry.
- You have logged in to your target mirror registry and have permissions to push images to it.
-
You have installed GNU
tar1.35 or later,jq1.7 or later, the OpenShift CLI (oc), theoc-mirrorOpenShift CLI plugin v2 (recommended), and Skopeo 1.20 or later on your workstation. - You have an account in Red Hat Developer portal.
- Make sure that your system meets the minimum sizing requirements. See Sizing requirements for Red Hat Developer Hub.
Procedure
Log in to your OpenShift Container Platform account using the OpenShift CLI (
oc) by running the following command:$ oc login -u <user> -p <password> https://api.<hostname>:6443
- From your disconnected cluster, log in to the image registry that you want to mirror, for example, the OpenShift Container Platform image registry.
Create an
ImageSetConfiguration.yamlfile to specify the resources that you want to mirror. For example:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: helm: repositories: - name: openshift-charts url: https://charts.openshift.io charts: - name: redhat-developer-hub version: "1.10"version: "1.10"- Enter the Red Hat Developer Hub version to mirror.
Mirror the resources specified in the image set configuration file directly to the target registry by running the
oc mirrorcommand. For example:$ oc mirror --v2 --config=<mirror_config_directory>/ImageSetConfiguration.yaml docker://<target_mirror_registry>
where:
<mirror_config_directory>-
Specifies the location of your image set configuration file on your system, for example,
.user. <target_mirror_registry>-
Specifies the location and name of your target mirror registry, for example,
registry.example:5000.
Note-
The
--v2flag is required for OpenShift Container Platform 4.21 and later. -
Running the
oc mirrorcommand generates a local workspace containing the Helm chart,ImageDigestMirrorSet(IDMS) andImageTagMirrorSet(ITMS) manifests. The IDMS and ITMS manifests contain files that you must apply against the cluster in a later step.
In your workspace, locate the
ImageDigestMirrorSet(IDMS) andImageTagMirrorSet(ITMS) files by running thelscommand. For example:$ ls <workspace_directory>/working-dir/cluster-resources/where:
<workspace_directory>-
Specifies the name of your workspace directory, for example,
oc-mirror-workspace. <results_directory>-
Specifies the name of your results directory, for example,
results-1738070846.
To configure image mirroring, deploy the IDMS and ITMS files in the disconnected cluster by running the
ocapply command. For example:$ oc apply -f <workspace_directory>/working-dir/cluster-resources
where:
<workspace_directory>-
Enter the name of your workspace directory, for example,
oc-mirror-workspace. <results_directory>-
Enter the name of your results directory, for example,
results-1738070846.
Update the cluster pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ oc get secret pull-secret -n openshift-config -o json | \ jq -r '.data.".dockerconfigjson"' | base64 -d | \ jq --arg registry "<mirror_registry>" \ --arg auth "$(echo -n '<username>:<password>' | base64)" \ '.auths[$registry] = {"auth": $auth}' | \ oc set data secret/pull-secret -n openshift-config --from-file=.dockerconfigjson=/dev/stdinwhere:
<mirror_registry>-
Enter the hostname and port of your mirror registry, for example,
registry.example.com:5000. <username>:<password>Enter the credentials for authenticating to your mirror registry.
NoteWait for all machine config pools to finish updating before proceeding.
In your air-gapped environment, deploy the Helm chart to the namespace that you want to use by running the
helm installcommand withnamespaceandsetoptions. For example:CLUSTER_ROUTER_BASE=$(oc get route console -n openshift-console -o=jsonpath='{.spec.host}' | sed 's/[.]*\.//') helm install <rhdh_instance> <workspace_directory>/<results_directory>/charts/<archive_file> --namespace <your_namespace> --create-namespace \ --set global.clusterRouterBase="$CLUSTER_ROUTER_BASE"where:
<rhdh_instance>-
Specifies the name of your Red Hat Developer Hub instance, for example,
my-rhdh. <workspace_directory>-
Specifies the name of your workspace directory, for example,
oc-mirror-workspace. <results_directory>-
Specifies the name of your results directory, for example,
results-1738070846. <archive_file>-
Specifies the name of the archive file containing the resources that you want to mirror, for example,
redhat-developer-hub-1.4.1.tgz. <your_namespace>-
Specifies the namespace that you want to deploy the Helm chart to, for example,
my-rhdh-project.
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Mirror the plugin catalog index and all referenced plugin OCI artifacts to your target registry by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-registry <target_registry>where:
<target_registry>Enter the URL of the target mirror registry, such as,
registry.example.com.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
Create a config map containing a
registries.conffile that redirects theinstall-dynamic-pluginsinit container to your mirror registry:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-plugin-mirror-conf data: rhdh-registries.conf: | [[registry]] prefix = "registry.access.redhat.com/rhdh" location = "<target_registry>/rhdh" [[registry]] prefix = "quay.io/rhdh" location = "<target_registry>/rhdh"where:
<target_registry>-
Enter the URL of your mirror registry, for example,
registry.example.com.
Mount the config map in the
install-dynamic-pluginsinit container by adding the following to your Helm values file:upstream: backstage: extraVolumes: - name: rhdh-plugin-mirror-conf configMap: name: rhdh-plugin-mirror-conf initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-plugin-mirror-conf mountPath: /etc/containers/registries.conf.d/rhdh-registries.conf subPath: rhdh-registries.conf readOnly: trueImportantBecause of Helm merge limitations, you must include all existing default volumes, volume mounts, and init container fields from the Red Hat Developer Hub Helm chart alongside your additions. Omitting the defaults overwrites them and can break the deployment.
NoteCluster-level mirroring resources, such as
ImageDigestMirrorSetorImageContentSourcePolicy, do not apply to theinstall-dynamic-pluginsinit container because it usesskopeodirectly to pull plugin artifacts.Optional: To enforce signature verification in production environments, create a
policy.jsonconfig map and mount it in theinstall-dynamic-pluginsinit container:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-mirror-policy data: policy.json: | { "transports": { "docker": { "<target_registry>/<namespace>": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "<path_to_gpg_key>" } ] } } }Then add the following volumes and volume mount entries to your Helm values file:
upstream: backstage: extraVolumes: - name: rhdh-mirror-policy configMap: name: rhdh-mirror-policy initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-mirror-policy mountPath: /etc/containers/policy.json subPath: policy.json readOnly: true
4.4.5. Deploy on Kubernetes platforms using Helm in air-gapped environments
4.4.5.1. Deploy on Kubernetes platforms using Helm in air-gapped environments
Install Red Hat Developer Hub on supported Kubernetes platforms in fully or partially disconnected environments by using the Helm chart.
Supported Kubernetes platforms include the following:
- Microsoft Azure Kubernetes Service
- Amazon Elastic Kubernetes Service
- Google Kubernetes Engine
4.4.5.2. Mirror Helm images to deploy in fully disconnected Kubernetes networks
Mirror Helm chart images to disk and transfer them to a fully disconnected Kubernetes environment.
In environments without internet access, a fully disconnected installation ensures that Red Hat Developer Hub can run reliably without external dependencies.
Prerequisites
-
You have installed GNU
tar1.35 or later, Helm 3.13 or later,jq1.7 or later, Skopeo 1.20 or later, andyq4.4 or later on your workstation. -
You authenticated to registry.redhat.io for pulling images by using the
skopeo logincommand. -
You have access to the Kubernetes cluster with
kubectlconfigured.
Procedure
On the mirroring host, in a terminal, fetch the Helm charts values by running the following commands:
$ helm repo add <helm_chart_repo_name> https://charts.openshift.io/ $ helm repo update $ helm show values <helm_chart_repo_name>/redhat-developer-hub --version <rhdh_version> values.default.yaml $ helm pull <helm_chart_repo_name>/redhat-developer-hub --version <rhdh_version>
where
- <helm_chart_repo_name>
-
Specifies the name of the Helm chart repository, for example,
openshift-helm-charts. - <rhdh_version>
Specifies the Red Hat Developer Hub version that you want to use, for example,
1.10.1.NoteThe
helm pull <helm_chart_repo_name>/redhat-developer-hub --version <rhdh_version>command automatically creates the Helm chart archive file and downloads the Helm chart to your current working directory.
Extract the image digests by running the following commands:
RHDH_IMAGE=$(yq '.upstream.backstage.image | .registry + "/" + .repository' values.default.yaml) RHDH_DIGEST=$(yq '.upstream.backstage.image.tag' values.default.yaml) PG_IMAGE=$(yq '.upstream.postgresql.image | .registry + "/" + .repository' values.default.yaml) PG_DIGEST=$(yq '.upstream.postgresql.image.tag' values.default.yaml)
Mirror the images to your local archive by running the following commands:
$ skopeo login registry.redhat.io $ skopeo copy --all docker://$RHDH_IMAGE}:$RHDH_DIGEST} dir:./rhdh-hub $ skopeo copy --all docker://${PG_IMAGE}:${PG_DIGEST} dir:./postgresql- Transfer the following files and directories to your air-gapped environment:
-
rhdh-hubdirectory containing the mirrored Red Hat Developer Hub image. -
postgresqldirectory containing the mirrored PostgreSQL image. -
Helm chart archive file, for example,
redhat-developer-hub-1.10.1.tgz. Load the images onto the air-gapped host by running the following commands:
$ skopeo copy --all dir:./rhdh-hub docker://<mirror_registry_name>/<rhdh_repo_name>:$RHDH_DIGEST} $ skopeo copy --all dir:./postgresql docker://<mirror_registry_name>/<postgresql_repo_name>:${PG_DIGEST}
where
- <mirror_registry_name>
-
Specifies the name of the target mirror registry that you want to push the images to, for example,
registry.example.com. - <rhdh_repo_name>
-
Specifies the name of the repository that stores your Red Hat Developer Hub image, for example,
rhdh/rhdh-hub-rhel9. This value must match the name of the Red Hat Developer Hub image that you loaded onto the air-gapped host. - <postgresql_repo_name>
-
Specifies the name of the repository that stores your PostgreSQL image, for example,
rhdh/postgresql-15.
Create a
values.yamlfile for the Kubernetes platform that you want to use and add the following image references to the file to reflect local use:upstream: backstage: image: registry: "<mirror_registry_name>" repository: <rhdh_repo_name> tag: "$RHDH_DIGEST}" postgresql: image: registry: "<mirror_registry_name>" repository: <postgresql_repo_name> tag: "${PG_DIGEST}"where
- <mirror_registry_name>
-
Specifies the name of the target mirror registry that you want to push the images to, for example,
registry.example.com. - <rhdh_repo_name>
-
Specifies the name of the repository that stores your Red Hat Developer Hub image, for example,
rhdh/rhdh-hub-rhel9. This value must match the name of the Red Hat Developer Hub image that you loaded onto the air-gapped host. - <postgresql_repo_name>
-
Specifies the name of the repository that stores your PostgreSQL image, for example,
rhdh/postgresql-15.
Create a pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ kubectl create secret docker-registry rhdh-pull-secret \ --docker-server=<mirror_registry> \ --docker-username=<username> \ --docker-password=<password> \ --namespace=<target_namespace> $ kubectl patch serviceaccount default \ --namespace=<target_namespace> \ --type='json' \ --patch='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"rhdh-pull-secret"}}]'where:
<mirror_registry>-
Enter the hostname and port of your mirror registry, for example,
registry.example.com:5000. <username>- Enter the username for authenticating to your mirror registry.
<password>- Enter the password for authenticating to your mirror registry.
<target_namespace>-
Enter the namespace where you will deploy Red Hat Developer Hub, for example,
rhdh.
For AKS, use the following
values.yamlfile template:global: host: <app_address> route: enabled: false upstream: ingress: enabled: true className: webapprouting.kubernetes.azure.com host: backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: fsGroup: 3000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true fsGroup: 3000 volumePermissions: enabled: trueFor EKS, use the following
values.yamlfile template:global: # TODO: Set your application domain name. host: <my_developer_hub_domain> route: enabled: false upstream: service: # NodePort is required for the ALB to route to the Service type: NodePort ingress: enabled: true annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing # TODO: Using an ALB HTTPS Listener requires a certificate for your own domain. Fill in the ARN of your certificate, e.g.: alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:xxx:xxxx:certificate/xxxxxx alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' alb.ingress.kubernetes.io/ssl-redirect: '443' # TODO: Set your application domain name. external-dns.alpha.kubernetes.io/hostname: <your rhdh domain name> backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: # you can assign any random value as fsGroup fsGroup: 2000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true # you can assign any random value as fsGroup fsGroup: 3000 volumePermissions: enabled: trueFor GKE, use the following
values.yamlfile template:global: host: <rhdh_domain_name> route: enabled: false upstream: service: type: NodePort ingress: enabled: true annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.global-static-ip-name: <ADDRESS_NAME> networking.gke.io/managed-certificates: <rhdh_certificate_name> networking.gke.io/v1beta1.FrontendConfig: <ingress_security_config> className: gce backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: fsGroup: 2000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true fsGroup: 3000 volumePermissions: enabled: trueInstall the Helm chart in the current namespace by running the following command:
$ helm install rhdh ./<helm_chart_archive_file_name> -f values.yamlwhere
- <helm_chart_archive_file_name>
-
Specifies the name of the Helm chart archive file, for example,
redhat-developer-hub-1.4.0.tgz.
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Export the plugin catalog index and all referenced plugin OCI artifacts to disk by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-dir <my_plugin_mirror_dir>where:
<my_plugin_mirror_dir>Enter the absolute path to a directory where you want to export the plugin artifacts, for example,
/home/user/rhdh-plugins-mirror.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
-
Transfer the directory specified by the
--to-diroption to your disconnected environment. From a machine in your disconnected environment that has access to the target mirror registry, import the plugin artifacts by running the following command:
$ bash mirror-plugins.sh \ --from-dir <my_plugin_mirror_dir> \ --to-registry <target_registry>
where:
<my_plugin_mirror_dir>- Enter the path to the directory containing the exported plugin artifacts.
<target_registry>-
Enter the URL of the target mirror registry, for example,
registry.example.com.
Create a config map containing a
registries.conffile that redirects theinstall-dynamic-pluginsinit container to your mirror registry:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-plugin-mirror-conf data: rhdh-registries.conf: | [[registry]] prefix = "registry.access.redhat.com/rhdh" location = "<target_registry>/rhdh" [[registry]] prefix = "quay.io/rhdh" location = "<target_registry>/rhdh"where:
<target_registry>-
Enter the URL of your mirror registry, for example,
registry.example.com.
Mount the config map in the
install-dynamic-pluginsinit container by adding the following to your Helm values file:upstream: backstage: extraVolumes: - name: rhdh-plugin-mirror-conf configMap: name: rhdh-plugin-mirror-conf initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-plugin-mirror-conf mountPath: /etc/containers/registries.conf.d/rhdh-registries.conf subPath: rhdh-registries.conf readOnly: trueImportantBecause of Helm merge limitations, you must include all existing default volumes, volume mounts, and init container fields from the Red Hat Developer Hub Helm chart alongside your additions. Omitting the defaults overwrites them and can break the deployment.
NoteCluster-level mirroring resources, such as
ImageDigestMirrorSetorImageContentSourcePolicy, do not apply to theinstall-dynamic-pluginsinit container because it usesskopeodirectly to pull plugin artifacts.Optional: To enforce signature verification in production environments, create a
policy.jsonconfig map and mount it in theinstall-dynamic-pluginsinit container:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-mirror-policy data: policy.json: | { "transports": { "docker": { "<target_registry>/<namespace>": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "<path_to_gpg_key>" } ] } } }Then add the following volumes and volume mount entries to your Helm values file:
upstream: backstage: extraVolumes: - name: rhdh-mirror-policy configMap: name: rhdh-mirror-policy initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-mirror-policy mountPath: /etc/containers/policy.json subPath: policy.json readOnly: true
4.4.5.3. Mirror Helm images to local registries for partially disconnected Kubernetes networks
Mirror Helm chart images directly to a target registry in a partially disconnected Kubernetes environment.
In a partially disconnected environment, the cluster cannot access external registries, for example, registry.redhat.io, but it can access an internal mirror registry. This method requires direct access to an internal mirror registry from the cluster.
Prerequisites
You have set up your workstation.
-
You have installed GNU
tar1.35 or later, Helm 3.13 or later,jq1.7 or later, Skopeo 1.20 or later, andyq4.4 or later. - You have an active Skopeo session against registry.redhat.io
-
You have an active Skopeo session against your target mirror registry, for example,
registry.internal.example.com -
You have access to the Kubernetes cluster with
kubectlconfigured
-
You have installed GNU
Procedure
In a terminal, download and extract the Helm chart by running the following commands:
$ helm repo add <helm_chart_repo_name> https://charts.openshift.io/ $ helm repo update $ helm pull <helm_chart_repo_name>/redhat-developer-hub --version <rhdh_version> $ helm show values <helm_chart_repo_name>/redhat-developer-hub --version <rhdh_version> > values.default.yaml
where:
- <helm_chart_repo_name>
-
Enter the name of the Helm chart repository, for example,
openshift-helm-charts. - <rhdh_version>
-
Enter the Red Hat Developer Hub version that you want to use, for example,
1.10.1.
Use
yqto extract the image digests by running the following commands:RHDH_IMAGE=$(yq '.upstream.backstage.image | .registry + "/" + .repository' values.default.yaml) RHDH_DIGEST=$(yq '.upstream.backstage.image.tag' values.default.yaml) PG_IMAGE=$(yq '.upstream.postgresql.image | .registry + "/" + .repository' values.default.yaml) PG_DIGEST=$(yq '.upstream.postgresql.image.tag' values.default.yaml)
Mirror the images to the internal mirror registry by entering the following commands:
$ skopeo login registry.redhat.io $ skopeo login _<mirror_registry_name>_ $ skopeo copy --remove-signatures \ docker://${PG_IMAGE}@${PG_DIGEST} \ docker://_<mirror_registry_name>_/_<postgresql_repo_name>_:${PG_DIGEST} $ skopeo copy --remove-signatures \ docker://$RHDH_IMAGE}@$RHDH_DIGEST} \ docker://_<mirror_registry_name>_/_<rhdh_repo_name>_$RHDH_DIGEST}where
- <mirror_registry_name>
-
Specifies the name of the internal mirror registry, for example,
registry.internal.example.com. - <postgresql_repo_name>
-
Specifies the name of the PostgreSQL repository, for example,
rhdh/postgresql-15. - <rhdh_repo_name>
-
Specifies the name of the Red Hat Developer Hub repository, for example,
rhdh/rhdh-hub-rhel9.
Create a pull secret to allow the
kubeletto pull all Red Hat Developer Hub images from your mirror registry:$ kubectl create secret docker-registry rhdh-pull-secret \ --docker-server=<mirror_registry> \ --docker-username=<username> \ --docker-password=<password> \ --namespace=<target_namespace> $ kubectl patch serviceaccount default \ --namespace=<target_namespace> \ --type='json' \ --patch='[{"op":"add","path":"/imagePullSecrets/-","value":{"name":"rhdh-pull-secret"}}]'where:
<mirror_registry>-
Enter the hostname and port of your mirror registry, for example,
registry.example.com:5000. <username>- Enter the username for authenticating to your mirror registry.
<password>- Enter the password for authenticating to your mirror registry.
<target_namespace>-
Enter the namespace where you will deploy Red Hat Developer Hub, for example,
rhdh.
Create a
values.yamlfile for the Kubernetes platform that you want to use and add the following image references to the file to reflect local use:upstream: backstage: image: registry: "_<mirror_registry_name>_" repository: _<rhdh_repo_name>_ tag: "$RHDH_DIGEST}" postgresql: image: registry: "_<mirror_registry_name>_" repository: _<postgresql_repo_name>_ tag: "${PG_DIGEST}"For AKS, use the following
values.yamlfile template:global: host: <app_address> route: enabled: false upstream: ingress: enabled: true className: webapprouting.kubernetes.azure.com host: backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: fsGroup: 3000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true fsGroup: 3000 volumePermissions: enabled: trueFor EKS, use the following
values.yamlfile template:global: # TODO: Set your application domain name. host: <your Developer Hub domain name> route: enabled: false upstream: service: # NodePort is required for the ALB to route to the Service type: NodePort ingress: enabled: true annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing # TODO: Using an ALB HTTPS Listener requires a certificate for your own domain. Fill in the ARN of your certificate, e.g.: alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:xxx:xxxx:certificate/xxxxxx alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]' alb.ingress.kubernetes.io/ssl-redirect: '443' # TODO: Set your application domain name. external-dns.alpha.kubernetes.io/hostname: <your rhdh domain name> backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: # you can assign any random value as fsGroup fsGroup: 2000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true # you can assign any random value as fsGroup fsGroup: 3000 volumePermissions: enabled: trueFor GKE, use the following
values.yamlfile template:global: host: <rhdh_domain_name> route: enabled: false upstream: service: type: NodePort ingress: enabled: true annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.global-static-ip-name: <ADDRESS_NAME> networking.gke.io/managed-certificates: <rhdh_certificate_name> networking.gke.io/v1beta1.FrontendConfig: <ingress_security_config> className: gce backstage: image: pullSecrets: - rhdh-pull-secret podSecurityContext: fsGroup: 2000 postgresql: image: pullSecrets: - rhdh-pull-secret primary: podSecurityContext: enabled: true fsGroup: 3000 volumePermissions: enabled: trueInstall the Helm chart in the current namespace by running the following command:
$ helm install rhdh ./_<helm_chart_archive_file_name>_ -f values.yaml
where
- <helm_chart_archive_file_name>
-
Specifies the name of the Helm chart archive file, for example,
redhat-developer-hub-1.10.1.tgz.
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Mirror the plugin catalog index and all referenced plugin OCI artifacts to your target registry by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-registry <target_registry>where:
<target_registry>Enter the URL of the target mirror registry, such as,
registry.example.com.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
Create a config map containing a
registries.conffile that redirects theinstall-dynamic-pluginsinit container to your mirror registry:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-plugin-mirror-conf data: rhdh-registries.conf: | [[registry]] prefix = "registry.access.redhat.com/rhdh" location = "<target_registry>/rhdh" [[registry]] prefix = "quay.io/rhdh" location = "<target_registry>/rhdh"where:
<target_registry>-
Enter the URL of your mirror registry, for example,
registry.example.com.
Mount the config map in the
install-dynamic-pluginsinit container by adding the following to your Helm values file:upstream: backstage: extraVolumes: - name: rhdh-plugin-mirror-conf configMap: name: rhdh-plugin-mirror-conf initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-plugin-mirror-conf mountPath: /etc/containers/registries.conf.d/rhdh-registries.conf subPath: rhdh-registries.conf readOnly: trueImportantBecause of Helm merge limitations, you must include all existing default volumes, volume mounts, and init container fields from the Red Hat Developer Hub Helm chart alongside your additions. Omitting the defaults overwrites them and can break the deployment.
NoteCluster-level mirroring resources, such as
ImageDigestMirrorSetorImageContentSourcePolicy, do not apply to theinstall-dynamic-pluginsinit container because it usesskopeodirectly to pull plugin artifacts.Optional: To enforce signature verification in production environments, create a
policy.jsonconfig map and mount it in theinstall-dynamic-pluginsinit container:apiVersion: v1 kind: ConfigMap metadata: name: rhdh-mirror-policy data: policy.json: | { "transports": { "docker": { "<target_registry>/<namespace>": [ { "type": "signedBy", "keyType": "GPGKeys", "keyPath": "<path_to_gpg_key>" } ] } } }Then add the following volumes and volume mount entries to your Helm values file:
upstream: backstage: extraVolumes: - name: rhdh-mirror-policy configMap: name: rhdh-mirror-policy initContainers: - name: install-dynamic-plugins volumeMounts: - name: rhdh-mirror-policy mountPath: /etc/containers/policy.json subPath: policy.json readOnly: true
Chapter 5. Upgrade
5.1. Upgrade
Keep your Red Hat Developer Hub instance current by upgrading to the latest version to receive new features, security patches, and bug fixes.
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
Upgrade your Red Hat Developer Hub instance to a later version to apply the latest features, security patches, and bug fixes without disrupting your development teams.
Red Hat Developer Hub supports two upgrade paths depending on your deployment method:
- Operator — An administrator can upgrade the Red Hat Developer Hub Operator by using the OpenShift Container Platform web console. After approval of the install plan, the Operator reconciles the deployment to the new version.
- Helm chart — You can upgrade by using either the OpenShift Container Platform web console or the Helm CLI. Red Hat Developer Hub supports direct upgrades from any earlier version to the latest release without installing intermediate versions.
Before upgrading, review the release notes for every version between your current release and the target release to identify breaking changes, deprecations, or required migration steps. If your Helm chart deployment uses custom values.yaml files that override default configuration lists, you must manually merge new mandatory defaults before upgrading.
5.2.2. Upgrade the RHDH Operator
If you use the Operator to deploy your Red Hat Developer Hub instance, then an administrator can use the OpenShift Container Platform web console to upgrade the Operator to a later version.
OpenShift Container Platform is currently supported from version 4.18 to 4.21. See also the Red Hat Developer Hub Life Cycle.
Prerequisites
- You have logged in as an administrator on the OpenShift Container Platform web console.
- You have installed the Red Hat Developer Hub Operator.
- You have configured the appropriate roles and permissions within your project to create or access an application. For more information, see the link:Building applications in the Red Hat OpenShift Container Platform documentation.
Procedure
- In the Administrator perspective of the OpenShift Container Platform web console, click Operators > Installed Operators.
- On the Installed Operators page, click Red Hat Developer Hub Operator.
- On the Red Hat Developer Hub Operator page, click the Subscription tab.
From the Upgrade status field on the Subscription details page, click Upgrade available.
NoteIf there is no upgrade available, the Upgrade status field value is Up to date.
On the
InstallPlandetails page, click PreviewInstallPlan> Approve.ImportantIf you are on the Orchestrator plugin
1.7, you must manually update the plugin configuration after approval to avoid a failed deployment. For more information, see Upgrading the Orchestrator plugin from1.7to 1.10.
Verification
- The Upgrade status field value on the Subscription details page is Up to date.
Additional resources
5.2.2.1. Approve the Operator InstallPlan
Approve the Operator InstallPlan to complete the upgrade to the latest version.
Procedure
- TO DO: Update procedure steps
5.2.3. Upgrade the RHDH Helm chart
You can upgrade to a later version of Red Hat Developer Hub in OpenShift Container Platform by using either the web console or the CLI.
Prerequisites
- You have deployed Developer Hub on OpenShift Container Platform by using the Helm chart.
Procedure
OpenShift Container Platform web console
WarningIf you have installed Developer Hub manually using the Helm CLI, the Helm chart release upgrade in the OpenShift Container Platform web console is going to fail. The failure is due to the limitations when using the OpenShift Container Platform console to upgrade a Helm release that was initially deployed using the Helm CLI. You can bypass this limitation by using the Helm CLI to upgrade. However, if you still want to upgrade using the console, select the Helm Chart version from the drop-down list and select the Developer Hub version you want to upgrade to. Before performing this step, save your
values.yamlconfiguration file in a different location.ImportantYou can upgrade Red Hat Developer Hub directly from any earlier version to the latest release without installing intermediate versions. Before upgrading, you must review the release notes for every skipped version to identify breaking changes, deprecations, or required migration steps. For example, if upgrading from version 1.5 to 1.7, check the release notes for both 1.6 and 1.7.
- In the Developer perspective, click Helm to open the Helm Releases tab.
- Click the overflow menu on the Helm release that you want to use and select Upgrade.
- On the Upgrade Helm Release page, select the version of Developer Hub that you want to upgrade to from the chart version drop-down list.
Click Upgrade.
NoteIt might take a few minutes to delete the resources in the older versions and to start the newer versions of the Developer Hub pods.
- Close all open Developer Hub web pages, and log in again to verify that the upgrade was successful.
- OpenShift Container Platform CLI
Log in to the OpenShift Container Platform cluster as the cluster administrator and switch to the project or namespace where you installed Developer Hub.
$ oc login -u <user> -p <password> https://api.<HOSTNAME>:6443 $ oc project my-rhdh-project
For a new version of the Developer Hub Helm chart, run the following upgrade command:
$ helm upgrade -i rhdh -f new-values.yml \ openshift-helm-charts/redhat-developer-hub --version 1.10.1
NoteYou can also give extra values to the chart by creating a
new-values.ymlfile on your workstation with values that override the attributes in the installed chart or by adding new attributes.
5.2.3.1. Apply the new Helm chart version
Apply the new Helm chart version to upgrade your Red Hat Developer Hub instance.
Procedure
- TO DO: Update procedure steps
5.2.3.2. Update custom Helm chart configurations
Update custom Helm chart configurations to ensure compatibility with the new version.
Procedure
- TO DO: Update procedure steps
5.2.3.3. Enable Quicklinks and starred items after an upgrade
If you upgrade from Red Hat Developer Hub 1.6 or earlier, Red Hat Developer Hub does not automatically enable the Quicklinks and Starred Items features. You must manually configure these features to display them in the global header.
Prerequisites
- You have access to your Red Hat Developer Hub configuration files.
- You have administrative permissions to modify ConfigMaps (if using the Operator).
Procedure
-
Locate your
dynamic-pluginconfiguration. - Operator deployment: The configuration is stored in a ConfigMap referenced by your Backstage custom resource (CR).
-
Helm deployment: The configuration is in your
values.yamlfile or separate configuration files. -
Enable the global header plugin. Ensure that the
red-hat-developer-hub-backstage-plugin-global-headerentry exists under theplugins: listand thatdisabledis set tofalse. Verify that you enabled the global header plugin. Confirm that you listed the
red-hat-developer-hub-backstage-plugin-global-headerplugin underplugins:withdisabled: false(or without adisabledproperty):- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-header disabled: falseAdd the required components. Under the
mountPointssection of the plugin, add the components as shown in the following example:mountPoints: - mountPoint: application/header importName: GlobalHeader config: position: above-sidebar - mountPoint: global.header/component importName: StarredDropdown config: priority: 85 - mountPoint: global.header/component importName: ApplicationLauncherDropdown config: priority: 82 - mountPoint: global.header/component importName: MenuItemLink config: section: Documentation priority: 150 props: title: Developer Hub icon: developerHub link: https://docs.redhat.com/en/documentation/red_hat_developer_hub - mountPoint: global.header/application-launcher importName: MenuItemLink config: section: Developer Tools priority: 100 props: title: "RHDH Local" icon: developerHub link: https://github.com/redhat-developer/rhdh-local- Apply the configuration.
- Operator deployment: Update the ConfigMap and allow the Operator to reconcile the changes.
-
Helm deployment: Apply your updated configuration using
helm upgrade. - Verify the features are enabled. After the Red Hat Developer Hub instance restarts, confirm that the star icon and Quicklinks matrix appear in the global header.
5.2.3.4. Update custom Helm configurations to safely upgrade from version 1.8 to 1.9
If you use custom values.yaml files that override default configuration lists, you must manually update the files to include new mandatory defaults before upgrading to 1.10.
Prerequisites
- You have a running instance of Red Hat Developer Hub 1.8 deployed using the Helm chart.
Your custom
values.yamlfile overrides any of the following affected fields:-
upstream.backstage.extraVolumeMounts -
upstream.backstage.extraVolumes -
upstream.backstage.initContainers
-
Procedure
Manually merge the new default items into your
values.yamlfile to include the following highlighted items within their lists and avoid configuration loss:upstream: backstage: extraVolumeMounts: # TODO: In addition to your custom mounts and the RHDH defaults, ensure this item is present (defined in the default RHDH chart): - name: extensions-catalog mountPath: /extensions extraVolumes: # TODO: In addition to your custom volumes and the RHDH defaults, ensure this item is present (defined in the default RHDH chart): - name: extensions-catalog emptyDir: {} initContainers: # TODO: Ensure the 'install-dynamic-plugins' container includes these environment variables and volume mounts: - name: install-dynamic-plugins env: # TODO: In addition to your custom env vars and the RHDH defaults for the install-dynamic-plugins init container, # ensure the following items are present (defined in the default RHDH chart): - name: CATALOG_INDEX_IMAGE value: '{{ .Values.global.catalogIndex.image.registry }}/{{ .Values.global.catalogIndex.image.repository }}:{{ .Values.global.catalogIndex.image.tag }}' - name: CATALOG_ENTITIES_EXTRACT_DIR value: '/extensions' volumeMounts: # TODO: In addition to your custom volume mounts and the RHDH defaults for the install-dynamic-plugins init container, # ensure the following item is present (defined in the default RHDH chart): - name: extensions-catalog mountPath: /extensions # ... other fields omitted for brevityTipTo view the full list of default values for 1.10, run the following command:
helm show values redhat-developer-hub --repo https://charts.openshift.io --version 1.10.1
Verification
- Verify that the Red Hat Developer Hub application successfully initializes.
5.2.3.5. Upgrade the OpenShift Serverless Logic Operator for Red Hat Developer Hub 1.9
Upgrade the OpenShift Serverless Logic (OSL) Operator to version 1.38.0 for compatibility with Red Hat Developer Hub 1.10.
See OpenShift Serverless Logic Operator documentation for the supported OpenShift Serverless Logic Operator versions and upgrade process.
Starting with OSL 1.37.0, the Operator subscription name and starting ClusterServiceVersion (CSV) no longer explicitly reference the operating system (OS) version.
In previous releases, the Operator subscription name and starting CSV explicitly included the OS version, such as logic-operator-rhel8 and logic-operator-rhel8.v1.36.0.
Before performing the upgrade, make sure you do not delete the existing SonataflowPlatform operands during this process. When performing the upgrade, you must replace the logic-operator-rhel8 subscription with the logic-operator subscription.
Prerequisites
- You have administrative access to the OpenShift cluster.
Procedure
Delete the previous
logic-operator-rhel8subscription and apply the following configuration to install thelogic-operatorsubscription:apiVersion: v1 kind: Namespace metadata: name: openshift-serverless-logic --- apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: openshift-serverless-logic namespace: openshift-serverless-logic spec: --- apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: logic-operator namespace: openshift-serverless-logic spec: channel: stable # channel of an operator package to subscribe to installPlanApproval: Automatic # whether the update should be installed automatically name: logic-operator # name of the operator package source: redhat-operators # name of the catalog source sourceNamespace: openshift-marketplace startingCSV: logic-operator.v1.38.0 # The initial version of the operator
Optional: If your configuration uses an external PostgreSQL database with SSL, add the required datasource environment variables to the
jobServicespecification in theSonataflowPlatformcustom resource as shown in the following configuration:jobService: enabled: true persistence: dbMigrationStrategy: service postgresql: # no additional url params here. We only have currentSchema=jobs-service. jdbcUrl: 'jdbc:postgresql://postgress-external-db-primary.postgress-external-db.svc.cluster.local:5432/sonataflow?currentSchema=jobs-service' secretRef: name: postgres-cred passwordKey: POSTGRES_PASSWORD userKey: POSTGRES_USER podTemplate: container: env: # only this two env vars - name: QUARKUS_DATASOURCE_REACTIVE_POSTGRESQL_SSL_MODE value: allow - name: QUARKUS_DATASOURCE_REACTIVE_TRUST_ALL value: 'true'
5.2.3.6. Upgrade the Orchestrator plugins for 1.9 Operator-backed instances
Update the dynamic-plugins ConfigMap to use Open Container Initiative (OCI) image references for Orchestrator plugins compatibility with Red Hat Developer Hub 1.10.
If you do not update the dynamic-plugins ConfigMap after upgrading the RHDH Operator to 1.10, the Developer Hub instance fails to upgrade.
Prerequisites
-
You have a running instance of Red Hat Developer Hub with Orchestrator
1.8backed by the Operator. - You have upgraded the Red Hat Developer Hub Operator to version 1.10.
- You have administrative access to the OpenShift cluster.
Procedure
-
Open your
dynamic-pluginsConfigMap for editing. Update the
packagereferences for the Orchestrator plugins to use the 1.10 OCI registry paths as shown in the following example:apiVersion: v1 kind: ConfigMap metadata: name: dynamic-plugins-rhdh data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}' disabled: false - package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend:{{inherit}}' disabled: false dependencies: - ref: sonataflow - package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:{{inherit}}' disabled: false - package: 'oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:{{inherit}}' disabled: falseNoteThe
{{inherit}}attribute in your configuration automatically resolves to the 1.10 version provided by the Operator.- Save the configuration changes.
Verification
- Log in to your Red Hat Developer Hub instance.
- Confirm that the Orchestrator plugins display the version metadata for 1.10.
5.2.4. Roll back a dynamic plugin to a previous version
If a dynamic plugin update causes issues after a z-stream update, you can roll back the plugin by replacing the {{inherit}} tag or the current version reference with a pinned OCI image digest. This procedure applies to any plugin packaged as an OCI image.
Prerequisites
- You have administrator access to your Developer Hub instance.
-
You have the
skopeoandjqCLI tools installed. - You have network access to the container registry hosting the plugin image.
Procedure
-
In your
dynamic-plugins.yamlfile, identify the plugin entry that uses the{{inherit}}tag or the version you want to roll back. List the available version tags for the plugin image:
$ skopeo list-tags docker://<plugin_image>
where:
<plugin_image>-
The OCI image path without the tag or digest. For example,
registry.access.redhat.com/rhdh/backstage-community-plugin-topologyorghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-tech-radar.
Get the SHA256 digest for the version tag you want to roll back to:
$ skopeo inspect docker://<plugin_image>:<tag> | jq '.Digest'
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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
In your
dynamic-plugins.yamlfile, replace the{{inherit}}tag or current version with the pinned digest:plugins: - package: oci://<plugin_image>@<digest> disabled: falsewhere:
<digest>-
The SHA256 digest value returned by the
skopeo inspectcommand. For example,sha256:28036abec4dffc714394e4ee433f16a59493db8017795049c831be41c02eb5dc.
Apply the configuration change:
-
If you deployed RHDH by using the Operator, update your
Backstagecustom resource (CR). -
If you deployed RHDH by using the Helm chart, update your Helm chart values and run the
helm upgradecommand.
-
If you deployed RHDH by using the Operator, update your
- Restart the RHDH application.
Verification
- Check the Developer Hub application logs to confirm the plugin loaded at the expected version.
- Verify the plugin behavior in the Developer Hub web console.
Chapter 6. Migrate
6.1. Migrate
Migrate your Red Hat Developer Hub data infrastructure to meet production requirements by moving from the default local database to an external PostgreSQL server to improve reliability, performance, and scalability.
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
When scaling your Red Hat Developer Hub deployment for production use, migrate from the default local database to an external PostgreSQL server to improve reliability, performance, and long-term maintainability of your data infrastructure.
By default, the Red Hat Developer Hub Operator and Helm chart create a local PostgreSQL instance for storing catalog data, user sessions, and plugin state. While this local database is suitable for evaluation and development, production environments require an external PostgreSQL server that supports high availability, automated backups, and independent scaling.
Migrating to an external PostgreSQL server provides the following benefits:
- Reliability — External databases support replication, failover, and disaster recovery, reducing the risk of data loss.
- Performance — Dedicated database resources prevent resource contention between the application and database layers.
- Scalability — External databases scale independently, supporting larger catalogs and higher concurrency.
- Maintainability — Database administrators can manage patching, monitoring, and tuning without affecting the RHDH deployment.
Configure your database to use the date format of the International Organization for Standardization (ISO) through the DateStyle setting. Other formats are incompatible with the internal tracking of the software catalog, which causes scheduling tasks to fail and prevents your catalog items from refreshing.
6.2.2. Configure an external PostgreSQL database
Configure an external PostgreSQL database for production environments instead of using the default local database created by the Red Hat Developer Hub Operator or Helm chart.
Configure your database to use the date format of the International Organization for Standardization (ISO) through the DateStyle setting. Other formats are incompatible with the internal tracking of the software catalog, which causes scheduling tasks to fail and prevents your catalog items from refreshing.
6.2.2.1. Configure an external PostgreSQL instance using the Operator
Configure an external PostgreSQL instance by using the Red Hat Developer Hub Operator instead of the default local PostgreSQL instance.
Prerequisites
- You meet the Sizing requirements for external PostgreSQL deployments.
- You are using a supported version of PostgreSQL. For more information, see the Product life cycle page.
You have the following details:
-
db_host: Denotes your PostgreSQL instance Domain Name System (DNS) or IP address -
db_port: Denotes your PostgreSQL instance port number, such as5432 -
username: Denotes the user name to connect to your PostgreSQL instance -
password: Denotes the password to connect to your PostgreSQL instance
-
- You have installed the Red Hat Developer Hub Operator.
- Optional: You have a CA certificate, Transport Layer Security (TLS) private key, and TLS certificate so that you can secure your database connection by using the TLS protocol. For more information, refer to your PostgreSQL vendor documentation.
By default, Developer Hub uses a database for each plugin and automatically creates it if none exists. You might need the Create Database privilege in addition to PostgreSQL Database privileges for configuring an external PostgreSQL instance.
Procedure
Optional: Create a certificate secret to configure your PostgreSQL instance with a TLS connection:
$ cat <<EOF | oc -n my-rhdh-project create -f - apiVersion: v1 kind: Secret metadata: name: my-rhdh-database-certificates-secrets type: Opaque stringData: postgres-ca.pem: |- -----BEGIN CERTIFICATE----- <ca_certificate_key> postgres-key.key: |- -----BEGIN CERTIFICATE----- <tls_private_key> postgres-crt.pem: |- -----BEGIN CERTIFICATE----- <tls_certificate_key> # ... EOF
Where:
my-rhdh-database-certificates-secrets- The certificate secret name.
<ca_certificate_key>- The CA certificate key.
<tls_private_key>- Optional: The TLS private key.
<tls_certificate_key>- Optional: The TLS certificate key.
Create a credential secret to connect to the PostgreSQL instance:
$ cat <<EOF | oc -n my-rhdh-project create -f - apiVersion: v1 kind: Secret metadata: name: my-rhdh-database-secrets type: Opaque stringData: POSTGRES_PASSWORD: <password> POSTGRES_PORT: "<db_port>" POSTGRES_USER: <username> POSTGRES_HOST: <db_host> PGSSLMODE: <ssl_mode> NODE_EXTRA_CA_CERTS: <abs_path_to_pem_file> EOF
Where:
my-rhdh-database-secrets- The credential secret name.
<password>- The password to connect to your PostgreSQL instance.
<db_port>-
Your PostgreSQL instance port number, such as
5432. <username>- The user name to connect to your PostgreSQL instance.
<db_host>- Your PostgreSQL instance DNS or IP address.
<ssl_mode>- Optional: For TLS connections, the required SSL mode.
<abs_path_to_pem_file>-
Optional: For TLS connections, the absolute path to the Privacy-Enhanced Mail (PEM) file, for example
/opt/app-root/src/postgres-crt.pem.
Create a Kubernetes service that points to your external PostgreSQL database:
apiVersion: v1 kind: Service metadata: name: external-postgresql-service spec: type: ExternalName externalName: <your-external-db-host-name> ports: - port: 5432 targetPort: 5432 protocol: TCPWhere:
external-postgresql-service- Name of the service to reference in plugin configurations.
ExternalName- Service type that creates a CNAME record to the external database host name.
<your-external-db-host-name>FQDN of your external PostgreSQL server, for example,
postgres.example.com.NoteIf your external database is outside the cluster or uses an IP address instead of a host name, create a service with endpoints:
apiVersion: v1 kind: Service metadata: name: external-postgresql-service spec: ports: - port: 5432 targetPort: 5432 protocol: TCP --- apiVersion: v1 kind: Endpoints metadata: name: external-postgresql-service subsets: - addresses: - ip: <your-external-db-ip> ports: - port: 5432 protocol: TCPWhere:
<your-external-db-ip>- IP address of your external PostgreSQL server.
Optional: Ensure your external PostgreSQL instance is configured with recommended performance tuning parameters.
Set
shared_buffersto approximately 1/4 andeffective_cache_sizeto approximately 1/2 of the allocated database memory. For recommended values based on your deployment scale, see Sizing requirements for Red Hat Developer Hub.Create your
Backstagecustom resource (CR):cat <<EOF | oc -n my-rhdh-project create -f - apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: <backstage_instance_name> spec: database: enableLocalDb: false application: extraFiles: mountPath: <path> secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem, postgres-ca.pem, postgres-key.key extraEnvs: secrets: - name: my-rhdh-database-secrets # ...Where:
spec.database.enableLocalDb-
Set to
falseto disable creating local PostgreSQL instances. <path>-
The mount path for certificate files, for example
/opt/app-root/src. my-rhdh-database-certificates-secrets- The certificate secret name, required if you configure a TLS connection.
key-
The key names as defined in the
my-rhdh-database-certificates-secretsSecret. my-rhdh-database-secretsThe credential secret name.
NoteThe environment variables listed in the
BackstageCR work with the Operator default configuration. If you have changed the Operator default configuration, you must reconfigure theBackstageCR accordingly.
-
Apply the
BackstageCR to the namespace where you have deployed the Developer Hub instance.
6.2.2.2. Configure an external PostgreSQL instance using the Helm chart
Configure an external PostgreSQL instance by using the Helm chart instead of the default local PostgreSQL instance.
Prerequisites
- You meet the Sizing requirements for external PostgreSQL deployments.
- You are using a supported version of PostgreSQL. For more information, see the Product life cycle page.
You have the following details:
-
db_host: Denotes your PostgreSQL instance Domain Name System (DNS) or IP address -
db_port: Denotes your PostgreSQL instance port number, such as5432 -
username: Denotes the user name to connect to your PostgreSQL instance -
password: Denotes the password to connect to your PostgreSQL instance
-
- You have installed the RHDH application by using the Helm chart.
- Optional: You have a CA certificate, Transport Layer Security (TLS) private key, and TLS certificate so that you can secure your database connection by using the TLS protocol. For more information, refer to your PostgreSQL vendor documentation.
By default, Developer Hub uses a database for each plugin and automatically creates it if none exists. You might need the Create Database privilege in addition to PostgreSQL Database privileges for configuring an external PostgreSQL instance.
Procedure
Optional: Create a certificate secret to configure your PostgreSQL instance with a TLS connection:
$ cat <<EOF | oc -n <your_namespace> create -f - apiVersion: v1 kind: Secret metadata: name: my-rhdh-database-certificates-secrets type: Opaque stringData: postgres-ca.pem: |- -----BEGIN CERTIFICATE----- <ca_certificate_key> postgres-key.key: |- -----BEGIN CERTIFICATE----- <tls_private_key> postgres-crt.pem: |- -----BEGIN CERTIFICATE----- <tls_certificate_key> # ... EOF
Where:
my-rhdh-database-certificates-secrets- The certificate secret name.
<ca_certificate_key>- The CA certificate key.
<tls_private_key>- Optional: The TLS private key.
<tls_certificate_key>- Optional: The TLS certificate key.
Create a credential secret to connect to the PostgreSQL instance:
$ cat <<EOF | oc -n <your_namespace> create -f - apiVersion: v1 kind: Secret metadata: name: my-rhdh-database-secrets type: Opaque stringData: POSTGRES_PASSWORD: <password> POSTGRES_PORT: "<db_port>" POSTGRES_USER: <username> POSTGRES_HOST: <db_host> PGSSLMODE: <ssl_mode> NODE_EXTRA_CA_CERTS: <abs_path_to_pem_file> EOF
Where:
my-rhdh-database-secrets- The credential secret name.
<password>- The password to connect to your PostgreSQL instance.
<db_port>-
Your PostgreSQL instance port number, such as
5432. <username>- The user name to connect to your PostgreSQL instance.
<db_host>- Your PostgreSQL instance DNS or IP address.
<ssl_mode>- Optional: For TLS connections, the required SSL mode.
<abs_path_to_pem_file>-
Optional: For TLS connections, the absolute path to the Privacy-Enhanced Mail (PEM) file, for example
/opt/app-root/src/postgres-crt.pem.
Create a Kubernetes service that points to your external PostgreSQL database:
apiVersion: v1 kind: Service metadata: name: external-postgresql-service spec: type: ExternalName externalName: <your-external-db-host-name> ports: - port: 5432 targetPort: 5432 protocol: TCPWhere:
external-postgresql-service- Name of the service to reference in plugin configurations.
ExternalName- Service type that creates a CNAME record to the external database host name.
<your-external-db-host-name>FQDN of your external PostgreSQL server, for example,
postgres.example.com.NoteIf your external database is outside the cluster or uses an IP address instead of a host name, create a service with endpoints:
apiVersion: v1 kind: Service metadata: name: external-postgresql-service spec: ports: - port: 5432 targetPort: 5432 protocol: TCP --- apiVersion: v1 kind: Endpoints metadata: name: external-postgresql-service subsets: - addresses: - ip: <your-external-db-ip> ports: - port: 5432 protocol: TCPWhere:
<your-external-db-ip>- IP address of your external PostgreSQL server.
Configure your PostgreSQL instance in the Helm configuration file named
values.yaml:# ... upstream: postgresql: enabled: false auth: existingSecret: my-rhdh-database-secrets backstage: appConfig: backend: database: connection: host: ${POSTGRES_HOST} port: ${POSTGRES_PORT} user: ${POSTGRES_USER} password: ${POSTGRES_PASSWORD} ssl: rejectUnauthorized: true, ca: $file: /opt/app-root/src/postgres-ca.pem key: $file: /opt/app-root/src/postgres-key.key cert: $file: /opt/app-root/src/postgres-crt.pem extraEnvVarsSecrets: - my-rhdh-database-secrets extraEnvVars: - name: BACKEND_SECRET valueFrom: secretKeyRef: key: backend-secret name: '{{ include "rhdh.backend-secret-name" $ }}' extraVolumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root - mountPath: /opt/app-root/src/postgres-crt.pem name: postgres-crt subPath: postgres-crt.pem - mountPath: /opt/app-root/src/postgres-ca.pem name: postgres-ca subPath: postgres-ca.pem - mountPath: /opt/app-root/src/postgres-key.key name: postgres-key subPath: postgres-key.key extraVolumes: - ephemeral: volumeClaimTemplate: spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi name: dynamic-plugins-root - configMap: defaultMode: 420 name: dynamic-plugins optional: true name: dynamic-plugins - name: dynamic-plugins-npmrc secret: defaultMode: 420 optional: true secretName: '{{ printf "%s-dynamic-plugins-npmrc" .Release.Name }}' - name: postgres-crt secret: secretName: my-rhdh-database-certificates-secrets # ...Where:
upstream.postgresql.enabled-
Set to
falseto disable the local PostgreSQL instance creation. upstream.postgresql.auth.existingSecret- The credentials secret to inject into Backstage.
upstream.backstage.appConfig.backend.database.connection- The Backstage database connection parameters.
upstream.backstage.extraEnvVarsSecrets- The credentials secret to inject as environment variables into Backstage.
extraVolumeMounts(postgres-crt,postgres-ca,postgres-key)- Optional: Inject TLS certificate, CA certificate, and TLS private key into the Backstage container.
extraVolumes(postgres-crt)- The certificate secret name, required if you configure TLS.
Optional: Ensure your external PostgreSQL instance is configured with recommended performance tuning parameters.
Set
shared_buffersto approximately 1/4 andeffective_cache_sizeto approximately 1/2 of the allocated database memory. For recommended values based on your deployment scale, see Sizing requirements for Red Hat Developer Hub.Apply the configuration changes in your Helm configuration file named
values.yaml:$ helm upgrade -n <your_namespace> <your_deploy_name> openshift-helm-charts/redhat-developer-hub -f values.yaml --version 1.10.1
6.2.2.3. Migrate local databases to an external PostgreSQL server
Migrate data from a local PostgreSQL server to an external PostgreSQL service by using PostgreSQL utilities such as pg_dump and psql.
The following procedure uses a database copy script to do a quick migration.
Prerequisites
Procedure
Configure port forwarding for the local PostgreSQL database pod by running the following command on a terminal:
$ oc port-forward -n <your_namespace> <pgsql_pod_name> <forward_to_port>:<forward_from_port>
Where:
-
The
<pgsql_pod_name>variable denotes the name of a PostgreSQL pod with the formatbackstage-psql-<deployment_name>-<_index>. -
The
<forward_to_port>variable denotes the port of your choice to forward PostgreSQL data to. The
<forward_from_port>variable denotes the local PostgreSQL instance port, such as5432.$ oc port-forward -n developer-hub backstage-psql-developer-hub-0 15432:5432
Make a copy of the following
db_copy.shscript and edit the details based on your configuration:#!/bin/bash to_host=<db_service_host> to_port=5432 to_user=postgres from_host=127.0.0.1 from_port=15432 from_user=postgres allDB=("backstage_plugin_app" "backstage_plugin_auth" "backstage_plugin_catalog" "backstage_plugin_permission" "backstage_plugin_scaffolder" "backstage_plugin_search") for db in ${!allDB[@]}; do db=${allDB[$db]} echo Copying database: $db PGPASSWORD=$TO_PSW psql -h $to_host -p $to_port -U $to_user -c "create database $db;" pg_dump -h $from_host -p $from_port -U $from_user -d $db | PGPASSWORD=$TO_PSW psql -h $to_host -p $to_port -U $to_user -d $db doneWhere:
to_host-
The destination hostname, for example
<db_instance_name>.rds.amazonaws.com. to_port-
The destination port, such as
5432. to_user-
The destination server username, for example
postgres. from_host-
The source hostname, such as
127.0.0.1. from_port-
The source port number, such as the
<forward_to_port>variable. from_user-
The source server username, for example
postgres. allDB- Database names to import, in double quotes separated by spaces.
Create a destination database for copying the data:
/bin/bash TO_PSW=<destination_db_password> /path/to/db_copy.sh
Replace
<destination_db_password>with the password to connect to the destination database.NoteYou can stop port forwarding when the copying of the data is complete. For more information about handling large databases and using the compression tools, see the Handling Large Databases section on the PostgreSQL website.
-
Reconfigure your
Backstagecustom resource (CR). For more information, see Configure an external PostgreSQL instance using the Operator. Check that the following code is present at the end of your
BackstageCR after reconfiguration:# ... spec: database: enableLocalDb: false application: # ... extraFiles: secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem extraEnvs: secrets: - name: my-rhdh-database-secrets # ...NoteReconfiguring the
BackstageCR deletes the correspondingStatefulSetandPodobjects, but does not delete thePersistenceVolumeClaimobject. Use the following command to delete the localPersistenceVolumeClaimobject:oc -n developer-hub delete pvc <local_psql_pvc_name>
where, the
<local_psql_pvc_name>variable is in thedata-<psql_pod_name>format.- Apply the configuration changes.
Verification
Verify that your RHDH instance is running with the migrated data and does not contain the local PostgreSQL database by running the following command:
oc get pods -n <your_namespace>
- Check the output for the following details:
-
The
backstage-developer-hub-xxxpod is in running state. The
backstage-psql-developer-hub-0pod is not available.You can also verify these details by using the Topology view in the OpenShift Container Platform web console.
6.2.2.4. Configure schema-based plugin isolation to simplify single-database provisioning
Configure schema-based plugin isolation to support database users without CREATEDB privileges or to reduce database provisioning overhead. Each RHDH plugin uses its own PostgreSQL schema within a single shared database.
Prerequisites
- An external PostgreSQL instance is configured using the Operator or the Helm chart.
-
Your database user has
CREATE SCHEMAprivileges on the target database, or your database administrator will create the required schemas.
By default, when pluginDivisionMode is set to schema, RHDH automatically creates the required schemas because the ensureExists configuration defaults to true. The database user must have CREATE SCHEMA privileges on the target database.
Procedure
Add
pluginDivisionMode: schemato thebackend.databasesection of your RHDH configuration in theapp-config-rhdhConfigMap:backend: database: client: pg pluginDivisionMode: schema connection: host: ${POSTGRES_HOST} port: ${POSTGRES_PORT} user: ${POSTGRES_USER} password: ${POSTGRES_PASSWORD}- Save the configuration changes.
- Restart the Red Hat Developer Hub deployment to apply the new configuration.
6.2.3. Execute the database copy script
Run the database copy script to migrate data from the local PostgreSQL instance to your external PostgreSQL server.
Procedure
- TO DO: Break apart existing topic
6.2.4. Create destination database on the external server
Create destination databases on the external PostgreSQL server to receive the migrated data.
Procedure
- TO DO: Break apart existing topic
6.3. Migrate to the front-end system to use blueprint-based dynamic routing
6.3.1. Migrate to the front-end system to use blueprint-based dynamic routing
Migrate your Red Hat Developer Hub environment to the extension-based front-end system to use blueprint-based dynamic routing for improved extensibility and performance.
Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
6.3.1.1. Additional resources
6.3.2. Customize platform appearance to reflect your brand identity
Apply custom color schemes, logos, and visual elements to the Red Hat Developer Hub interface so the platform reflects your organization’s brand identity.
Prerequisites
-
You have installed the
@backstage/frontend-defaultspackage. -
You have access to the
packages/app/src/App.tsxfile. -
You have access to the
app-config.yamlfile.
Procedure
To enable the custom theme, import the
rhdhThemeModulefrom the theme plugin alpha module in yourpackages/app/src/App.tsxfile:import { createApp } from '@backstage/frontend-defaults'; import { rhdhThemeModule } from '@red-hat-developer-hub/backstage-plugin-theme/alpha'; export default createApp({ features: [ rhdhThemeModule, // Additional features ], });NoteFor advanced customization beyond color schemes and branding, you can create a custom theme module that extends the base theme configuration. For a complete example of creating a custom theme module by overriding theme plugin extensions, see the theme plugin example in the rhdh-plugins repository.
To set the application title and branding, configure extension settings in your
app-config.yamlfile:app: title: My Company Catalog baseUrl: http://localhost:3000 organization: name: My Company
- Save the configuration file and restart your Red Hat Developer Hub instance to apply the theme changes.
Verification
- Open your Red Hat Developer Hub instance in a web browser.
- Verify that the interface displays your custom theme.
- Check that theme colors match your brand identity specifications.
6.3.3. Update Global Header mount points to integrate securely with the new Blueprint architecture
Update Global Header mount points to integrate securely with the new Blueprint architecture by installing and integrating the global header plugin into your Red Hat Developer Hub application as a prerequisite for adding custom buttons, menus, and navigation shortcuts to the header.
Procedure
To enable custom navigation, install the global header plugin package.
yarn --cwd packages/app add @red-hat-developer-hub/backstage-plugin-global-header
To register the global header, import the plugin and modules in your
packages/app/src/App.tsxfile.import { createApp } from '@backstage/frontend-defaults'; import globalHeaderPlugin, { globalHeaderModule, globalHeaderTranslationsModule, } from '@red-hat-developer-hub/backstage-plugin-global-header/alpha'; export default createApp({ features: [ globalHeaderModule, globalHeaderTranslationsModule, // Enables translation support globalHeaderPlugin, ], });NoteYou can omit the
globalHeaderPluginif yourapp-config.yamlfile includes the following configuration:app: packages: all
- Restart your development server to load the plugin.
6.3.5. Add plugin-specific buttons to the toolbar for quick actions
Add custom buttons or interactive widgets to the global header toolbar that trigger your plugin’s functionality directly. Use GlobalHeaderComponentBlueprint to create these toolbar components programmatically.
Prerequisites
- You have set up the global header plugin in your application.
- You have access to your plugin source code.
Procedure
To add a plugin button to the toolbar, create a custom toolbar component extension in your plugin code:
import { GlobalHeaderComponentBlueprint } from '@red-hat-developer-hub/backstage-plugin-global-header/alpha'; const myToolbarButton = GlobalHeaderComponentBlueprint.make({ name: 'my-toolbar-item', params: { component: MyCustomComponent, // React component to render in the toolbar. priority: 100, // Higher priority values display first in the toolbar. }, });To create icon buttons without custom components, you can provide data-driven configuration instead of a component:
const dashboardButton = GlobalHeaderComponentBlueprint.make({ name: 'dashboard-button', params: { icon: 'dashboard', title: 'Dashboard', link: '/dashboard', priority: 75, // Higher priority values display first in the toolbar. }, });To activate the toolbar button, register the extension in your plugin’s alpha exports:
export default createPlugin({ id: 'my-plugin', extensions: [myToolbarButton], });
6.3.7. Reorganize or remove header items to align with your team priorities
Adjust the display order of global header components by changing their priority values, replace default implementations with custom versions, or hide items that your team does not use to streamline the interface.
Procedure
To reorder components, assign higher priority values to items that should appear first:
globalHeader: components: - title: Priority Item icon: star link: /important priority: 200 # Higher values render before lower-priority defaults.To override a default component, create an extension with the same name but different configuration:
const customSearch = GlobalHeaderComponentBlueprint.make({ name: 'search', // Matches the default search component to replace it. params: { component: MyCustomSearchComponent, priority: 150, }, });To disable a default extension, configure it with
disabled: truein your extension overrides:extensions: - global-header-component:search: disabled: true # Disables the default search component.
6.3.8. Migrate the Homepage to function as a dynamic plugin loaded through blueprints
Migrate the dynamic homepage to function as a plugin loaded through blueprints to choose which templates and widgets appear when you log in. You can use customizable layouts to drag and resize cards, or fixed layouts with predefined positions.
Available widgets include:
- Onboarding sections
- Entity catalogs
- Software templates
- Quick access cards
- Search bars
- Recently visited items
- Top visited resources
Prerequisites
-
You have installed the
@red-hat-developer-hub/backstage-plugin-dynamic-home-pagepackage. -
You have access to the
packages/app/src/App.tsxfile. -
You have access to the
app-config.yamlfile.
Procedure
To enable the dynamic homepage, import and register the homepage modules in your
packages/app/src/App.tsxfile:import { createApp } from '@backstage/frontend-defaults'; import { homePageDevModule, homepageTranslationsModule, } from '@red-hat-developer-hub/backstage-plugin-dynamic-home-page/alpha'; export default createApp({ features: [ homePageDevModule, // Enables the dynamic homepage plugin homepageTranslationsModule, // Adds internationalization support // Additional features ], });To set the homepage route and visit tracking, configure them in your
app-config.yamlfile:app: extensions: - page:home: config: path: / # Set to / to make the homepage your landing page - api:home/visits: true # Enables visit tracking for recently visited and top visited widgets - app-root-element:home/visit-listener: true # Activates the visit listener to record page visitsChoose a layout mode by setting the
customizableoption. Set totruefor a customizable grid where you can drag and resize cards, or set tofalsefor a read-only grid with fixed card positions:app: extensions: - home-page-layout:home/dynamic-homepage-layout: config: customizable: true # Set to false to prevent you from moving or resizing cardsTo control widget display order and sizing, configure widget sections with priority values and responsive breakpoints. Priority values determine display order in read-only layouts, with higher values appearing first.
app: extensions: - home-page-layout:home/dynamic-homepage-layout: config: customizable: false widgetLayout: RhdhTemplateSection: # Software templates widget section priority: 300 # Priority applies only to read-only layouts. Higher values display first. breakpoints: # Card dimensions (width w and height h in grid units) across device sizes 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 } RhdhEntitySection: # Entity catalog widget section showing registered components priority: 200 breakpoints: xl: { w: 12, h: 7 } lg: { w: 12, h: 7 } md: { w: 12, h: 7 } sm: { w: 12, h: 7 } xs: { w: 12, h: 9 } xxs: { w: 12, h: 15 } RhdhOnboardingSection: # Onboarding widget section with getting started guides priority: 100 breakpoints: xl: { w: 12, h: 6 } lg: { w: 12, h: 6 } md: { w: 12, h: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 8 } xxs: { w: 12, h: 12 }- Save the configuration file.
- Restart your Red Hat Developer Hub instance to apply the homepage layout changes.
Verification
- Open your Red Hat Developer Hub instance in a web browser.
- Verify that the homepage displays at the configured path.
- Check that widget cards appear in the expected order and size.
-
If
customizable: true, confirm that you can drag and resize cards. - Verify that visit tracking works by navigating to different pages and checking the recently visited widget.
6.3.9. Enable guided tutorials to learn platform features
Enable guided tutorials in Red Hat Developer Hub to learn platform features through interactive quick start walkthroughs. Tutorials automatically display on first visit and are accessible from a Quick start button in the global header.
Prerequisites
-
You have installed the
@red-hat-developer-hub/backstage-plugin-quickstartpackage. -
You have access to the
packages/app/src/App.tsxfile.
Procedure
To enable guided tutorials, import the quick start modules in your
packages/app/src/App.tsxfile:import { createApp } from '@backstage/frontend-defaults'; import { quickstartInitModule, quickstartTranslationsModule, } from '@red-hat-developer-hub/backstage-plugin-quickstart/alpha'; export default createApp({ features: [ quickstartInitModule, // Handles first-visit auto-open and notifications quickstartTranslationsModule, // Provides internationalization support // Additional features ], });To make tutorials accessible, add the Quick start sidebar button to your navigation component:
import { useAppDrawer } from '@backstage/frontend-plugin-api'; import { WavingHandOutlinedIcon } from '@mui/icons-material'; import { QUICKSTART_DRAWER_ID } from '@red-hat-developer-hub/backstage-plugin-quickstart'; function QuickstartSidebarItem() { const { toggleDrawer } = useAppDrawer(); return ( <SidebarItem text="Quick start" icon={WavingHandOutlinedIcon} onClick={() => toggleDrawer(QUICKSTART_DRAWER_ID)} /> ); }NoteIf you have the global header plugin installed, a default menu item for opening and closing the Quick start drawer automatically appears in the Help menu. The custom sidebar button shown above is only necessary if the global header plugin is not installed.
Verification
- Open your Red Hat Developer Hub instance in a new browser window.
- Verify that the Quick start drawer opens automatically on first visit.
- Click the Quick start sidebar button to toggle the drawer.
- Confirm that tutorials display based on your role.
6.3.10. Preserve custom integrations when migrating to the front-end system
Migrate your mount points and custom components from the Scalprum-based system to Red Hat Developer Hub extension-based front-end system by converting YAML-based mount points to extension blueprints.
Your existing mount points for entity pages, application headers, search filters, and admin pages map to specific extension attachment points in the front-end system. The extension tree resolves attachments by matching extension outputs to parent inputs. Blueprints provide typed patterns for common extension types including pages, navigation items, and entity content.
Available entity page mount points:
- overview
- topology
- issues
- pull-requests
- ci
- cd
- kubernetes
- image-registry
- monitoring
- api
- dependencies
- docs
- definition
- diagram
Prerequisites
-
You have access to the
packages/app/src/App.tsxfile. -
You have access to your
app-config.yamlfile. -
You understand your current mount point configuration in the
dynamicPlugins.frontendsection.
Procedure
To begin migration, identify your current mount points in the
dynamicPlugins.frontendconfiguration:dynamicPlugins: frontend: my-plugin: mountPoints: - mountPoint: entity.page.overview/cards # Current mount point importName: MyComponent config: if: isKind: component layout: xs: { w: 12, h: 4 }To understand the migration path, map your mount points to front-end system extension points:
Previous mount point Current extension attachment Blueprint to use entity.page.overview/cardspage:catalog/entitywith inputcontentsEntityContentBlueprintorEntityCardBlueprintentity.page.*/cardspage:catalog/entitywith inputcontentsEntityContentBlueprintapplication/headerapp/rootwith custom attachmentCustom extension with
coreExtensionData.reactElementsearch.page.resultspage:searchwith inputcontentCustom extension
admin.page.pluginspage:adminwith inputcontentCustom extension
To migrate your configuration, convert your mount point configuration to extension blueprint code in your plugin’s
/alphaexport file:// For entity page cards import { EntityCardBlueprint } from '@backstage/plugin-catalog-react/alpha'; const myEntityCard = EntityCardBlueprint.make({ name: 'my-component', params: { filter: entity => entity.kind === 'Component', // Replaces if.isKind condition loader: () => import('./MyComponent').then(m => <m.MyComponent />), }, }); export default createFrontendPlugin({ pluginId: 'my-plugin', extensions: [myEntityCard], });To migrate entity tabs, convert
entityTabsconfiguration toEntityContentBlueprint:// Old configuration dynamicPlugins: frontend: my-plugin: entityTabs: - path: /my-tab title: My Tab mountPoint: entity.page.my-tab // New extension blueprint import { EntityContentBlueprint } from '@backstage/plugin-catalog-react/alpha'; const myTab = EntityContentBlueprint.make({ name: 'my-tab', params: { defaultPath: '/my-tab', defaultTitle: 'My Tab', loader: () => import('./MyTabContent').then(m => <m.MyTabContent />), }, });To activate the migrated plugin, update your
packages/app/src/App.tsxfile to import it:import { createApp } from '@backstage/frontend-defaults'; import myPlugin from '@my-org/backstage-plugin-my-plugin/alpha'; export default createApp({ features: [ myPlugin, // Additional plugins ], });-
To complete the migration, remove the previous mount point configuration from your
app-config.yamlfile after verifying the migration works.
Verification
- Open your Red Hat Developer Hub instance in a web browser.
- Navigate to an entity page where your component should appear.
- Verify that your custom component displays in the correct location.
- Check that conditional rendering based on entity kind or type works as expected.
- Verify that any custom layout configurations apply correctly.
Chapter 7. Administer
7.1. Administer
Measure component compliance, track portfolio health, and analyze platform adoption to maintain operational visibility across your Red Hat Developer Hub deployment. Administration tasks ensure software standards are met and platform investments deliver measurable value.
7.2. Evaluate component compliance using Scorecards
7.2.1. Component health and compliance monitoring using Scorecards
This section describes Developer Preview features in the Scorecard plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
Use the Scorecard plugin to achieve the following goals:
- Identify and prioritize risks: Use unified health data to make faster remediation decisions.
- Maintain security standards: Automatically surface compliance gaps to enforce best practices.
- Streamline workflows: Access all metrics in RHDH to reduce development overhead.
- Standardize service quality: Define and measure consistent health criteria across the organization.

7.2.2. Supported Scorecard metrics providers
The Scorecard plugin gathers data from third-party systems through metric providers. Use the following table to identify which metrics are available for each supported provider.
The following metric providers are supported:
| Provider | Metric ID | Title | Description | Type |
|---|---|---|---|---|
|
GitHub |
|
GitHub open PRs |
Number of open pull requests in GitHub. |
number |
|
Jira |
|
Jira open issues |
Number of open issues in Jira. |
number |
|
OpenSSF |
|
Binary Artifacts |
Determines if the project has generated executable (binary) artifacts in the source repository. |
score (0-10) |
|
OpenSSF |
|
Branch Protection |
Determines if the default and release branches are protected with branch protection settings. |
score (0-10) |
|
OpenSSF |
|
CII Best Practices |
Determines if the project has an OpenSSF (formerly CII) Best Practices Badge. |
score (0-10) |
|
OpenSSF |
|
CI Tests |
Determines if the project runs tests before pull requests are merged. |
score (0-10) |
|
OpenSSF |
|
Code Review |
Determines if the project requires human code review before pull requests are merged. |
score (0-10) |
|
OpenSSF |
|
Contributors |
Determines if the project has a set of contributors from multiple organizations. |
score (0-10) |
|
OpenSSF |
|
Dangerous Workflow |
Determines if the project’s GitHub Action workflows avoid dangerous patterns. |
score (0-10) |
|
OpenSSF |
|
Dependency Update Tool |
Determines if the project uses a dependency update tool. |
score (0-10) |
|
OpenSSF |
|
Fuzzing |
Determines if the project uses fuzzing. |
score (0-10) |
|
OpenSSF |
|
License |
Determines if the project has defined a license. |
score (0-10) |
|
OpenSSF |
|
Maintained |
Determines if the project is actively maintained. |
score (0-10) |
|
OpenSSF |
|
Packaging |
Determines if the project is published as a package. |
score (0-10) |
|
OpenSSF |
|
Pinned Dependencies |
Determines if the project has declared and pinned the dependencies of its build process. |
score (0-10) |
|
OpenSSF |
|
SAST (Static Analysis Security Testing) |
Determines if the project uses static code analysis. |
score (0-10) |
|
OpenSSF |
|
Security Policy |
Determines if the project has published a security policy. |
score (0-10) |
|
OpenSSF |
|
Signed Releases |
Determines if the project cryptographically signs release artifacts. |
score (0-10) |
|
OpenSSF |
|
Token Permissions |
Determines if the project’s workflows follow the principle of least privilege. |
score (0-10) |
|
OpenSSF |
|
Vulnerabilities |
Determines if the project has open, known unfixed vulnerabilities. |
score (0-10) |
|
Filecheck |
|
<key> |
Verifies that the configured file exists in the repository. The metric ID suffix and title are derived from the key you define in |
boolean |
For information about customizing metric thresholds, see Scorecard metric thresholds.
7.2.3. Set up Scorecards
7.2.3.1. Set up Scorecards
Enable the Scorecards plugin and configure role-based access control to restrict metric visibility and administration. Initial setup establishes who can view compliance data and who can modify metric configurations.
7.2.3.2. Enable Scorecards
To monitor component health and quality in RHDH, you must enable the Scorecard plugin in your configuration.
Prerequisites
Procedure
Add the following configuration in your RHDH
dynamic-plugin-config.yamlfile:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:<tag> disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-scorecard: entityTabs: - path: '/scorecard' title: Scorecard mountPoint: entity.page.scorecard mountPoints: - mountPoint: entity.page.scorecard/cards importName: EntityScorecardContent config: layout: gridColumn: 1 / -1 if: allOf: - isKind: component - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
7.2.3.3. Configure RBAC using the CSV file
You can grant read access to Scorecard metrics by adding permission policies to your RBAC CSV file.
Prerequisites
- You have enabled RBAC and assigned a policy administrator role.
-
You have added
scorecardto the list of authorized plugins under yourpermission.rbac.pluginsWithPermissionconfiguration.
Procedure
Add the following policy to your CSV file to allow users to view metrics:
g, user:default/<YOUR_USERNAME>, role:default/scorecard-viewer p, role:default/scorecard-viewer, scorecard.metric.read, read, allow p, role:default/scorecard-viewer, catalog.entity.read, read, allow
Optional: Restrict access to specific metrics by defining a conditional policy in the
rbac-conditional-policies.yamlfile as described in Defining conditional policies:result: CONDITIONAL roleEntityRef: "role:default/scorecard-viewer" pluginId: scorecard resourceType: scorecard-metric permissionMapping: - read conditions: rule: HAS_METRIC_ID resourceType: scorecard-metric params: metricIds: [<your_metric_id>]where:
metricIdsEnter the metric ID for user access, such as
github.open_prs.This policy allows users to read only the specified metrics and restricts access to all other metrics.
Verification
- Verify that the user can view Scorecard metrics in RHDH.
7.2.3.4. Configure RBAC using the Web UI
You can grant read access to Scorecard metrics by using the RBAC Web UI in RHDH.
Prerequisites
- You have added a custom Developer Hub application configuration.
-
You have added
scorecardto the list of authorized plugins under yourpermission.rbac.pluginsWithPermissionconfiguration.
Procedure
- In the Red Hat Developer Hub navigation menu, go to Administration > RBAC.
- Select or create the Role for Scorecard access.
- In the Add permission policies section, select Scorecard from the plugins list.
Expand the Scorecard entry, select policy with the following details, and click Next:
-
Name:
scorecard.metric.read Permission:
read
-
Name:
Optional: Restrict access to specific metrics:
In the Add permission policies step, select the following:
-
Name:
scorecard.metrics.read -
Permission:
Read
-
Name:
- Click Use advanced customized permissions to allow access to specific parts of the selected resource type under Actions.
-
Select the
HAS_METRIC_IDrule and specify the plugin IDs, using commas to separate multiple IDs.
Verification
- Verify that the user can view Scorecard metrics in RHDH.
7.2.4. Install and configure Scorecards
7.2.4.1. Install and configure Scorecards
Integrate external metric providers to populate Scorecard data from your existing development tools. Each provider connection enables specific health metrics that reflect real-time project activity.
7.2.4.2. Integrate GitHub health metrics
You can configure the GitHub Scorecard plugin to display repository metrics in your RHDH catalog. This integration allows you to monitor component health and security risks directly from Red Hat Developer Hub.
You can grant RHDH access to the GitHub API by using a GitHub App or a GitHub token.
For long-lived integrations or organizational access, you must use a GitHub App.
Prerequisites
- You have installed your RHDH instance.
- You have installed the Scorecard images.
- Optional: If you choose the GitHub App option, you must have permissions in GitHub to create and manage a GitHub App.
- You have added a custom Developer Hub application configuration.
Procedure
Grant GitHub API access: Create one of the following authentication methods:
Configure using a GitHub App.
Create a GitHub App with the required permissions (Read-only for Contents to allow reading repositories).
NoteYou must install the GitHub App on the organization (or user account) that owns repositories you want access to, granting it the necessary repository access permissions.
- In the General > Clients secrets section, click Generate a new client secret.
- In the General > Private keys section, click Generate a private key.
- In the Install App tab, choose an account to install your GitHub App on.
- Record the App ID, Client ID, Client Secret, and Private key values.
Add secrets to RHDH by adding the following key/value pairs to your RHDH secrets. You can use these secrets in the RHDH configuration files by using the corresponding environment variable name for each secret.
-
GITHUB_INTEGRATION_APP_ID:: The saved App ID. -
GITHUB_INTEGRATION_CLIENT_ID:: The saved Client ID. -
GITHUB_INTEGRATION_CLIENT_SECRET:: The saved Client Secret. -
GITHUB_INTEGRATION_HOST_DOMAIN:: The GitHub host domain:github.com. -
GITHUB_INTEGRATION_ORGANIZATION:: Your GitHub organization name, such as<your_github_organization_name>. -
GITHUB_INTEGRATION_PRIVATE_KEY_FILE:: The saved Private key content.
-
Configure the GitHub integration in your RHDH
app-config.yamlfile by adding the authentication details to theintegrations.githubsection:integrations: github: - host: ${GITHUB_INTEGRATION_HOST_DOMAIN} apps: - appId: ${GITHUB_INTEGRATION_APP_ID} clientId: ${GITHUB_INTEGRATION_CLIENT_ID} clientSecret: ${GITHUB_INTEGRATION_CLIENT_SECRET} privateKey: | ${GITHUB_INTEGRATION_PRIVATE_KEY_FILE}
Configure using a GitHub token.
Create a GitHub token with the following permissions:
-
Classic Personal Access Token (PAT): Select the
reposcope for read/write access to private repositories. Fine-Grained Personal Access Token (PAT):
- Choose the specific repositories that RHDH must access.
- Grant the token a Read permission for Contents.
-
Classic Personal Access Token (PAT): Select the
Add the token to RHDH secrets by adding the following key/value pair to your RHDH secrets.
where:
GITHUB_TOKEN- The generated GitHub token.
Configure the GitHub integration in your RHDH
app-config.yamlfile by adding the authentication details to theintegrations.githubsection:integrations: github: - host: github.com token: ${GITHUB_TOKEN}
Enable the GitHub Scorecard plugin: Add the GitHub Scorecard module to your RHDH
dynamic-plugins-config.yamlfile:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github:<tag> disabled: falsewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Annotate catalog entities: Link a component to the GitHub data source by editing the
catalog-info.yamlfile for your RHDH entity and adding the required annotations as shown in the following code:apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-service annotations: # Required: GitHub project slug in format "owner/repository" github.com/project-slug: myorg/my-service # Required: Entity source location backstage.io/source-location: url:https://github.com/myorg/my-service spec: type: service lifecycle: production owner: _<your_team_name>_where:
annotations:github.com/project-slug-
The GitHub repository format, for example,
owner/repository. annotations:backstage.io/source-location-
The entity source location format, for example,
url:https://github.com/owner/repository. spec:ownerYour team name.
NoteYou must add the team entity to the Catalog to ensure the provided permissions are applicable.
Ingest the catalog entity: Add the location of your
catalog-info.yamlto thecatalog.locationssection in your RHDHapp-config.yamlfile:catalog: locations: - type: url target: https://github.com/<owner>/<repository>/catalog-info.yamlOptional: Customize thresholds: Define custom roles for the GitHub Open Pull Requests (
github.open_prs) metric in your RHDHapp-config.yamlfile:scorecard: plugins: github: open_prs: thresholds: rules: - key: success expression: '<10' - key: warning expression: '10-50' - key: error expression: '>50'where:
scorecard:plugins:github:open_prs:thresholds- Lists the default threshold values for the GitHub open PRs metric.
GitHub metrics use the following default thresholds for the GitHub Open Pull Requests (github.open_prs) metric:
- Error: More than 50 open pull requests.
- Warning: Between 10 and 50 open pull requests.
- Success: Fewer than 10 open pull requests.
You can customize these thresholds in your RHDH app-config.yaml file. For more information, see Scorecard metric thresholds.
7.2.4.3. Integrate Jira health metrics
You can configure the Jira Scorecard plugin to display project tracking and delivery velocity data in your RHDH instance. This integration centralizes development status and facilitates the evaluation of component readiness.
The plugin supports Jira Cloud (API v3) and Jira Data Center (API v2).
Prerequisites
- You must have administrator privileges for Jira and RHDH.
- You have installed your RHDH instance.
- You have installed the Scorecard images.
- You have added a custom Developer Hub application configuration.
Procedure
Generate a Jira configuration token using one of the following methods, depending on your Jira product:
Jira Cloud: Create a personal token. You must create a
Base64-encodedstring using the following plain text format:your-atlassian-email:your-jira-api-token.$ echo -n 'your-atlassian-email:your-jira-api-token' | base64
- Jira data center: Create a Personal Access Token (PAT) in your Jira data center account.
Add Jira secrets: Define the following key/value pairs in your RHDH secrets:
JIRA_TOKEN- Enter your generated Jira token.
JIRA_BASE_URL- Enter your Jira base URL.
Configure the plugin: In your RHDH
dynamic-plugins-config.yamlfile, enable the plugin using either a direct setup or a proxy setup.NoteYou must use the proxy setup to ensure configuration compatibility if you also use the Roadie Jira Frontend Plugin.
Use a direct setup:
Add the following code to your RHDH
dynamic-plugins-config.yamlfile:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira:<tag> disabled: falsewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
In your RHDH
app-config.yamlfile, add the following direct setup settings:jira: baseUrl: ${JIRA_BASE_URL} token: ${JIRA_TOKEN} product: _<jira_product>_where:
baseUrl- The base URL of your Jira instance, configured under ${JIRA_BASE_URL} in your RHDH secrets.
token- The Jira token (Base64 string for Cloud, PAT for Data Center), configured under ${JIRA_TOKEN} in your RHDH secrets.
productEnter the supported product:
cloudordatacenter.- Use a proxy setup:
In your RHDH
dynamic-plugins-config.yamlfile, add the following code:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira:<tag> disabled: falsewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
In your RHDH
app-config.yamlfile, add the following proxy settings:proxy: endpoints: '/jira/api': target: ${JIRA_BASE_URL} headers: Accept: 'application/json' Content-Type: 'application/json' X-Atlassian-Token: 'no-check' Authorization: ${JIRA_TOKEN} # Must be configured in your environment jira: proxyPath: /jira/api product: cloud # Change to 'datacenter' if using Jira Datacenterwhere:
target- The base URL of your Jira instance, configured under ${JIRA_BASE_URL} in your RHDH secrets.
AuthorizationThe Jira token, configured under ${JIRA_TOKEN} in your RHDH secrets. Set the token value as one of the following values:
-
For Cloud:
Basic YourCreatedCloudToken -
For Data Center:
Bearer YourJiraToken
-
For Cloud:
Annotate catalog entities: Add the Jira project key to the
metadata.annotationssection of thecatalog-info.yamlfile for your component:apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-service annotations: jira/project-key: PROJECT jira/component: Component jira/label: UI jira/team: 9d3ea319-fb5b-4621-9dab-05fe502283e jira/custom-filter: 'reporter = "abc@xyz.com" AND resolution is not EMPTY' spec: type: website lifecycle: experimental owner: guests system: examples providesApis: [example-grpc-api]where:
jira/project-key- Required: Enter the Jira project key.
jira/component- Optional: Enter the Jira component name.
jira/label- Optional: Enter the Jira label.
jira/team- Optional: Enter the Jira team ID (not the team title).
jira/custom-filter- Optional: Enter a custom Jira Query Language (JQL) filter.
Ingest the catalog entity: Add the location of your
catalog-info.yamlto thecatalog.locationssection in the RHDHapp-config.yamlfile:catalog: locations: - type: url target: https://github.com/<owner>/<repository>/catalog-info.yamlOptional: Define metric thresholds and filters: To customize health criteria or filter issues, add the Jira Open Issues metric thresholds to your RHDH
app-config.yamlfile:scorecard: plugins: jira: open_issues: thresholds: rules: - key: success expression: '<=50' - key: warning expression: '>50' - key: error expression: '>100'where:
scorecard:plugins:jira:open_issues:thresholds- Lists the default threshold values for the Jira Open Issues metric.
Optional: Define global or custom mandatory filters that entities can override by adding the following code to your RHDH
app-config.yamlfile:scorecard: plugins: jira: open_issues: options: mandatoryFilter: Type = Task AND Resolution = Unresolved customFilter: priority in ("Critical", "Blocker")where:
mandatoryFilter-
Optional: Replaces the default filter (
type = Bug and resolution = Unresolved). customFilter-
Optional: Specifies a global custom filter. The entity annotation
jira/custom-filteroverrides this value.
Jira metrics use the following default thresholds for the Jira Open Issues (jira.open_issues) metric:
- Error: More than 100 open issues.
- Warning: More than 50 open issues.
- Success: 50 or fewer open issues.
You can customize these thresholds in your RHDH app-config.yaml file. For more information, see Scorecard metric thresholds.
7.2.4.4. Integrate OpenSSF security metrics by using Scorecards
This section describes Developer Preview features in the Scorecard plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
You can configure the OpenSSF Scorecard module to display security and compliance metrics from the OpenSSF Scorecard project in your RHDH catalog.
By default, the module fetches data from the public OpenSSF Scorecard API, which requires no authentication and supports public GitHub repositories. Alternatively, the annotation can point to any HTTPS endpoint that serves OpenSSF Scorecard JSON data, such as a self-hosted instance or a static file.
Prerequisites
- You have installed your RHDH instance.
- You have set up the Scorecard plugin.
- You have added a custom Developer Hub application configuration.
- The target repositories are publicly accessible on GitHub, or you have an alternative HTTPS endpoint that serves OpenSSF Scorecard JSON data.
Procedure
Enable the OpenSSF Scorecard module: Add the following configuration to your RHDH
dynamic-plugins-config.yamlfile:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-openssf:<tag> disabled: falsewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Annotate catalog entities: Link a component to the OpenSSF Scorecard data source by editing the
catalog-info.yamlfile for your RHDH entity and adding the required annotation as shown in the following code:apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-service annotations: openssf/scorecard-location: https://api.securityscorecards.dev/projects/github.com/_<owner>_/_<repository>_ spec: type: service lifecycle: production owner: _<your_team_name>_where:
annotations:openssf/scorecard-location-
Specifies the full URL to the OpenSSF Scorecard API endpoint for the repository. The URL must start with
https://. spec:ownerSpecifies your team name.
NoteFor organizations running a self-hosted OpenSSF Scorecard instance, replace
api.securityscorecards.devwith the URL of your instance.
Ingest the catalog entity: Add the location of your
catalog-info.yamlto thecatalog.locationssection in your RHDHapp-config.yamlfile:catalog: locations: - type: url target: https://github.com/<owner>/<repository>/catalog-info.yaml
OpenSSF metrics use the following default thresholds:
- Error: Score below 2.
- Warning: Score between 2 and 7.
- Success: Score above 7.
You can customize these thresholds in your RHDH app-config.yaml file. For more information, see Scorecard metric thresholds.
7.2.4.5. Configure file-level checks to verify repositories contain required compliance documentation
This section describes Developer Preview features in the Scorecard plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
You can configure the Scorecard filecheck module to verify that repositories contain required files such as LICENSE, CODEOWNERS, CONTRIBUTING.md, or any file that you have configured. Each configured file generates a boolean metric that reports whether the file is present or missing.
Prerequisites
- You have installed your RHDH instance.
- You have set up the Scorecard plugin.
- You have added a custom Developer Hub application configuration.
-
Your catalog entities have the
backstage.io/source-locationannotation set. This annotation is usually added automatically during catalog ingestion.
Procedure
Enable the filecheck module: Add the following configuration to your RHDH
dynamic-plugins-config.yamlfile:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-filecheck:<tag> disabled: falsewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Configure the files to check: Define which files to verify in your RHDH
app-config.yamlfile:scorecard: plugins: filecheck: files: license: LICENSE codeowners: CODEOWNERS contributing: CONTRIBUTING.md readme: README.mdwhere:
scorecard:plugins:filecheck:filesA map of file checks. Each key becomes a metric ID suffix (for example,
licenseproduces thefilecheck.licensemetric) and each value is the relative file path to check within the repository.ImportantFile paths must be relative. Do not use a leading
/,./, or../prefix in the path. When no files are configured, no metrics are registered and the module is inactive.
Optional: Customize the collection schedule: By default, the filecheck module collects metrics every hour. To override the schedule, add the following configuration to your RHDH
app-config.yamlfile:scorecard: plugins: filecheck: schedule: frequency: cron: '0 6 * * *' timeout: minutes: 5 initialDelay: seconds: 5NoteAll configured file checks share one schedule. The module fetches each entity’s repository tree once per run and checks all configured paths in that single request.
Verify the entity annotation: Confirm that your catalog entities have the
backstage.io/source-locationannotation set:apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-service annotations: backstage.io/source-location: url:https://github.com/myorg/my-service spec: type: service lifecycle: production owner: _<your_team_name>_where:
annotations:backstage.io/source-location- The entity source location. The filecheck module uses this annotation to resolve the source repository and read its file tree.
spec:ownerYour team name.
NoteThis annotation is usually added automatically during catalog ingestion. If your entities are already registered in the catalog, this annotation is likely already present.
Filecheck metrics use the following default thresholds:
- exist: File is present (success).
- missing: File is absent (error).
You can customize these thresholds in your RHDH app-config.yaml file. For more information, see Scorecard metric thresholds.
7.2.4.6. Disable specific scorecard metrics per entity
You can disable specific scorecard metrics for an individual catalog entity by adding an annotation to its catalog-info.yaml file. This applies to metrics from any provider, including GitHub, Jira, and OpenSSF. Disabled metrics are not calculated.
Prerequisites
- You have installed your RHDH instance.
- You have set up the Scorecard plugin.
Procedure
Add the
scorecard.io/disabled-metricsannotation to thecatalog-info.yamlfile for your RHDH entity:metadata: annotations: scorecard.io/disabled-metrics: openssf.maintained,filecheck.readme,filecheck.licensewhere:
scorecard.io/disabled-metrics- Enter a comma-separated list of metric IDs to disable for this entity. You can use IDs from any provider. For available values, see Available scorecard metric providers and metric IDs.
Additional resources
7.2.4.7. Disable scorecard metrics globally
You can disable specific scorecard metrics globally across all catalog entities, and control whether entity owners can disable additional metrics by using annotations.
Prerequisites
- You have installed your RHDH instance.
- You have set up the Scorecard plugin.
- You have added a custom Developer Hub application configuration.
Procedure
Add the following configuration to your RHDH
app-config.yamlfile:scorecard: disabledMetrics: - openssf.packaging entityAnnotations: disabledMetrics: enabled: true except: - openssf.maintainedwhere:
disabledMetrics- Enter a list of metric IDs to disable globally. Metrics in this list are always skipped and cannot be overridden by entity annotations. For available values, see Available scorecard metric providers and metric IDs.
entityAnnotations.disabledMetrics.enabled-
Enter
trueto allow entity owners to disable metrics by using thescorecard.io/disabled-metricsannotation. Enterfalseto prevent entity owners from disabling metrics. Defaults totrue. entityAnnotations.disabledMetrics.except-
Enter a list of metric IDs that entity owners cannot disable, even when
enabledistrue. Use this to ensure critical metrics always run.
7.2.5. Manage metric thresholds
7.2.5.1. Manage metric thresholds
Define threshold rules that categorize metric values into pass, warning, and fail states. Threshold management controls how Scorecards evaluate component health and flag noncompliant services.
7.2.5.2. Metric categorization criteria
A threshold defines conditions or expressions to assign metric values to specific visual categories.
To categorize metric values accurately, you must follow the following evaluation rules:
- Sequential evaluation: The system processes threshold rules in the order you define them and applies only the first matching rule.
- Restrictive ordering: You must sequence rules from the most restrictive range to the least restrictive range to verify that the system assigns categories correctly.
-
Supported categories: Use only the
success,warning, anderrorkeys to define thresholds.
7.2.5.3. Threshold expression syntax
Metric threshold expressions use mathematical and logical operators to evaluate data. Use the following operators to define health criteria based on the metric data type.
| Metric Type | Operator | Example Expression | Job Performed |
|---|---|---|---|
|
Number |
|
|
The category applies if the value is greater than 40. |
|
Number |
|
|
The category applies if the value is between 80 and 100 (inclusive). |
|
Boolean |
|
|
The category applies if the value is exactly true. |
7.2.5.4. Resolve configuration conflicts using threshold precedence
Threshold rules follow a specific order of precedence. Higher-priority configurations override lower-priority settings, allowing you to define global defaults with entity-specific exceptions.
| Priority | Configuration Method | Location | Job Performed |
|---|---|---|---|
|
1 (Highest) |
Entity Annotations |
|
Overrides specific rules for a single component. |
|
2 (Medium) |
App Configuration |
|
Sets global rules that override provider defaults. |
|
3 (Lowest) |
Provider Defaults |
Backend Plugin Code |
Baseline rules defined by the metric source. |
7.2.5.5. Standardize metric thresholds across components
You can define global thresholds in your RHDH app-config.yaml file to standardize health indicators across all components. Global configurations replace the default thresholds provided by a metric source.
If you omit a threshold category, such as success, the Scorecard plugin does not assign that category to the metric.
The following example defines thresholds for the jira.open_issues metric. These settings apply to all components using this metric unless an entity annotation overrides them.
scorecard:
plugins:
jira:
open_issues:
thresholds:
rules:
- key: success
expression: '<10' # fewer than 10 open issues
- key: warning
expression: '10-50' # Between 10 and 50 open issues
- key: error
expression: '>50' # More than 50 open issues7.2.5.6. Component-specific threshold rules
Use annotations in the catalog-info.yaml file of a component to override global threshold rules. These annotations merge with and take precedence over the global rules defined in your RHDH app-config.yaml file.
7.2.5.6.1. Annotation structure
The annotation key must use the following format: scorecard.io/{providerId}.thresholds.rules.{thresholdKey}: '{expression}'
| Element | Description | Example Annotation | Example Value |
|---|---|---|---|
|
|
Unique identifier of the metric |
|
|
|
|
The overridden category |
|
|
|
|
The new condition for the rule |
|
|
7.2.5.6.2. Example: Override global Jira thresholds
In the following example, the component overrides the warning and error rules for the jira.open_issues metric. The success rule remains unchanged from the global configuration.
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: critical-production-service
annotations:
# Changes global 'warning' from '>50' to '10-15'
scorecard.io/jira.open_issues.thresholds.rules.warning: '10-15'
# Changes global 'error' from '>100' to '>15'
scorecard.io/jira.open_issues.thresholds.rules.error: '>15'
spec:
type: service7.2.5.7. Logical flow verification
To ensure Scorecard assigns the correct health status, order rules carefully, because the evaluation stops at the first matching rule.
Evaluation order for rules- To ensure the system evaluates all values correctly, sequence rules from the most strict (smallest range) value to the least strict (largest range). If rules are ordered incorrectly, a broad rule can prevent the system from reaching stricter rules.
Problematic rule order exampleIf rules are ordered incorrectly, a less restrictive rule can prevent stricter rules from being evaluated:
-
warning: <50: Any value less than 50 triggers the warning rule and stops evaluation. -
success: <10: This rule is not evaluated because all values less than 10 have already matched the preceding warning rule.
-
Correct ordering example- The following example demonstrates the correct sequence for successes, warnings, and errors:
rules:
- key: success
expression: '<10' # Most restrictive: Only values below 10
- key: warning
expression: '10-50' # Values between 10 and 50
- key: error
expression: '>50' # Least restrictive: All values above 507.2.5.8. Configure custom severity levels and colors for Scorecard
Customizing severity thresholds and color mappings in your Scorecard configuration allows you to visualize platform metrics using your organization’s custom operational terminology.
Each custom severity threshold key requires both a corresponding icon configuration value and a color parameter configuration value. The scorecard plugin validates the YAML configuration files during application startup. Omitting either property or providing an invalid value causes an initialization failure, and the Scorecard plugin fails to function.
Prerequisites
- You have administrative access to the Red Hat Developer Hub configuration files.
- You have added a custom application configuration file to your Red Hat Developer Hub deployment workspace.
- You have installed Scorecard backend and frontend plugins, and at least one Scorecard plugin module.
Procedure
-
Open the RHDH
app-config.yamlfile. -
Navigate to the
scorecard.pluginsbackend threshold definition block. Define your custom severity threshold keys by adding a structured rule entry containing your custom key string, your boundary expression, your preferred color parameter format, and a supported icon string variable.
scorecard: plugins: myDatasource: myMetric: thresholds: rules: - key: ideal expression: '<10' color: '#5CE65C' icon: star - key: warning expression: '10-50' color: 'rgb(233, 213, 2)' icon: monitor - key: critical expression: '>50' color: error.main icon: scorecardErrorStatusIconwhere:
myDatasource-
represents your specific scorecard data source, such as
jira myMetric-
represents the metric identifier, such as
open_issues
- Save the changes to the configuration file.
- Restart your Red Hat Developer Hub instance to apply the new threshold rules.
Verification
- Open the Red Hat Developer Hub UI, navigate to the Scorecard component, and verify that the custom severity levels display with the colors and icons you specified.
7.2.5.9. Scorecard color and icon configuration formats
Learn the supported color string formats and syntax rules required to map custom severity threshold keys in the configuration parser.
7.2.5.9.1. Threshold color mapping values
| Color format type | Configuration examples |
|---|---|
|
Theme palette references |
|
|
HEX hexadecimal codes |
|
|
RGB or RGBA functional strings |
|
The default threshold rules use the built-in theme palette references: success.main for success states, warning.main for warning states, and error.main for error states. You can use these standard theme indicators for custom severity levels if desired.
7.2.5.9.2. Supported threshold icon configuration formats
To determine what graphic displays in the metrics matrix block, the Scorecard plugin uses standard frontend mapping components, allowing you to specify icons using any of the following parameters.
When using Material Design strings, use only icons from the internal icon catalog, such as star or monitor. Standard upstream values that are not added, such as check, will not appear in the user interface. You can use default icons or extend the icon set with dynamic plugins.
7.2.5.9.3. Threshold icon component options
| Icon syntax layout | Value definition format examples |
|---|---|
|
Backstage system icons |
|
|
Material Design icon strings |
|
|
Inline SVG strings |
Raw XML element blocks (for example, |
|
External URLs |
|
|
Data encoded URIs |
|
The default threshold rules use pre-configured icons: scorecardSuccessStatusIcon for success rule matches, scorecardWarningStatusIcon for warning rule matches, and scorecardErrorStatusIcon for error rule matches. You can use these pre-configured icons for custom severity levels if desired.
7.2.6. Monitor component health
You can view metrics to evaluate the health and security of your software components directly in the RHDH catalog.
Prerequisites
- You have installed your RHDH instance.
- You have configured the GitHub or Jira Scorecard (or both) plugin.
-
If RBAC is enabled, you have a role with the following permission:
scorecard.metric.read.
Procedure
- In your RHDH navigation menu, go to Catalog.
- Select the software component (catalog entity) that has Scorecard metrics configured.
- On the component Service page, click the Scorecard tab.
- Select a metric tile to view detailed data.
7.3. Monitor portfolio health using aggregated Scorecard KPIs
7.3.1. Monitor portfolio health using aggregated Scorecard KPIs
Track compliance trends across your entire software portfolio by using aggregated Scorecard KPIs. Aggregated views surface systemic issues that individual component scores cannot reveal, enabling data-driven prioritization of remediation work.
7.3.2. Monitor collective health
7.3.2.1. Monitor collective health
View aggregated compliance metrics across all components owned by your team or organization. Collective health monitoring identifies portfolio-wide trends that require coordinated remediation.
7.3.2.2. Monitor portfolio health with aggregated KPIs
Use aggregated Key Performance Indicators (KPIs) to identify high-level health trends and technical risks across your portfolio. By consolidating metrics from multiple entities in the Software Catalog, you can assess the health of your entire team from a single dashboard.
To maintain RHDH performance, the Scorecard plugin fetches data from external sources on schedule and saves them to a database. Although the backend calculates KPIs in real time using this stored data, the synchronization of metrics for each entity occurs hourly by default. You have the option to customize the refresh schedule to balance your requirement for current data with the system processing load.
The aggregation endpoint (/metrics/:metricId/catalog/aggregations) summarizes metrics based on entity ownership. By default, the plugin only considers direct ownership, which includes the following entities:
- Entities you own directly.
- Entities owned by groups where you are a direct member.
The plug-in does not traverse nested group hierarchies unless you enable transitive parent group ownership.
The plugin supports simple aggregation logic, such as summing values (SUM) or calculating averages (AVERAGE) across entities.
7.3.2.3. Aggregated KPIs in the scorecard
Monitor the technical health and regulatory compliance of your infrastructure by using aggregated Key Performance Indicators (KPIs). These KPIs summarize complex data from multiple entities into a high-level overview, allowing you to identify system risks quickly.
Aggregated KPIs allow engineering and product managers to monitor the collective status of all entities the viewer owns in the Software Catalog. Instead of manually inspecting individual service scorecards, managers can use these metrics to identify broad trends or risks within their portfolio.
Aggregated metrics rely on the owner field defined in the Software Catalog entities to determine which data points to include. The scorecard plugin performs scheduled batch processing to calculate these values; therefore, aggregated data is not updated in real-time.
The plugin supports simple aggregation logic, such as summing values (SUM) or calculating averages (AVERAGE) across entities.
7.3.3. Configure aggregated Scorecard KPIs
7.3.3.1. Configure aggregated Scorecard KPIs
Configure home page cards, scheduling intervals, and retention policies for aggregated Scorecard KPIs. Aggregation settings control how frequently metrics refresh, how long historical data persists, and where summary dashboards appear.
7.3.3.2. Aggregated KPIs in the scorecard
Monitor the technical health and regulatory compliance of your infrastructure by using aggregated Key Performance Indicators (KPIs). These KPIs summarize complex data from multiple entities into a high-level overview, allowing you to identify system risks quickly.
Aggregated KPIs allow engineering and product managers to monitor the collective status of all entities the viewer owns in the Software Catalog. Instead of manually inspecting individual service scorecards, managers can use these metrics to identify broad trends or risks within their portfolio.
Aggregated metrics rely on the owner field defined in the Software Catalog entities to determine which data points to include. The scorecard plugin performs scheduled batch processing to calculate these values; therefore, aggregated data is not updated in real-time.
The plugin supports simple aggregation logic, such as summing values (SUM) or calculating averages (AVERAGE) across entities.
7.3.3.3. Configure a default scorecard aggregation card
Add a standard scorecard summary card to your homepage using default, out-of-the-box configurations.
Prerequisites
- The scorecard plugin is installed and configured in your Red Hat Developer Hub instance.
- You have administrator permissions to update application configuration files.
Procedure
- Open your dynamic plugin configuration file.
-
Navigate to your scorecard card block under the
home.page/cardsmount point. Update the configuration to use the
aggregationIdproperty with an established system metric name:- mountPoint: home.page/cards importName: ScorecardHomepageCard config: props: aggregationId: "github.open_prs" layouts: xl: { w: 3, h: 6, x: 3 } lg: { w: 4, h: 6, x: 4 } md: { w: 6, h: 6, x: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 6 } xxs: { w: 12, h: 6 }- Save the modified configuration file and restart your Red Hat Developer Hub instance.
Verification
- Access your Developer Hub homepage interface.
- Verify that the standard scorecard summary card displays with default metrics.
7.3.3.4. Configure aggregated KPIs for the scorecard
Define aggregated Key Performance Indicators (KPIs) in your configuration to provide a consolidated view of team or group health. Aggregating KPIs allows you to summarize technical metrics into high-level insights for management and stakeholders.
Prerequisites
- The scorecard plugin is installed and configured in your Red Hat Developer Hub instance.
-
You have identified the
metricIdyou want to aggregate.
Procedure
-
Access your
app-config.yamlfile. -
Navigate to the
scorecardsection and add anaggregationKPIsblock. Update the configuration to create a homepage card that summarizes a specific metric for a team portfolio. The following example adds a Jira open issues card that groups counts by threshold status for the entities that the signed-in user owns:
scorecard: aggregationKPIs: openIssuesKpi: title: 'Jira open issues KPI' description: 'Open issues across entities you own, grouped by status.' type: statusGrouped metricId: jira.open_issueswhere:
scorecard.aggregationKPIs-
Map of KPI keys to KPI definitions. Each key is an aggregation ID. For example
openIssuesKpi. title- Title shown for the KPI.
description- Short description of the KPI.
type-
Aggregation strategy. Use
statusGroupedfor counts per threshold status, oraveragefor a weighted portfolio score. metricId-
Metric provider ID. For example
jira.open_issues,github.open_prs.
- Save the configuration and restart your Red Hat Developer Hub instance.
Verification
- Navigate to the Developer Hub homepage.
- Verify that the new aggregated card is displayed with the defined name and calculated value.
7.3.3.5. Configure an aggregation card with a status-grouped tracking type
Configure a scorecard aggregation card to count entities based on status thresholds.
Prerequisites
- The scorecard plugin is installed and configured in your Red Hat Developer Hub instance.
Procedure
-
Open your
app-config.yamlfile. Navigate to the
scorecardsection and define your backend Key Performance Indicator (KPI) map within anaggregationKPIsblock, setting the tracking type tostatusGrouped:scorecard: aggregationKPIs: team-alpha-bugs: title: "Team Alpha Bug KPI" description: "Portfolio bug counts grouped by status threshold" type: statusGrouped metricId: jira.open_issues- Open your dynamic plugin configuration file.
Reference your custom aggregation ID inside the homepage card properties block under the
home.page/cardsmount point:- mountPoint: home.page/cards importName: ScorecardHomepageCard config: props: aggregationId: "team-alpha-bugs" layouts: xl: { w: 3, h: 6 } lg: { w: 4, h: 6 } md: { w: 6, h: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 6 } xxs: { w: 12, h: 6 }- Save the modified configuration files and restart your Red Hat Developer Hub instance.
Verification
- Access your Developer Hub homepage interface.
- Verify that the status-grouped scorecard summary card displays with your defined title and calculations.
7.3.3.6. Configure an aggregation card with an average tracking type
Configure a scorecard aggregation card to calculate a single weighted portfolio score across multiple components.
Prerequisites
- The scorecard plugin is installed and configured in your Red Hat Developer Hub instance.
Procedure
-
Open your
app-config.yamlfile. -
Navigate to the
scorecardsection and define your backend Key Performance Indicator (KPI) map within anaggregationKPIsblock, setting the tracking type toaverage. Add the required
statusScoresmap to bind numeric weights to your status rules:scorecard: aggregationKPIs: portfolio-average-health: title: "Portfolio Health KPI" description: "Weighted average score across portfolio components" type: average metricId: github.open_prs options: statusScores: success: 100 warning: 50 error: 0Optional: To override the built-in system defaults, add custom threshold parameters using a continuous, gapless number range evaluated on a scale of
0to100:options: statusScores: success: 100 warning: 50 error: 0 thresholds: rules: - key: success expression: '>=80' color: '#6bb300' - key: warning expression: '51-80' color: 'rgb(224, 189, 108)' - key: error expression: '<51' color: '#be1ec7' - key: critical expression: '<10' color: '#ff0000'- Open your dynamic plugin configuration file.
Reference your average tracking aggregation ID inside the homepage card properties block under the
home.page/cardsmount point:- mountPoint: home.page/cards importName: ScorecardHomepageCard config: props: aggregationId: "portfolio-average-health" layouts: xl: { w: 3, h: 6 } lg: { w: 4, h: 6 } md: { w: 6, h: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 6 } xxs: { w: 12, h: 6 }- Save the modified configuration files and restart your Red Hat Developer Hub instance.
Verification
- Access your Developer Hub homepage interface.
- Verify that the weighted average scorecard summary card displays with your custom scores and thresholds.
7.3.3.7. Configure portfolio health
7.3.3.7.1. Configure portfolio health
Add portfolio health cards to the Red Hat Developer Hub home page to display aggregated compliance summaries. Card placement depends on whether you use a customizable or read-only home page layout.
7.3.3.7.2. Configure on a customizable home page
You can add the aggregated Scorecard widget to a customizable RHDH home page to monitor the collective technical health of your portfolio.
Prerequisites
- You established owner group relationships in the Software Catalog.
- You have installed the Scorecard plugin.
-
You have the
scorecard.metric.readpermission. - You have added a custom Developer Hub application configuration.
Procedure
Update your RHDH
app-config.yamlwith the following code:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:<tag> disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-scorecard: entityTabs: - path: "/scorecard" title: Scorecard mountPoint: entity.page.scorecard mountPoints: - mountPoint: entity.page.scorecard/cards importName: EntityScorecardContent config: layout: gridColumn: 1 / -1 - mountPoint: home.page/cards importName: ScorecardHomepageCard config: id: "scorecard-jira.open_issues" title: "Jira open blocking tickets" props: metricId: "jira.open_issues" - mountPoint: home.page/cards importName: ScorecardHomepageCard config: id: "scorecard-github.open_prs" title: "GitHub open PRs" props: metricId: "github.open_prs" - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-dynamic-home-page: dynamicRoutes: - path: / importName: DynamicCustomizableHomePagewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
For more information, see Customizing Red Hat Developer Hub.
- Log in to the RHDH application.
- Enter the Edit mode on the home page.
Click Add widget and select the metric to include.
NoteYou can add only one metric at a time.
- Drag the widget to your preferred layout position.
- Click Save.
Verification
- Log in to RHDH.
- On the Home page, verify that the aggregated Scorecard widget appears with the name you provided.
- Confirm that the displayed KPIs reflect the status of your owned components, systems, and resources.
7.3.3.7.3. Configure on a read-only home page
You can add the aggregated Scorecard widget to a read-only RHDH home page to monitor the collective technical health of your portfolio.
Prerequisites
- You established owner group relationships in the Software Catalog.
- You have installed the Scorecard plugin.
-
You have the
scorecard.metric.readpermission. - You have added a custom Developer Hub application configuration.
Procedure
-
Open your RHDH
app-config.yamlfile. For more information, see Configuring Red Hat Developer Hub. Add the aggregated Scorecard mount points to the dynamic plugin configuration file:
plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:<tag> disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-scorecard: entityTabs: - path: "/scorecard" title: Scorecard mountPoint: entity.page.scorecard mountPoints: - mountPoint: entity.page.scorecard/cards importName: EntityScorecardContent config: layout: gridColumn: 1 / -1 - mountPoint: home.page/cards importName: ScorecardHomepageCard config: props: aggregationId: "jira.open_issues" layouts: xl: { w: 3, h: 6 } lg: { w: 4, h: 6 } md: { w: 6, h: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 6 } xxs: { w: 12, h: 6 } - mountPoint: home.page/cards importName: ScorecardHomepageCard config: props: aggregationId: "github.open_prs" layouts: xl: { w: 3, h: 6, x: 3 } lg: { w: 4, h: 6, x: 4 } md: { w: 6, h: 6, x: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 6 } xxs: { w: 12, h: 6 } - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-dynamic-home-page: dynamicRoutes: - path: / importName: DynamicHomePagewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
NoteThe widget automatically calculates and displays aggregations for the entities you own. You do not have to manually configure filters or specify target owner groups in the widget settings.
Verification
- Log in to RHDH.
- On the Home page, verify that the aggregated Scorecard widget appears with the name you provided.
- Confirm that the displayed KPIs reflect the status of your owned components, systems, and resources.
7.3.3.7.4. Configure a default scorecard aggregation card
Add a standard scorecard summary card to your homepage using default, out-of-the-box configurations.
Prerequisites
- The scorecard plugin is installed and configured in your Red Hat Developer Hub instance.
- You have administrator permissions to update application configuration files.
Procedure
- Open your dynamic plugin configuration file.
-
Navigate to your scorecard card block under the
home.page/cardsmount point. Update the configuration to use the
aggregationIdproperty with an established system metric name:- mountPoint: home.page/cards importName: ScorecardHomepageCard config: props: aggregationId: "github.open_prs" layouts: xl: { w: 3, h: 6, x: 3 } lg: { w: 4, h: 6, x: 4 } md: { w: 6, h: 6, x: 6 } sm: { w: 12, h: 6 } xs: { w: 12, h: 6 } xxs: { w: 12, h: 6 }- Save the modified configuration file and restart your Red Hat Developer Hub instance.
Verification
- Access your Developer Hub homepage interface.
- Verify that the standard scorecard summary card displays with default metrics.
7.3.3.8. Schedule metrics
To balance data freshness with system performance and API rate limits, you can customize the collection frequency for Scorecard metrics. Scorecard uses the Backstage built-in scheduler service. The default refresh frequency is hourly, but you can adjust it for each metric.
Prerequisites
- You have added a custom Developer Hub application configuration.
-
You have identified the
datasourceIdandmetricNamefor the provider you want to configure.
Procedure
-
Open your RHDH
app-config.yamlfile. -
Navigate to the
scorecard.pluginssection. Add a schedule configuration for your specific data source and metric using the following structure:
scorecard: plugins: my_datasource: example_metric: schedule: frequency: cron: '0 6 * * *' timeout: minutes: 5 initialDelay: minutes: 1-
Define the schedule parameters based on the
Backstage SchedulerServiceTaskScheduleDefinitionConfigschema. - Save the file.
Restart the RHDH backend to apply the changes.
ImportantConstraints: You must make sure the configured frequency does not exceed the API rate limits of your metric provider.
Verification
- Review the backend logs to make sure the task is scheduled without errors.
- Verify that new metric data appears in the database according to the defined interval.
7.3.3.9. Adjust metric retention
To manage storage capacity and comply with data retention policies, adjust the number of days the Scorecard plugin retains metric data to align with your organization’s policies. By default, the system retains metrics for 365 days.
Prerequisites
Procedure
-
Open your RHDH
app-config.yamlfile. In the
scorecardsection, add or update thedataRetentionDaysparameter with the desired number of days:scorecard: dataRetentionDays: 12
- Save the file.
- Restart the RHDH backend to apply the changes.
Verification
- Review the backend logs during the next scheduled cleanup cycle to make sure the job runs without errors.
- Query the database to confirm that records older than your specified limit are removed.
7.3.3.10. Establish ownership in the software catalog
To enable automatic metric aggregation in the Scorecard plugin, you must establish ownership relationships between users, groups, and components in the Software Catalog. The Scorecard plugin uses these definitions to calculate health trends based on who owns the entities.
When you implement the following examples, you must replace the placeholder values with your specific project details.
Group entity-
The
Groupentity defines a team within a specific namespace.
apiVersion: backstage.io/v1alpha1 kind: Group metadata: name: _<example_team>_ namespace: _<your_namespace>_ spec: type: team children: [user:_<your_namespace>_/userName]
User entity-
The
Userentity defines an individual and establishes their team membership by using thememberOffield.
apiVersion: backstage.io/v1alpha1
kind: User
metadata:
name: userName
title: Example User
spec:
profile:
displayName: Example User
memberOf: [group:_<your_namespace>_/example-team]Component entities-
The
Componentspecification defines the owner to include the component in a user’s or team’s aggregated metrics.
# Example of user ownership
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: _<user_owned_service>_
annotations:
github.com/_<your_project_name>_: example-org/example-repository
jira/project-key: ET
spec:
type: service
owner: user:_<your_namespace>_/userName
lifecycle: production# Example of group ownership
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: _<group_owned_service>_
annotations:
github.com/_<your_project_name>_: example-org/example-repository
jira/project-key: ET
spec:
type: service
owner: group:_<your_namespace>_/_<example_team>_
lifecycle: production7.3.3.11. View aggregated metrics for owned entities
View aggregated metrics for your owned entities in RHDH to monitor the collective health of your software portfolio. The Scorecard plugin consolidates these metrics based on your ownership definitions in the Software Catalog.
Prerequisites
- (To view aggregated KPIs) You have established owner group relationships in the Software Catalog.
- You have added a custom Developer Hub application configuration.
-
You have the
catalog.entity.readpermission for the entities included in the aggregation. -
You have the
scorecard.metric.readpermission to view aggregated metrics on the home page.
Procedure
- Navigate to your RHDH home page.
- Locate the Scorecard dashboard to view the aggregated metrics for your owned entities.
- Optional: To include entities from a nested group hierarchy in the aggregation, you must enable transitive parent group ownership.
Verification
- Confirm that the displayed Key Performance Indicators (KPIs) reflect the status of all components, systems, and resources defined under your ownership in the Software Catalog.
7.3.3.12. Scorecard card configuration parameters
Parameters for application settings and dynamic plugin files used to manage homepage visualizations and portfolio data logic.
7.3.3.12.1. Dynamic plugin properties
| Property | Description |
|---|---|
|
|
The target identifier for the homepage visualization block. Accepts a default system metric name string or a custom KPI key mapped in your core settings. |
|
|
[Deprecated] Legacy identifier for the source metric string. Supported for backwards compatibility but scheduled for removal in a future release. Replace with |
7.3.3.12.2. Application configuration properties (scorecard.aggregationKPIs)
| Property | Description |
|---|---|
|
|
The primary textual label rendered on the header block of the homepage card. |
|
|
A brief text string summarizing the target scope of the KPI. |
|
|
The structural tracking strategy. Specify |
|
|
The unique provider identifier mapping to the individual source plugin collection layer. |
7.3.3.12.3. Options parameters for the average tracking type
options.statusScores-
Map of threshold status rule keys (
success,warning,error) to numeric weight integers. This parameter is required for theaveragetype and must be non-empty; missing or empty maps cause application startup failures. options.thresholds-
Optional numeric value array tracking custom status levels evaluated against the
averageScoreoutput value on a scale from 0 to 100 with one decimal place. If omitted, the system falls back to default values: less than 30 indicates an error, 30 to 79 indicates a warning, and 80 or higher indicates a success. Custom configurations must provide full real-line range coverage with no numeric gaps.
7.3.4. Identify services impacting team compliance KPIs
7.3.4.1. Identify services impacting team compliance KPIs
Query the Scorecard REST API to retrieve metric data and identify which services drive down team compliance scores. Programmatic access enables integration with external dashboards, alerting systems, and automated remediation workflows.
7.3.4.2. View detailed metrics from aggregated scorecard KPIs
Configure the Red Hat Developer Hub Scorecard plugin to enable drill-down capabilities. This allows you to investigate the specific catalog entities and metrics that contribute to aggregated KPI scores, helping to identify and troubleshoot failing applications across a portfolio.
Prerequisites
- You have installed Red Hat Developer Hub.
- You have configured at least one Scorecard metric provider, such as GitHub or Jira.
- You have configured aggregated KPIs.
Procedure
Define the metric ID for drill-down in your
app-config.yamlfile.Drill-downs are metric-scoped. Even when you click an aggregated KPI, the system requires the underlying
metricIdto query the catalog for related entities.jira: product: cloud baseUrl: ${JIRA_URL} token: ${JIRA_TOKEN} scorecard: plugins: jira: open_issues: schedule: frequency: { minutes: 5 } timeout: { minutes: 10 } initialDelay: { seconds: 10 }Configure Role-Based Access Control (RBAC) permissions for the relevant user roles to enable scorecard access.
-
Open your RBAC policy file, typically
rbac-policy.csv. Add the following permission to read both scorecard metrics and catalog entities.
p, role:default/team_lead, scorecard.metric.read, read, allow p, role:default/team_lead, catalog.entity.read, read, allow
-
Open your RBAC policy file, typically
Verification
- Navigate to the Red Hat Developer Hub Home Page.
- Click an aggregated KPI tile, such as Critical Jira Issues.
Verify that a list of individual catalog entities appears, showing the components contributing to that aggregate score.
If the list does not appear, ensure you are using the latest version of the RHDH plugins.
7.3.4.3. API endpoints and parameter details
REST API endpoints for the scorecard plugin used to fetch portfolio evaluations and component summaries.
7.3.4.3.1. Required permissions
To use these endpoints, make sure your account has the following permissions:
-
scorecard.metric.read -
catalog.entity.read(for the specific entities you intend to query)
7.3.4.3.2. Supported REST API endpoints
| Method and endpoint | Description | Status |
|---|---|---|
|
|
Retrieves all base metrics collected by the plugin environment. |
Active |
|
|
Retrieves the latest metric values for a specific catalog entity. |
Active |
|
|
Retrieves calculated summary parameters for a targeted portfolio grouping definition. |
Active |
|
|
Retrieves aggregated summary parameters for a specified entity grouping path. |
Deprecated |
The endpoint GET /metrics/:metricId/catalog/aggregations is deprecated. Update your platform integrations to use the new route path structure: GET /aggregations/:aggregationId.
7.3.4.3.3. API parameter definitions
aggregationId- The unique identification key tracking a targeted scorecard summary layout block.
metricId- The unique provider key tracking an individual metrics collection channel source layer.
7.3.4.3.4. Filtering metrics (GET /metrics)
Use these parameters to refine the list of metrics.
You must not use both parameters in the same request.
| Parameter | Type | Required | Description |
|---|---|---|---|
|
|
String |
No |
A comma-separated list of IDs (for example, |
|
|
String |
No |
Filter by the source ID (for example, |
7.3.4.3.5. Identifying entities (GET /metrics/catalog/…)
Use path parameters to specify an entity in the Software Catalog.
| Parameter | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
The entity type (for example, |
|
|
String |
Yes |
The entity namespace (for example, |
|
|
String |
Yes |
The specific name of the entity. |
7.3.4.3.6. Troubleshooting API errors
If a request fails, the API returns a status code and a message. Use the following table to resolve common issues.
| Status code | Error message | Resolution |
|---|---|---|
|
400 Bad Request |
Validation error |
Make sure you are not using |
|
403 Forbidden |
Permission denied |
Verify that you have both |
|
404 Not Found |
User entity reference not found |
Verify that your user account has a defined entity reference in the Software Catalog. |
7.3.4.4. Available metric data for entities
Use the Scorecard API endpoints to list available metrics, retrieve values for specific catalog entities, and analyze performance trends for entities or aggregated groups.
7.3.4.4.1. Required permissions
To use these endpoints, make sure your account has the following permissions:
-
scorecard.metric.read -
catalog.entity.read(for the specific entities you intend to query)
7.3.4.4.2. API overview
The following table summarizes the available endpoints and their primary functions.
| Endpoint | Description | Query parameters |
|---|---|---|
|
|
Retrieves a list of all available metrics. |
|
|
|
Retrieves the latest metric values for a specific catalog entity. |
|
|
|
Retrieves status counts (success, warning, error) for entities you own. |
None |
7.3.4.4.3. API parameter details
Filtering metrics (GET /metrics)- Use these parameters to refine the list of metrics.
You must not use both parameters in the same request.
| Parameter | Type | Required | Description |
|---|---|---|---|
|
|
String |
No |
A comma-separated list of IDs (for example, |
|
|
String |
No |
Filter by the source ID (for example, |
Identifying entities (GET /metrics/catalog/…)- Use path parameters to specify an entity in the Software Catalog.
| Parameter | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
The entity type (for example, |
|
|
String |
Yes |
The entity namespace (for example, |
|
|
String |
Yes |
The specific name of the entity. |
7.3.4.4.4. Troubleshooting API errors
If a request fails, the API returns a status code and a message. Use the following table to resolve common issues.
| Status code | Error message | Resolution |
|---|---|---|
|
400 Bad Request |
Validation error |
Make sure you are not using |
|
403 Forbidden |
Permission denied |
Verify that you have both |
|
404 Not Found |
User entity reference not found |
Verify that your user account has a defined entity reference in the Software Catalog. |
7.4. Analyze platform adoption trends to measure engagement and tool popularity
7.4.1. Analyze platform adoption trends to measure engagement and tool popularity
Track user engagement, template usage, and plugin popularity to measure how effectively teams adopt Red Hat Developer Hub. Adoption metrics justify platform investments and reveal which capabilities deliver the most value to developers.
7.4.2. Adoption Insights
7.4.2.1. Adoption Insights overview
The Red Hat Developer Hub instance includes the Adoption Insights plugin preinstalled and enabled by default.
As organizations generate an increasing number of data events, there is a growing need for detailed insights into the adoption and engagement metrics of the internal developer portal. These insights help platform engineers make data-driven decisions to improve performance and usability, and convert them into actionable insights.
You can use Adoption Insights in Red Hat Developer Hub to visualize key metrics and trends to get information about the usage of Developer Hub in your organization. The information provided by Adoption Insights in Developer Hub helps you pinpoint areas of improvement, highlights popular features, and evaluates progress toward adoption goals. You can also monitor user growth against licensed users and identify trends over time.
The Adoption Insights dashboard in Developer Hub includes the following cards:
- Active users
- Total number of users
- Top catalog entities
- Top 3 templates
- Top 3 techdocs
- Top 3 plugins
- Portal searches

7.4.2.2. Enable the Adoption Insights plugin
Adoption Insights is enabled by default on Developer Hub instances. If you are migrating from a Developer Preview or you have installed Adoption Insights manually before, update your configuration.
Procedure
- Remove legacy plugins, because Adoption Insights is now built-in. Delete the following references from your dynamic-plugins.yaml file:
-
red-hat-developer-hub-backstage-plugin-adoption-insights -
red-hat-developer-hub-backstage-plugin-adoption-insights-backend -
red-hat-developer-hub-backstage-plugin-analytics-module-adoption-insights Enable the
backstage-community-plugin-analytics-provider-segmentplugin by settingdisabledtofalse:plugins: - package: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment disabled: false
7.4.2.3. Disable the Adoption Insights plugin
Disable the Adoption Insights plugin by updating the dynamic plugins configuration file.
Procedure
In your
dynamic-plugins.yamlfile, update thepackage.disabledvalue of the plugin totrue:plugins: - package: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment disabled: true
7.4.2.4. Customize the Adoption Insights plugin
Customize buffer size, flush interval, debug settings, licensed users, and RBAC permissions for the Adoption Insights plugin.
Procedure
To customize
maxBufferSize,flushInterval,debug, andlicensedUsersin the Adoption Insights plugin, in your Red Hat Developer Hubapp-config.yamlfile, update the relevant settings as shown in the following code:app: analytics: adoptionInsights: maxBufferSize: _<maximum_buffer_size>_ flushInterval: _<flush_interval>_ debug: _<debug_value>_ licensedUsers: _<licensed_users>_maxBufferSize-
(Optional) Enter the maximum buffer size for event batching. The default value is
20. flushInterval-
(Optional) Enter the flush interval in milliseconds for event batching. The default value is
5000ms. debug-
(Optional) Enter
trueto enable debug logging for the Adoption Insights plugin, orfalseto disable it. The default value isfalse. licensedUsers-
(Optional) Enter the maximum number of licensed users who can access the RHDH instance. The default value is
100.
Optional: Configure the required RBAC permission for the users who are not administrators, as shown in the following example:
p, role:default/_<your_team>_, adoption-insights.events.read, read, allow g, user:default/_<your_user>_, role:default/_<your_team>_
7.4.3. Use Adoption Insights
7.4.3.1. Use Adoption Insights
Set time ranges and navigate Adoption Insights dashboards to analyze platform engagement over specific periods. Duration controls enable comparison of adoption trends across sprints, quarters, or custom date ranges.
7.4.3.2. Use Adoption Insights in Red Hat Developer Hub
Access the Adoption Insights dashboard through the Administration menu to view usage metrics and analytics.
Procedure
- In the Developer Hub application, on the navigation menu, click Administration → Adoption Insights.
7.4.3.3. Set the duration of data metrics
Set the time range for viewing metrics data, including today, last week, last month, last 28 days, last year, or a custom date range.
You can set the data metrics duration by using any of the following time ranges:
- Today
- Last week
- Last month
- Last 28 days (default)
- Last year
- Date range…
Procedure
- On the top of the screen, click the dropdown list to display the choices.
Select the duration choice for which you want to see the data metrics.

7.4.4. View the Adoption Insights cards
7.4.4.1. View the Adoption Insights cards
Review individual Adoption Insights cards to monitor active users, top catalog entities, templates, TechDocs, and plugins. Each card provides focused visibility into a specific dimension of platform adoption.
7.4.4.2. View the Adoption Insights card
View detailed analytics through individual dashboard cards including active users, total users, and top catalog entities.
For the top catalog entities, templates, and techdocs dashboard cards:
-
The Name column displays
metadata.titleif it exists. If themetadata.titleis missing or empty, the UI falls back to themetadata.name. -
Hover over the titles to display a tooltip with
entityRef | type | description. - To avoid breaking the layout, long titles are truncated with an ellipsis.
Procedure
- Navigate to Administration → Adoption Insights to access the dashboard cards.
7.4.4.3. View active users
View the total number of active users over time, including returning and new users, and export the data in CSV format.
The Active users card displays the total number of active users over a specified date and time period. You can export the user data in a CSV format.

- Returning users
- Existing users who have logged into Developer Hub before
- New users
- New users who have registered and logged into Developer Hub for the first time
Procedure
- To view the list of active users in your Red Hat Developer Hub instance, go to Administration → Adoption Insights, and see the Active users card.
- To view the exact number of users for a particular day, hover over the corresponding date in the Active users card.
- To export the user data in CSV format, click the Export CSV link.
7.4.4.4. View total users
View the total number of licensed users, and compare logged-in users versus licensed users in numeric and percentage format.
This card displays the total number of users who have license to use Red Hat Developer Hub. It also provides a comparison of the number of Logged-in users and Licensed users in numeric and percentage form.
- Logged-in users
- Total number of users, including licensed and unlicensed users, currently logged in to Developer Hub.
- Licensed users
-
Total number of licensed users logged in to Developer Hub. You can set the target for the number of licensed users in your Developer Hub
app-config.yamlfile.
Procedure
- To view the total number of users in your Developer Hub instance in numeric and percentage forms, go to Administration → Adoption Insights and see the Total number of users card.
- To view a percentage representation of the total number of logged-in users among the total number of licensed users, hover over the tooltip in the Total number of users card.
7.4.4.5. View top catalog entities
View the most-viewed catalog entities including name, type, last used date, and total views in the Top catalog entities card.
This card lists the most-viewed catalog entities (such as components, APIs, and so on) and documentation entries, including usage statistics, in a table.
Each item displays the following details:
- Name
- Name of the catalog
- Kind
- Type of the catalog
- Last used
- The last time a user accessed the catalog entity
- Views
- The number of times users viewed the catalog entity
Procedure
- To view the most commonly used catalog entities in your Developer Hub instance, go to Administration → Adoption Insights and see the Top catalog entities card.
- To know more about the displayed catalog entity, hover over the catalog entity name.
7.4.4.6. View top templates
View the most commonly used templates including name, most frequent user type, and total executions in the Top 3 templates card.
This card lists the three most commonly used templates in a table. You can click the down arrow next to 3 rows to view the full list of the commonly used templates.
- Name
- Name of the template
- Mostly in use by
- Type of user who uses this template most often
- Executions
- Number of times users ran this template
Procedure
- To view the most commonly used templates in your Developer Hub instance, go to Administration → Adoption Insights and see the Top 3 templates card.
- To know more about the displayed template, hover over the template name.
7.4.4.7. View top TechDocs
View the most-viewed TechDocs documentation entries including name, entity type, last used date, and total views.
This card lists the most-viewed documentation entries, including the total views, in a table.
- Name
- Title of the document
- Entity
- Type of document
- Last used
- The last time a user viewed the document
- Views
- Number of times users visited the document
Procedure
- To view the most commonly used templates in your Developer Hub instance, go to Administration → Adoption Insights and see the Top 3 techdocs card.
- To learn more about the documents, hover over each name.
7.4.4.8. View top plugins
View the most commonly used plugins, including name, popularity trend, and total views in the Top 3 plugins card.
This card lists the three most commonly used plugins in a table. You can click the down arrow next to 3 rows to view the full list of the commonly used plugins.
- Name
- Name of the plugin
- Trend
- Popularity of the plugin as a graph
- Views
- Number of times users viewed this plugin
Procedure
- To view the most commonly used plugins and the plugin page visit trends in your Developer Hub instance, go to Administration → Adoption Insights and see the Top 3 plugins card.
- To know more about the displayed plugin, hover over the plugin name.
7.4.5. Change the number of displayed records
Change the number of displayed records from top 3 to top 5, 10, or 20 for catalog entities, templates, TechDocs, and plugins cards.
You can change the number of displayed records in Adoption Insights for the following cards:
- Top catalog entities
- Top 3 templates
- Top 3 techdocs
- Top 3 plugins
You can select any of the following number of records for display:
- Top 3
- Top 5
- Top 10
- Top 20
By default, the top three most-viewed catalog entities are displayed.
Procedure
Go to Administration → Adoption Insights and click the Down arrow next to 3 rows to change the number of displayed records.

7.4.6. Filter records
By default, the Top catalog entities card displays all of the items in your Developer Hub instance. Filter the Top catalog entities card to display specific entity types.
Procedure
- To view a specific catalog entity in the table, go to Administration → Adoption Insights, click the drop-down list on the Top catalog entities card, and select the item that you want to view.
7.4.7. View platform searches
View portal search trends over time, including total searches and average searches per time period in the Searches card.
In the Searches card, you can view the following data:
- Visualizes the number of portal searches and trends over time as a graph
- Displays the total for the period in the card title
- Clarifies the average number each hour/day/week/month depending on the time period chosen
Procedure
- Go to Administration → Adoption Insights to view the Searches card.
Chapter 8. Develop
8.1. Develop
Register software components, use templates to standardize projects, automate repository onboarding, and orchestrate workflows to streamline development processes.
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
The Red Hat Developer Hub Software Catalog is a centralized system that gives you visibility into all the software across your ecosystem, including services, websites, libraries, and data pipelines.
The metadata for the components in your Software Catalog is stored as YAML files that live alongside your code in your version control system. The version control repositories can include one or many metadata files. Software Catalog organizes items as entities, which include Components, Resources, and APIs, and other related types. Each entity includes associated metadata such as its owner, type, and other relevant details.
By storing metadata in YAML files alongside the code, you allow Red Hat Developer Hub to process and display this information through a clear, visual interface. With the Software Catalog, you can manage and maintain your software, stay aware of all software available in your ecosystem, and take ownership of your services and tools.
The Overview page for a component provides key information such as links to the source code, documentation, dependencies, and ownership details. You can customize this page with plugins to suit specific needs.
8.2.2. Manage your software components
8.2.2.1. Manage your software components
The Red Hat Developer Hub Software Catalog is a centralized system that gives you visibility into all the software across your ecosystem, including services, websites, libraries, and data pipelines.
The metadata for the components in your Software Catalog is stored as YAML files that live alongside your code in your version control system. The version control repositories can include one or many metadata files. Software Catalog organizes items as entities, which include Components, Resources, and APIs, and other related types. Each entity includes associated metadata such as its owner, type, and other relevant details.
By storing metadata in YAML files alongside the code, you allow Red Hat Developer Hub to process and display this information through a clear, visual interface. With the Software Catalog, you can manage and maintain your software, stay aware of all software available in your ecosystem, and take ownership of your services and tools.
The Overview page for a component provides key information such as links to the source code, documentation, dependencies, and ownership details. You can customize this page with plugins to suit specific needs.
8.2.2.2. Register new software components
8.2.2.2.1. Register new software components
You can add new components to your Red Hat Developer Hub catalog by either generating new components from software templates or registering existing repositories manually.
8.2.2.2.2. Create new components in your Red Hat Developer Hub instance
You can create new components in the Software Catalog in your RHDH instance. Red Hat Developer Hub automatically registers all components that developers or platform engineers create using Templates in the Software Catalog.
Prerequisites
- You have installed and configured the Red Hat Developer Hub instance.
-
If RBAC is enabled, you have a role with the following permissions:
catalog.entity.create,scaffolder.template.parameter.read,scaffolder.template.step.read,scaffolder.task.create.
Procedure
- In your Red Hat Developer Hub navigation menu, click Catalog.
- On the Catalog page, click Self-service.
8.2.2.2.3. Register components manually in your RHDH instance
To manually register components in your RHDH instance, create a catalog-info.yaml file and register it with your Red Hat Developer Hub instance.
Prerequisites
- You have installed and configured the Red Hat Developer Hub instance.
-
If RBAC is enabled, you have a role with the following permissions:
catalog.entity.create,catalog.location.create.
Procedure
In the root directory of your software project, create a file named
catalog-info.yaml.apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: _<your_software_component>_ description: _<software_component_brief_description>_ tags: - example - service annotations: github.com/project-slug: _<repo_link_of_your_component_to_register>_ spec: type: _<your_service>_ owner: _<your_team_name>_ lifecycle: _<your_lifecycle>_-
Commit the
catalog-info.yamlfile to the root of your project source code repository. - In your Red Hat Developer Hub navigation menu, go to Catalog > Self-service.
- On the Self-service page, click Register Existing Component.
-
On the Register an existing component page, enter the full URL of the
catalog-info.yamlfile in your repository. For example: Artist lookup component. - Complete the wizard instructions.
Verification
- Your software component is listed in the Software Catalog. You can view its details and ensure all the metadata is accurate.
8.2.2.2.4. Add new components to your Red Hat Developer Hub instance
You can add new components to expand your Developer Hub Software Catalog by registering them manually, creating them from Software Templates, or using bulk import.
Prerequisites
- You have installed and configured the Red Hat Developer Hub instance.
-
If RBAC is enabled, you have a role with the following permissions:
catalog.entity.create,catalog.location.create,bulk.import.
Procedure
Add components to your RHDH instance using the following methods:
-
Register components manually using the GUI or by using your
app-config.yamlwith the required permissions. - Create new components by using Software Templates.
-
Register components manually using the GUI or by using your
- Use the bulk import plugin with the required permissions. For more information, see Bulk importing GitHub repositories.
8.2.2.3. Update existing components in your Red Hat Developer Hub catalog
You can update components in the Software Catalog in your Red Hat Developer Hub instance.
Prerequisites
- You have installed and configured the Red Hat Developer Hub instance.
-
If RBAC is enabled, you have a role with the following permission:
catalog.entity.refresh.
Procedure
- In your Red Hat Developer Hub navigation menu, click Catalog.
Find the software component that you want to edit, under Actions, click the Edit icon.
NoteThis action redirects you to the YAML file on GitHub.
On your remote repository UI, update your YAML file.
NoteAfter you merge your changes, the updated metadata in the Software Catalog is displayed after some time.
8.2.2.4. Find components by Kind in the Red Hat Developer Hub catalog
Filter the Software Catalog to display components by their type, such as Component, API, or Template.
Prerequisites
- You are logged in to the RHDH instance.
Procedure
- In your Red Hat Developer Hub navigation menu, click Catalog.
- On the Catalog page, click the Kind drop-down list.
Select the Kind you want to filter by, such as Component, API, or Template.
NoteThe available filter lists change based on the Kind you select, showing options relevant to that entity type.
Verification
- The Catalog updates to list only the components matching the selected Kind.
8.2.2.5. Filter components by text in the Red Hat Developer Hub catalog
Search and filter components by text in the Software Catalog to quickly locate specific services, libraries, or other entities.
Procedure
- In your Red Hat Developer Hub navigation menu, click Catalog.
- In the Search field, enter a component name, description, or keyword that you are looking for.
Verification
- The Catalog list updates to display only components matching your search criteria.
8.2.2.6. Review the YAML configuration of your Red Hat Developer Hub Software Catalog
You can view the Software Catalog YAML file in your Red Hat Developer Hub instance to review the metadata for the components in your Software Catalog.
Procedure
- In your Red Hat Developer Hub navigation menu, click Catalog.
Find the software component that you want to view, under Actions, click the View icon.
NoteThese steps redirect you to the YAML file on your remote repository.
8.2.2.7. Star key components in the Software Catalog
You can add commonly used components to the Your Starred Entities card for quick access.
Procedure
- In the Red Hat Developer Hub navigation menu, select Catalog.
- Locate the components you want to add as a favorite.
- In the Actions column for that component, click the Add to favorites (star) icon.
Verification
- Navigate to the Home page and verify that the Your Starred Entities card lists the component.
8.2.3. Define software components in the catalog
Populate your software catalog by creating and configuring a YAML descriptor file that defines your application or service.
Prerequisites
- You have access to a Git repository to host your catalog files.
Procedure
-
Create a YAML file named
catalog-info.yamlin the root directory of your repository. Add the following component configuration to the file:
apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: example-service spec: type: service lifecycle: production owner: group:example-team
- Save and commit the file to your Git repository.
Verification
- Navigate to the Catalog page in the UI, filter by Component, and verify your service is visible.
8.2.4. Define APIs in the catalog
Expose your interfaces for consumption within the hub by registering an API entity.
Procedure
-
Create a YAML file named
catalog-info.yamlin your repository. Add the following API schema configuration to the file:
apiVersion: backstage.io/v1alpha1 kind: API metadata: name: example-api spec: type: openapi lifecycle: production owner: group:example-team definition: | openapi: "3.0.0" info: title: Example API version: "1.0.0" paths: {}- Save and commit the file to your Git repository.
Verification
- Navigate to the Catalog page in the UI, filter by API, and verify your endpoint definition is visible.
8.2.5. Define resources in the catalog
Track infrastructure dependencies by creating a YAML descriptor file to register a resource entity in the software catalog.
Prerequisites
- You have an active {product-title} instance.
- You have access to a Git repository to host your catalog descriptor files.
Procedure
-
Create a YAML file named
catalog-info.yamlin your project or infrastructure repository directory. Add the following resource configuration to the file:
apiVersion: backstage.io/v1alpha1 kind: Resource metadata: name: example-database spec: type: database owner: group:example-team
- Save the file and commit it to your Git repository.
Verification
- Log in to your {product-title} instance web console.
- Navigate to the Catalog page using the left sidebar menu.
- Locate the Filters panel on the left side of the catalog view and click Resource.
- Confirm that your newly defined resource appears in the filtered list.
8.2.6. Define locations in the catalog
Import multiple entity descriptors into the software catalog by creating a YAML descriptor file that defines a location entity.
Prerequisites
- You have an active {product-title} instance.
- You have access to a Git repository to host your catalog descriptor files.
Procedure
-
Create a YAML file named
catalog-info.yamlin your centralized repository folder. Add the location configuration to the file, using the
spec.targetsarray to point to your individual target configurations:apiVersion: backstage.io/v1alpha1 kind: Location metadata: name: example-location spec: type: url targets: - https://github.com/example-org/example-repo/blob/main/catalog-info.yaml- Save the file and commit it to your Git repository.
Verification
- Log in to your {product-title} instance web console.
- Navigate to the Catalog page using the left sidebar menu.
- Locate the Filters panel on the left side of the catalog view and click Location.
- Confirm that your newly defined location entity appears in the list and that the target data components are successfully discovered without validation errors.
8.2.7. Catalog entity descriptor reference
Use these reference tables to identify required YAML attributes and mandatory fields for registering components in the Red Hat Developer Hub catalog.
8.2.7.1. Mandatory fields for catalog entities
The following table lists the fields required for each entity kind supported by {product-title}. If you do not provide a mandatory field, the catalog processor fails to validate the entity and throws a TypeError.
8.2.7.2. Mandatory fields by entity kind
| Entity Kind | Mandatory Fields | Practical Usage and Optional Fields |
|---|---|---|
|
Component |
|
— |
|
Template |
|
— |
|
API |
|
— |
|
Group |
|
— |
|
User |
|
— |
|
Resource |
|
— |
|
System |
|
— |
|
Domain |
|
— |
|
Location |
|
While
* |
8.2.7.3. Conditional UI behavior for component entities
The visibility of navigation tabs in the {product-title} interface is determined by the spec.type attribute or specific metadata annotations within the component descriptor.
8.2.7.4. Component UI behavior mapping
| Field or Annotation | Setting | UI Change |
|---|---|---|
|
|
|
The API tab is visible in the component interface. |
|
|
|
The API tab is hidden, but provided and consumed APIs remain visible under the Dependencies tab. |
|
|
|
The Docs tab is visible, providing access to TechDocs documentation. |
For the Docs tab to successfully render technical documentation, the TechDocs plugin must be configured correctly in your instance.
8.3. Project standardization with software templates
8.3.1. Project standardization 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.2. Create new Software Templates
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
- You have added a custom Developer Hub application configuration.
- You have a Git repository to store Software Template files.
Procedure
- Create a directory in your Git repository for the Software Template.
-
Create a file named
template.yamlin that directory. -
In the
template.yamlfile, define theapiVersion,kind, andmetadatato identify the starter kit in the software catalog. -
Add a
specsection to define theparametersthat a developer must provide when they use the Software Template. Define the
stepsrequired to generate the project, which can includefetch:templateto retrieve the skeleton andpublish:githubto create the new repository.ImportantYou must include TechDocs in your Software Templates to ensure that documentation is automatically generated for every new project created from the Software Template.
Verification
-
Inspect the
template.yamlfile to ensure the YAML syntax is valid. -
Confirm that the
nameandactionfields are defined so the template is correctly recognized as a Scaffolder task. -
Check that the defined
parametersmatch the variables used in your Software Template skeleton files. -
Navigate to the form playground at
<instance_url>/create/template-formand test the Software Template configuration to confirm the fields and logic render as intended.
8.3.3. Use sample templates
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}
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
Secrets are automatically masked in logs. They are only available to backend actions, never exposed to the frontend.
8.3.5. Extend templates using conditional logic and external fetch capabilities
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.
| Feature | Description |
|---|---|
|
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 Software Templates
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
Backstageormy-rhdh-app-configfile:-
backstage-community-plugin-catalog-backend-module-scaffolder-relation-processor-dynamic -
backstage-plugin-notifications -
backstage-plugin-notifications-backend-dynamic
-
Procedure
Make sure the required plugins are enabled in your RHDH
my-rhdh-app-configfile 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- Modify the Software Template that you want to update.
- Complete one or both of the following tasks:
-
Include the annotation in your template: Add the
backstage.io/template-versionannotation in your template metadata. When this annotation is present, it is automatically used to annotate your catalog entity and display a default version value. 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
- 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).
Check the component in the Catalog UI.
- On the Catalog page, locate the newly created catalog component.
-
Verify that the
backstage.io/template-versionannotation 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.
Only if you have published the catalog component: Check the component file in the repository.
- If VIEW SOURCE is present in your UI: Click VIEW SOURCE to open the stored component file in the repository.
-
Locate the file manually and verify that the
backstage.io/template-versionannotation is present.
8.3.6.3. Enable update notifications
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
-
backend:
Procedure
-
Open your RHDH
app-config.yamlfile. -
Add the following configuration to the
scaffoldersection to enable Software Template update notifications Optional: To customize the notification title and description, add the
messageblock:scaffolder: notifications: templateUpdate: enabled: true message: title: 'Custom title for $ENTITY_DISPLAY_NAME' description: 'Custom description'where:
enabled-
Set to
trueto enable the notification. Default value isfalse. message:title- Enter the notification title.
message:descriptionEnter the notification description.
NoteThe
message:titleandmessage:descriptionfields support the$ENTITY_DISPLAY_NAMEvariable. The system replaces this variable with the title (or the name, if the title is missing) of the scaffolded entity.
Verification
-
Log in to your
Red Hat Developer Hubinstance. - In the left navigation menu, verify that the Notifications item is displayed.
- 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 annotations
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.
Prerequisites
Procedure
-
Locate the Software Template object YAML file where you want to add the provenance information and add a step that uses the
catalog:scaffolded-fromaction. This action links the resulting catalog entity back to the source template. Optional: To track the template version (for example, v1.0 versus v1.5), include the
catalog:template:versionaction in thestepssection. The following code block is an example to adding versioning action to thestepssection: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:templateVersionReads the version parameter
NoteThe
catalog:template:versionaction reads a version parameter defined in the template and applies it as an annotation to the resulting catalog entity.
In your Red Hat Developer Hub
app-config.yamlfile, configure thecatalog.locationssection to point to the Software Template that you want to add. You might need to addTemplateto the globalcatalog.rules.allowlist 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
urltype 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
Templaterule 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.
- In the Red Hat Developer Hub navigation menu, go to Catalog and locate the newly created catalog component.
- To view the underlying data that links the entity to the template, select the INSPECT ENTITY option.
To verify provenance annotations, complete the following steps:
-
Select the YAML Raw or JSON Raw view and verify the presence of the data item for the
scaffoldedFromlink. Optional: If versioning was included, verify the presence of the
backstage.io/template-versionannotation.NoteIf 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-versionannotation.
-
Select the YAML Raw or JSON Raw view and verify the presence of the data item for the
8.3.7.3. View template dependencies in the catalog
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
- In the Red Hat Developer Hub navigation menu, click Catalog, use the filters to find and select the Software Template you want to inspect.
- 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 the scaffolder-relation-processor
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.yamlfile. -
Your scaffolded entities include the
spec.scaffoldedFromfield referencing the source template. -
Your entities include the
backstage.io/managed-by-locationannotation pointing to a valid GitHub or GitLab URL.
Procedure
Enable the template sync and notification plugins in your
RHDH dynamic-plugins.yamlfile: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-
Open your
RHDH app-config.yamlfile. Configure the pull request (PR) feature by adding the following configuration:
scaffolder: pullRequests: templateUpdate: enabled: trueOptional: Enable notifications to alert entity owners when a PR is created:
scaffolder: notifications: templateUpdate: enabled: true- Restart the Red Hat Developer Hub instance to apply the changes.
Verification
- Update the version of a source template in its repository.
- Navigate to a repository scaffolded from that template.
-
Confirm that a new pull request named
[component-name]/template-upgrade-v[version]exists.
8.3.8.3. Template sync 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-loginannotation. GitLab: Requires the
gitlab.com/user-loginannotation.If the owner is a Group, the plugin creates the PR without an assigned reviewer.
-
GitHub: Requires the
- 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 Creation | Notifications | Outcome |
|---|---|---|
|
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. |
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. Run Software Templates from the UI
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. Browse available templates
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.4. Automate repository onboarding to the catalog
8.4.1. Automate repository onboarding to the catalog
Automate onboarding of GitHub repositories and GitLab projects to Red Hat Developer Hub catalog, and monitor import status by using bulk import capabilities.
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.
8.4.2. Import source code repositories in bulk
8.4.2.1. Import source code repositories in bulk
Automate onboarding of GitHub repositories to the Red Hat Developer Hub catalog, and monitor import status by using bulk import capabilities.
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.
8.4.2.2. Repository visibility in Bulk Import
View and bulk-import only the repositories you have permission to access and have not yet added to your catalog.
8.4.2.2.1. User-scoped repository access
When you use Bulk Import, Red Hat Developer Hub retrieves the list of available repositories using your authenticated user credentials through OAuth. Repository and organization listing API calls use your OAuth token for each configured source code management (SCM) host, ensuring that results match your personal access permissions rather than server-wide integration credentials.
This approach provides several benefits:
- User-scoped access
- You see only repositories you can access in GitHub or GitLab, matching your experience in those platforms.
- Enhanced security
- Import operations use your personal access token, maintaining audit trails tied to your user account.
- Permission alignment
- Repository visibility respects your organizational access policies and role-based permissions.
This differs from catalog discovery providers, which use service account credentials to automatically discover and import repositories containing catalog-info.yaml files across an entire organization.
8.4.2.2.2. Technical implementation
Bulk Import requires user authentication for all repository and organization listing operations. The following API endpoints require a valid OAuth token:
-
GET /repositories- List all accessible repositories -
GET /organizations/{org}/repositories- List repositories in a specific organization
These endpoints use the X-SCM-Tokens header to pass user OAuth tokens for GitHub and GitLab hosts. There is no fallback to server-wide integration credentials (GitHub App, PAT, or GitLab token) for these listing operations. Requests without valid user OAuth tokens are rejected with HTTP 401 Unauthorized.
Deployments that previously relied on integration-only listing must configure SCM authentication providers for user authentication. See the Bulk Import plugin documentation for configuration details.
8.4.2.2.3. Automatic filtering of imported repositories
The Bulk Import interface automatically excludes repositories that are already present in your Developer Hub catalog, showing only repositories that have not yet been imported. This filtering helps you:
- Avoid duplicate catalog entries.
- Focus on new repositories that need onboarding.
- Identify which repositories remain to be imported from your Git provider.
If a repository is removed from the catalog, it will reappear in the Bulk Import repository list and can be imported again.
8.4.2.2.4. Prerequisites for repository visibility
User authentication with OAuth is a mandatory requirement for the Bulk Import feature. To view and import repositories through Bulk Import, you must:
Configure GitHub or GitLab authentication using one of the following approaches:
- As your primary authentication provider for Developer Hub.
- As an auxiliary authentication provider if you use another primary provider, for example, OIDC or Red Hat build of Keycloak.
- Configure SCM authentication providers with OAuth support for your Git hosts
-
Have the
bulk.importpermission configured in RBAC policies. - Maintain an active OAuth session with your Git provider.
Repository and organization listing operations require user OAuth tokens. There is no fallback to server-wide integration credentials. Deployments without user authentication configured will receive HTTP 401 errors when accessing Bulk Import.
8.4.2.2.5. Troubleshooting repository visibility
If you cannot see expected repositories in the Bulk Import interface, verify the following:
- User access
- Your user account has access to those repositories in GitHub or GitLab
- Catalog status
- The repositories are not already imported into the Developer Hub catalog
- Session validity
- Your Developer Hub OAuth session has not expired
- Authentication configuration
- GitHub or GitLab authentication provider is correctly configured
- ScmAuthApi registration
-
The
ScmAuthApiis properly registered for your SCM hosts
If you receive HTTP 401 Unauthorized errors when accessing the Bulk Import page, this indicates that user OAuth tokens are not available. Verify that:
- You have authenticated to Developer Hub using GitHub or GitLab as your authentication provider
- Your authentication provider includes OAuth scopes required for repository access
- The SCM authentication provider is configured and registered in your Developer Hub deployment
8.4.2.3. Enable and authorize Bulk Import capabilities in Red Hat Developer Hub
Enable Bulk Import plugins and configure RBAC permissions to allow users to import multiple GitHub repositories and GitLab projects into the catalog.
Prerequisites
- You have configured user authentication with GitHub or GitLab as your authentication provider. This is a mandatory requirement for Bulk Import, as repository listings use user OAuth tokens.
- You have configured the GitHub or GitLab integration.
- For GitHub only: You have enabled GitHub repository discovery.
Bulk Import requires user OAuth tokens for all repository and organization listing operations. Deployments without user authentication configured will receive HTTP 401 Unauthorized errors when accessing the Bulk Import feature.
Procedure
The Bulk Import plugins are installed but disabled by default. To enable the
./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamicand./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-importplugins, edit yourdynamic-plugins.yamlwith the following content:plugins: - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import-backend-dynamic disabled: false - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-bulk-import disabled: falseSee Installing and viewing plugins in Red Hat Developer Hub.
Configure the required
bulk.importRBAC permission for the users who are not administrators as shown in the following code:rbac-policy.csvfragmentp, role:default/bulk-import, bulk.import, use, allow g, user:default/<your_user>, role:default/bulk-importNote that only Developer Hub administrators or users with the
bulk.importpermission can use the Bulk Import feature. See Permission policies in Red Hat Developer Hub.
Verification
- The sidebar displays a Bulk Import option.
- The Bulk Import page shows a list of added GitHub repositories and GitLab projects.
8.4.2.4. Import multiple GitHub repositories
Select and import multiple GitHub repositories that you can access into the Red Hat Developer Hub catalog, automatically creating pull requests with required catalog-info.yaml files.
Prerequisites
The Bulk Import feature displays only repositories that your GitHub user account can access and that are not already imported into the Developer Hub catalog. Repository visibility is determined by your GitHub permissions, not the Developer Hub GitHub App configuration.
Procedure
- Click Bulk Import in the Developer Hub left sidebar.
If your RHDH instance has multiple source control tools configured, select GitHub from the Source control tool list.
The interface displays GitHub repositories that your authenticated user account can access, excluding repositories already present in the catalog.
Select the repositories to import, and click Add.
Developer Hub creates a pull request in each selected repository to add the required
catalog-info.yamlfile using your GitHub credentials.- For each repository to import, click PR to review and merge the changes in GitHub.
Verification
- Click Bulk Import in the Developer Hub left sidebar.
- Verify that each imported GitHub repository in the Selected repositories list has the status Waiting for approval or Imported.
For each Waiting for approval repository, click the pull request link to review and merge the
catalog-info.yamlfile in the corresponding repository.The pull request is created using your GitHub user account, ensuring proper attribution in the repository history.
8.4.2.5. Import multiple GitLab repositories
Select and import multiple GitLab projects that you can access into the Red Hat Developer Hub catalog, automatically creating merge requests with required catalog-info.yaml files.
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 enabled the Bulk Import feature and configured access permissions.
- You have authenticated to Developer Hub using GitLab as your authentication provider.
- You have set up a GitLab personal access token (PAT).
You configured the GitLab integration by adding the following section to your RHDH
app-config.yamlfile:integrations: gitlab: - host: ${GITLAB_HOST} token: ${GITLAB_TOKEN}You enabled the GitLab catalog provider plugin in your
dynamic-plugins.yamlfile to import GitLab users and groups:plugins: - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-gitlab-org-dynamic' disabled: false
The Bulk Import feature displays only projects that your GitLab user account can access and that are not already imported into the Developer Hub catalog. Project visibility is determined by your GitLab permissions, not the Developer Hub GitLab integration token configuration.
Procedure
- In the Developer Hub left sidebar, click Bulk Import.
If your RHDH instance has multiple source control tools configured, select GitLab from the Source control tool list.
The interface displays GitLab projects that your authenticated user account can access, excluding projects already present in the catalog.
Select the projects to import, and click Add.
Developer Hub creates a merge request in each selected project to add the required
catalog-info.yamlfile using your GitLab credentials.- For each project to import, click MR to review and merge the changes in GitLab.
Verification
- Click Bulk Import in the Developer Hub left sidebar.
- Verify that each imported GitLab project in the Selected projects list has the status Waiting for approval or Imported.
For projects with the Waiting for approval status, click the merge request link to review and add the
catalog-info.yamlfile to the project repository.The merge request is created using your GitLab user account, ensuring proper attribution in the project history.
8.4.2.6. Manage imported repositories
You can oversee and manage the Git repositories that are imported to Developer Hub.
Prerequisites
- You have imported GitHub repositories.
Procedure
Click Bulk Import in the left sidebar to display all the current GitHub repositories and GitLab projects that are being tracked as Import jobs, along with their status.
- Added
-
The Git repository is added to the Developer Hub catalog after the import pull request is merged or if the Git repository already contained a
catalog-info.yamlfile during the bulk import. It can take a few minutes for the entities to be available in the catalog. - Waiting for approval
-
There is an open pull request or merge request adding a
catalog-info.yamlfile to the GitHub repository or GitLab project. You can:
- Click pencil icon on the right to see details about the pull request or merge request. You can use the detailed view to edit the request content right from Developer Hub.
- Delete the Import job, this action closes the import pull request or merge request as well.
To move the Import job to the Added state, merge the import pull request or merge request from the Git repository.
- Empty
Developer Hub is unable to determine the import job status because the Git repository is imported from other sources but does not have a
catalog-info.yamlfile and lacks any import pull or merge request adding it.Note- After an import pull request or merge request is merged, the import status is marked as Added in the list of Added entities, but it might take a few seconds for the corresponding entities to appear in the Developer Hub Catalog.
A location added through other sources (for example, statically in an
app-config.yamlfile, dynamically when enabling GitHub discovery, or registered manually using the "Register an existing component" page) might show up in the Bulk Import list of Added Repositories if the following conditions are met:-
The location URL points to a
catalog-info.yamlfile at the root of the Git repository default branch. - For GitHub only: The target repository is accessible from the configured GitHub integrations.
-
The location URL points to a
8.4.2.7. Monitor Bulk Import actions using audit logs
Review Bulk Import backend plugin audit log events to monitor repository import operations, track API requests, and troubleshoot import issues.
Procedure
- Access your Developer Hub backend logs where audit log events are recorded.
Review the following Bulk Import audit log events to monitor repository operations:
BulkImportUnknownEndpoint- Tracks requests to unknown endpoints.
BulkImportPing-
Tracks
GETrequests to the/pingendpoint, which allows us to make sure the bulk import backend is up and running. BulkImportFindAllOrganizations-
Tracks
GETrequests to the/organizationsendpoint, which returns the list of organizations accessible from all configured GitHub Integrations. BulkImportFindRepositoriesByOrganization-
Tracks
GETrequests to the/organizations/:orgName/repositoriesendpoint, which returns the list of repositories for the specified organization (accessible from any of the configured GitHub Integrations). BulkImportFindAllRepositories-
Tracks GET requests to the
/repositoriesendpoint, which returns the list of repositories accessible from all configured GitHub Integrations. BulkImportFindAllImports-
Tracks
GETrequests to the/importsendpoint, which returns the list of existing import jobs along with their statuses. BulkImportCreateImportJobs-
Tracks
POSTrequests to the/importsendpoint, which allows to submit requests to bulk-import one or many repositories into the Developer Hub catalog, by eventually creating import pull requests in the target repositories. BulkImportFindImportStatusByRepo-
Tracks
GETrequests to the/import/by-repoendpoint, which fetches details about the import job for the specified repository. BulkImportDeleteImportByRepoTracks
DELETErequests to the/import/by-repoendpoint, which deletes any existing import job for the specified repository, by closing any open import pull request that could have been created.Example audit log output:
{ "actor": { "actorId": "user:default/myuser", "hostname": "localhost", "ip": "::1", "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36" }, "eventName": "BulkImportFindAllOrganizations", "isAuditLog": true, "level": "info", "message": "'get /organizations' endpoint hit by user:default/myuser", "meta": {}, "plugin": "bulk-import", "request": { "body": {}, "method": "GET", "params": {}, "query": { "pagePerIntegration": "1", "sizePerIntegration": "5" }, "url": "/api/bulk-import/organizations?pagePerIntegration=1&sizePerIntegration=5" }, "response": { "status": 200 }, "service": "backstage", "stage": "completion", "status": "succeeded", "timestamp": "2024-08-26 16:41:02" }
8.4.3. Configure bulk import capabilities
8.4.3.1. Configure bulk import capabilities
Configure custom Scaffolder workflows and register repository lists with the orchestrator for advanced bulk import operations.
8.4.3.2. Input parameters for Bulk Import Scaffolder template
Define Scaffolder template parameters such as repository URL, name, organization, and branch details to customize bulk import automation workflows for your repositories.
As an administrator, you can use the Bulk Import plugin to run a Scaffolder template task with specified parameters, which you must define within the template.
The Bulk Import plugin analyzes Git repository information and provides the following parameters for the Scaffolder template task:
repoUrlNormalized repository URL in the following format:
${gitProviderHost}?owner=${owner}&repo=${repository-name}name- The repository name.
organization- The repository owner, which can be a user nickname or organization name.
branchName-
The proposed repository branch. By default, the proposed repository branch is
bulk-import-catalog-entity. targetBranchName- The default branch of the Git repository.
gitProviderHost-
The Git provider host parsed from the repository URL. You can use this parameter to write
Git-provider-agnostictemplates.
Example of a Scaffolder template:
parameters:
- title: Repository details
required:
- repoUrl
- branchName
- targetBranchName
- name
- organization
properties:
repoUrl:
type: string
title: Repository URL ({product-short} format)
description: github.com?owner=Org&repo=repoName
organization:
type: string
title: Owner of the repository
name:
type: string
title: Name of the repository
branchName:
type: string
title: Branch to add the catalog entity to
targetBranchName:
type: string
title: Branch to target the PR/MR to
gitProviderHost:
type: string
title: Git provider host8.4.3.3. Set up a custom Scaffolder workflow for Bulk Import
Create custom Scaffolder templates aligned with your organization’s repository conventions to automate bulk import tasks such as entity imports, pull request creation, and webhook integration.
As an administrator, you can create a custom Scaffolder template inline with the repository conventions of your organization and add the template into the Red Hat Developer Hub catalog for use by the Bulk Import plugin on many selected repositories.
You can define various custom tasks, including, but not limited to the following:
- Importing existing catalog entities from a repository
- Creating pull requests for cleanup
- Calling webhooks for external system integration
Prerequisites
- You created a custom Scaffolder template for the Bulk Import plugin.
You have run your RHDH instance with the following environment variable enabled to allow the use of the Scaffolder functionality:
export NODE_OPTIONS=--no-node-snapshot
Procedure
Configure your app-config.yaml configuration to instruct the Bulk Import plugin to use your custom template as shown in the following example:
bulkImport: importTemplate: <your_template_entity_reference_or_template_name> importAPI: `open-pull-requests` | `scaffolder`;
where:
importTemplate:- Enter your Scaffolder template entity reference.
importAPI- Set the API to 'scaffolder' to trigger the defined workflow for high-fidelity automation. This field defines the import workflow and currently supports two following options:
open-pull-requests- This is the default import workflow, which includes the logic for creating pull requests for every selected repository.
scaffolderThis workflow uses an import scenario defined in the Scaffolder template to create import jobs. Select this option to use the custom import scenario defined in your Scaffolder template.
Optional: You can direct the Bulk Import plugin to hand off the entire list of selected repositories to a custom Orchestrator workflow.
ImportantThe Scaffolder template must be generic and not specific to a single repository if you want your custom Scaffolder template to run successfully for every repository in the bulk list.
Verification
-
The Bulk Import plugin runs the custom Scaffolder template for the list of repositories using the
/task-importsAPI endpoint.
8.4.3.4. Register repository lists with the orchestrator
8.4.3.4.1. Register repository lists with the orchestrator
Run orchestrator workflows for bulk imports and design custom workflows for data handoff.
8.4.3.4.2. Run Orchestrator workflows for bulk imports
Configure Bulk Import to use Orchestrator workflows for advanced bulk operations across multiple repositories, enabling automated pull request creation and configuration publishing at scale.
As a platform engineer, you can configure the Bulk Import plugin to run Orchestrator workflows for bulk import operations. This mode uses the Orchestrator engine to provide advanced capabilities, such as creating pull requests or publishing configurations across multiple repositories.
Prerequisites
- You have installed and configured the Orchestrator plugin in your Developer Hub instance.
-
You have registered a generic custom workflow (for example,
universal-pr) in the Orchestrator plugin. - You have added a custom Developer Hub application configuration.
Procedure
Configure the Bulk Import plugin by editing your
app-config.yamlfile to enable Orchestrator mode.bulkImport: orchestratorWorkflow: your_workflow_id importAPI: 'orchestrator'
where:
orchestratorWorkflow- The ID of the workflow to run for each repository.
importAPI-
The execution mode for the workflow. Enter
orchestratorto enable workflow execution.
Verify that the Orchestrator workflow receives the following input:
{ "inputData": { "owner": "redhat-developer", "repo": "rhdh-plugins", "baseBranch": "main", "targetBranch": "bulk-import-orchestrator" }, "authTokens": [ { "token": "<github_token>", "provider": "github" } ] }where:
owner- Specifies the repository owner (organization or user name).
repo- Specifies the repository name.
baseBranch- Specifies the default branch of the Git repository (for example, main).
targetBranch-
Specifies the target branch for the import operation. By default, this is set to
bulk-import-orchestrator. authTokens- Specifies the authentication tokens for the Git provider:
-
For GitHub: {
token: <github_token>, provider: github} -
For GitLab: {
token: <gitlab_token>, provider: gitlab} Navigate to the Bulk Import page in the sidebar and complete the following steps:
- Select your Git provider (for example, GitHub or GitLab).
- Select the projects you want to import.
- Click import to run the workflow.
Verification
- Locate your repository and confirm status is COMPLETED.
8.4.3.4.3. Data handoff and custom workflow design
Design Scaffolder templates to receive repository data as parameters and automate repository-specific tasks when using Scaffolder mode for bulk imports.
When you configure the Bulk Import plugin by setting the importAPI field to scaffolder, the Bulk Import Backend passes all necessary context directly to the Scaffolder API.
As an administrator, you can define the Scaffolder template workflow and structure the workflow to do the following:
- Define template parameters to consume input
- Structure the Scaffolder template to receive the repository data as template parameters for the current workflow run. The template must be generic, and not specific to a single repository, so that it can successfully run for every repository in the bulk list.
- Automate processing for each repository
-
Implement the custom logic needed for a single repository within the template. The Orchestrator iterates through the repository list, launching the template once for each repository and passes only the data for that single repository to the template run. This allows you to automate tasks such as creating the
catalog-info.yaml, running compliance checks, or registering the entity with the catalog.
8.4.4. Enable GitHub repository discovery
Configure automatic GitHub repository discovery to import repositories containing catalog-info.yaml files into the Red Hat Developer Hub catalog without manual registration.
Prerequisites
- You have added a custom Developer Hub application configuration.
- You have sufficient permissions in GitHub to create and manage a GitHub App.
- To allow users to access GitHub templates or plugins that require GitHub authentication, you have configured GitHub either as an auxiliary authentication provider or as your main authentication provider.
Procedure
Create a GitHub App to allow Developer Hub to access the GitHub API. Opt for a GitHub App instead of an OAuth app to use fine-grained permissions, gain more control over which repositories the application can access, and use short-lived tokens.
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>. - Authorization callback URL
-
Enter your Developer Hub authentication backend URL:
https://<my_developer_hub_domain>/api/auth/github/handler/frame. - Webhook
- Clear "Active", as this is not needed for authentication and catalog providers.
- App permissions
Select permissions to define the level of access for the app. Adapt permissions to your needs:
- Reading software components
- Contents
-
Read-only - Commit statuses
-
Read-only
- Reading organization data
- Members
-
Read-only
- Publishing software templates
Set permissions if you intend to use the same GitHub App for software templates.
- Administration
-
Read & write(for creating repositories) - Contents
-
Read & write - Metadata
-
Read-only - Pull requests
-
Read & write - Issues
-
Read & write - Workflows
-
Read & write(if templates include GitHub workflows) - Variables
-
Read & write(if templates include GitHub Action Repository Variables) - Secrets
-
Read & write(if templates include GitHub Action Repository Secrets) - Environments
-
Read & write(if templates include GitHub Environments)
- Organization permissions
- Members
-
Read-only
- Where can this GitHub App be installed?
-
Select
Only on this account.
- In the General → Clients secrets section, click Generate a new client secret.
- In the General → Private keys section, click Generate a private key.
- In the Install App tab, choose an account to install your GitHub App on.
- Save the following values for the next step:
- App ID
- Client ID
- Client secret
- Private key
Add your GitHub credentials 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 the corresponding environment variable name for each secret.
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>.
Enable the
plugin-catalog-backend-module-githubplugin in yourdynamic-plugins.yamlfile.This plugin discovers catalog entities by scanning repositories within a GitHub organization for
catalog-info.yamlfiles. It provides an automated alternative to manually registering components viacatalog.locations. When a repository contains acatalog-info.yamlfile, the entity is ingested into the catalog as a component.dynamic-plugins.yamlfile fragmentplugins: - package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github' disabled: falseConfigure the GitHub integration, by adding the
catalog.providers.githuband theintegrations.githubsections to your custom Developer Hubapp-config.yamlconfiguration file:app-config.yamlfile fragment with mandatory fields to enable GitHub integrationcatalog: providers: github: providerId: organization: "${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}
8.5. Orchestrate infrastructure tasks using workflows
8.5.1. Orchestrate infrastructure tasks using workflows
You can streamline and automate your work by using the Orchestrator in Red Hat Developer Hub to design, run, and monitor workflows across applications and services.
- Design, run, and monitor workflows to simplify multi-step processes across applications and services.
- Standardize onboarding, migration, and integration workflows to reduce manual effort and improve consistency.
- Extend RHDH with enterprise-grade Orchestration features to support collaboration and scalability.
Orchestrator currently supports only Red Hat OpenShift Container Platform (OpenShift Container Platform); it is not available on Microsoft Azure Kubernetes Service (AKS), Amazon Elastic Kubernetes Service (EKS), or Google Kubernetes Engine (GKE).
8.5.2. Orchestrator process automation architecture
8.5.2.1. Orchestrator process automation architecture
You can streamline and automate your work by using the Orchestrator in Red Hat Developer Hub to design, run, and monitor workflows across applications and services.
- Design, run, and monitor workflows to simplify multi-step processes across applications and services.
- Standardize onboarding, migration, and integration workflows to reduce manual effort and improve consistency.
- Extend RHDH with enterprise-grade Orchestration features to support collaboration and scalability.
Orchestrator currently supports only Red Hat OpenShift Container Platform (OpenShift Container Platform); it is not available on Microsoft Azure Kubernetes Service (AKS), Amazon Elastic Kubernetes Service (EKS), or Google Kubernetes Engine (GKE).
8.5.3. Build serverless workflows
8.5.3.1. Build serverless workflows
Deploy a workflow and make it available in the Orchestrator plugin by building workflow images, generating workflow manifests, and deploying workflows to a cluster.
- Building workflow images
- Generating workflow manifests
- Deploying workflows to a cluster
This process moves the workflow from your local machine to deployment on a cluster.
8.5.3.2. Pre-built workflow container image capabilities
8.5.3.2.1. Pre-built workflow container image capabilities
Pre-built workflow container images provide capabilities for building and deploying workflow projects.
8.5.3.2.2. Project structure overview
The project utilizes Quarkus project layout (Maven project structure), as illustrated by the 01_basic workflow example.
01_basic
├── pom.xml
├── README.md
└── src
└── main
├── docker
│ ├── Dockerfile.jvm
│ ├── Dockerfile.legacy-jar
│ ├── Dockerfile.native
│ └── Dockerfile.native-micro
└── resources
├── application.properties
├── basic.svg
├── basic.sw.yaml
├── schemas
│ ├── basic__main-schema.json
│ └── workflow-output-schema.json
└── secret.properties
The main workflow resources are located under the src/main/resources/ directory.
The kn-workflow CLI generated this project structure. You can try generating the structure yourself by following the Getting Started guide.
Additional resources
8.5.3.2.3. Benefits of workflow images
While the OpenShift Serverless Logic Operator supports the building of workflows dynamically, this approach is primarily for experimentation. For production deployments, building images is the preferred method due to the following reasons:
- Production readiness: Prebuilt images can be scanned, secured, and tested before going live.
-
GitOps compatibility: The Orchestrator relies on a central OpenShift Serverless Logic Operator instance to track workflows and their state. To use this tracking service, you must deploy workflows with the
gitopsprofile, which expects a prebuilt image. - Testing and quality: Building an image gives you more control over the testing process.
8.5.3.2.4. Create and run your serverless workflow project locally
Use the kn-workflow CLI to generate workflow manifests and project structures, enabling you to develop and test a new serverless workflow locally.
Procedure
Use the
kn-workflowCLI to create a new workflow project, which adheres to the Quarkus structure as shown in the following example:$ kn-workflow quarkus create --name <specify project name, for example ,00_new_project>
Edit the workflow, add schema and specific files, and run it locally from project folder as shown in the following example:
$ kn-workflow quarkus run
Run the workflow locally using the
kn-workflow runwhich pulls the following image:registry.redhat.io/openshift-serverless-1/logic-swf-devmode-rhel9:1.38.0
For building the workflow image, the
kn-workflowCLI pulls the following images:registry.redhat.io/openshift-serverless-1/logic-swf-builder-rhel9:1.38.0 registry.access.redhat.com/ubi9/openjdk-17:1.21-2
8.5.3.3. Build workflow container images locally using the build.sh script
8.5.3.3.1. Build workflow container images locally using the build.sh script
Build workflow images locally using the provided build.sh script with support for various configuration flags and environment variables.
8.5.3.3.2. The build-sh script functionality and important flags
The build-sh script generates workflow manifests, builds workflow images, and optionally pushes images and deploys workflows.
-
Generates workflow manifests using the
kn-workflowCLI. -
Builds the workflow image using
podmanordocker. -
Optional: The script pushes the images to an image registry and deploys the workflow using
kubectl.
You can review the script configuration options and see available flags and their functions by accessing the help menu:
./scripts/build.sh [flags]
The following flags are essential for running the script:
| Flag | Description |
|---|---|
|
|
Required: Full image path, for example, |
|
|
Workflow source directory (default is the current directory) |
|
|
Where to save generated manifests |
|
|
Push the image to the registry |
|
|
Deploy the workflow |
|
|
Show the help message |
The script also supports builder and runtime image overrides, namespace targeting, and persistence flags.
8.5.3.3.3. Environment variables supported by the build script
The build-sh script supports environment variables that customize the workflow build process without modifying the script itself.
QUARKUS_EXTENSIONSThe
QUARKUS_EXTENSIONSvariable specifies additional Quarkus extensions required by the workflow. This variable takes the format of a comma-separated list of fully qualified extension IDs as shown in the following example:export QUARKUS_EXTENSIONS="io.quarkus:quarkus-smallrye-reactive-messaging-kafka"
Add Kafka messaging support or other integrations at build time.
MAVEN_ARGS_APPENDThe
MAVEN_ARGS_APPENDvariable appends additional arguments to the Maven build command. This variable takes the format of a string of Maven CLI arguments as shown in the following example:export MAVEN_ARGS_APPEND="-DmaxYamlCodePoints=35000000"
Control build behavior. For example, set
maxYamlCodePointsparameter that controls the maximum input size for YAML input files to 35000000 characters (~33MB in UTF-8).
Additional resources
8.5.3.3.4. Required tools
To run the build-sh script locally and manage the workflow lifecycle, you must install several command-line tools.
| Tool | Conceptual Purpose. |
|---|---|
|
podman or docker |
Container runtime required for building the workflow images. |
|
|
Kubernetes CLI. |
|
|
YAML processor. |
|
|
JSON processor. |
|
|
Shell utilities. |
|
|
CLI for generating workflow manifests. |
8.5.3.3.5. Build the 01_basic workflow
To run the script from the root directory of the repository, you must use the -w flag to point to the workflow directory. Additionally, specify the output directory with the -m flag.
Prerequisites
- You have specified the target image using a tag.
Procedure
Run the following command:
$ ./scripts/build.sh --image=quay.io/orchestrator/demo-basic:test -w 01_basic/ -m 01_basic/manifests
This build command produces the following two artifacts:
-
A workflow image and Kubernetes manifests:
quay.io/orchestrator/demo-basic:testand tagged aslatest. -
Kubernetes manifests under:
01_basic/manifests/ -
Optional: You can add the
--pushflag to automatically push the image after building. Otherwise, pushing manually is mandatory before deploying.
8.5.3.3.6. Build workflow images locally
Build workflow images locally by using the build script (build.sh) to prepare container images for deployment.
Procedure
Clone the project as shown in the following example:
git clone git@github.com:rhdhorchestrator/orchestrator-demo.git cd orchestrator-demo
Check the help menu of the script:
./scripts/build.sh --help
Run the
build.shscript, providing the required flags, for example, the image path (-i), workflow source directory (-w), and manifests output directory (-m).ImportantYou must specify the full target image path with a tag as shown in the following example:
./scripts/build.sh --image=quay.io/orchestrator/demo-basic:test -w 01_basic/ -m 01_basic/manifests
8.5.3.4. Generated workflow manifests
Review the structure and content of workflow manifests generated under the 01_basic/manifests directory.
01_basic/manifests ├── 00-secret_basic-secrets.yaml ├── 01-configmap_basic-props.yaml ├── 02-configmap_01-basic-resources-schemas.yaml └── 03-sonataflow_basic.yaml
00-secret_basic-secrets.yaml-
Contains secrets from
01_basic/src/main/resources/secret.properties. Values are not required at this stage as you can set them later after applying CRs or when using GitOps.
In OpenShift Serverless Logic 1.38.0, after updating a secret, you must manually restart the workflow Pod for changes to apply.
01-configmap_basic-props.yaml- Holds application properties from application.properties. Any change to this ConfigMap triggers an automatic Pod restart.
02-configmap_01-basic-resources-schemas.yamlContains JSON schemas from src/main/resources/schemas.
NoteYou do not need to deploy certain configuration resources when using the GitOps profile.
03-sonataflow_basic.yamlThe SonataFlow custom resource (CR) that defines the workflow.
podTemplate: container: image: quay.io/orchestrator/demo-basic resources: {} envFrom: - secretRef: name: basic-secretspersistence: postgresql: secretRef: name:sonataflow-psql-postgresqluserKey:<your_postgres_username>passwordKey:<your_postgres_password>serviceRef: name:sonataflow-psql-postgresqlport: 5432 databaseName: sonataflow databaseSchema: basicwhere:
postgresql:secretRef:name- Enter the Secret name for your deployment.
postgresql:secretRef:userKey- Enter the key for your deployment.
postgresql:secretRef:passwordKey- Enter the password for your deployment.
postgresql:serviceRef:nameEnter the Service name for your deployment.
If you must connect to an external database, replace
serviceRefwithjdbcUrl. See Managing workflow persistence.
By default, the script generates all the manifests without a namespace. You can specify a namespace to the script by using the --namespace flag if you know the target namespace in advance. Otherwise, you must provide the namespace when applying the manifests to the cluster. See Configuring workflow services.
8.5.3.5. Deploy workflows on a cluster
You can deploy the workflow on a cluster, because the image is pushed to the image registry and the deployment manifests are available.
Prerequisites
You have an OpenShift Container Platform cluster with the following versions of components installed:
- Red Hat Developer Hub (RHDH) 1.10
- Orchestrator plugins 1.10.0
- OpenShift Serverless 1.37.1
OpenShift Serverless Logic 1.38.0
For instructions on how to install these components, see the Orchestrator plugin components on OpenShift Container Platform.
-
You must apply the workflow manifests in a namespace that contains a
SonataflowPlatformcustom resource (CR), which manages the supporting services.
Procedure
Use the
kubectl createcommand specifying the target namespace to apply the Kubernetes manifests as shown in the following example:$ kubectl create -n <your_namespace> -f ./01_basic/manifests/.
After deployment, monitor the status of the workflow pods as shown in the following example:
$ kubectl get pods -n <your_namespace> -l app=basic
The pod may initially appear in an
Errorstate because of missing or incomplete configuration in the Secret or ConfigMap.Inspect the Pod logs as shown in the following example:
$ oc logs -n <your_namespace> basic-f7c6ff455-vwl56
The following code is an example of the output:
SRCFG00040: The config property quarkus.openapi-generator.notifications.auth.BearerToken.bearer-token is defined as the empty String ("") which the following Converter considered to be null: io.smallrye.config.Converters$BuiltInConverter java.lang.RuntimeException: Failed to start quarkus ... Caused by: io.quarkus.runtime.configuration.ConfigurationException: Failed to read configuration propertiesThe error indicates a missing property:
quarkus.openapi-generator.notifications.auth.BearerToken.bearer-token.In such a case where the logs show the
ConfigurationException: Failed to read configuration propertieserror or indicate a missing value, retrieve the ConfigMap as shown in the following example:$ oc get -n <your_namespace> configmaps basic-props -o yaml
The following code is an example of the sample output:
apiVersion: v1 data: application.properties: | # Backstage notifications service quarkus.rest-client.notifications.url=${BACKSTAGE_NOTIFICATIONS_URL} quarkus.openapi-generator.notifications.auth.BearerToken.bearer-token=${NOTIFICATIONS_BEARER_TOKEN} ...Resolve the placeholders using values provided using a Secret.
You must edit the corresponding Secret and provide appropriate base64-encoded values to resolve the placeholders in
application.propertiesas shown in the following example:$ kubectl edit secrets -n <your_namespace> basic-secrets
- Restart the workflow Pod for Secret changes to take effect in OpenShift Serverless Logic 1.38.0.
Verification
Verify the deployment status by checking the Pods again as shown in the following example:
$ oc get pods -n <your_namespace> -l app=basic
The expected status for a successfully deployed workflow Pod is as shown in the following example:
NAME READY STATUS RESTARTS AGE basic-f7c6ff455-grkxd 1/1 Running 0 47s
-
Once the Pod is in the
Runningstate, the workflow now appears in the Orchestrator plugin inside the Red Hat Developer Hub.
Next steps
- Inspect the provided build script to extract the actual steps and implement them in your preferred CI/CD tool, for example, GitHub Actions, GitLab CI, Jenkins, and Tekton.
8.5.3.6. Workflow design best practices
8.5.3.6.1. Workflow design best practices
Follow best practices when creating serverless workflows, including maintaining unique workflow IDs to prevent duplicates.
8.5.3.6.2. Best practices when creating serverless workflows
Create effective serverless workflows using thoughtful approaches to design, handle data, and manage error by following these best practices based on the Serverless Workflow Domain Specific Language (DSL) principles. These principles help you to build robust workflows.
- Workflow design principles
The Serverless Workflow DSL prioritizes clarity and ease of use when writing workflows.
- Priority of constituencies
- When developing workflows or APIs, ensure the needs of the author (workflow writer) come first. The constituencies are prioritized in the following order: Authors > Operators > Implementers > Specifications writers.
- Linguistic fluency and clarity
-
Use imperative verbs such as
Call,Emit,For,Fork,Raise,Run,Set,Switch, andWait. These simple, universally understood terms make your workflow simple to read and understand.
-
Use imperative verbs such as
- Structure and extensibility
- Use implicit default behaviors to reduce redundancy.
- Declare components inline if they are not reusable to keep the definition self-contained.
- Use external references to import and reuse shared components, which promotes a modular design.
- Prioritize flexibility over strict enumerations to ensure extensibility and adaptability across different runtime environments.
- Data flow and runtime management
-
Controlling data flow is critical for efficient workflows. Tasks are the fundamental computing units of a workflow. The Domain Specific Language (DSL) defines several default task types that runtimes must do. These include
Do,Listen,Raise,Run,Try, andWait. - Security and error handling
- Secrets
- Use Secrets with caution. Avoid passing them directly in call inputs as this might expose sensitive information.
- Fault tolerance and error handling
- Serverless Workflow is designed with resilience in mind to recover from failures.
- Orchestrator UI integration best practices
For your workflow results to be effectively displayed in the Orchestrator UI and to facilitate chaining of workflows, you must structure the output data according to the
WorkflowResultschema. Additionally, include any error information as part of the workflow output so the UI and subsequent workflows can handle them accordingly.- Workflow output schema
- Results placement
-
The primary output intended for subsequent processing must be placed under the
data.resultproperty. - Schema reference
-
Your output schema file (
schemas/workflow-output-schema.json) must reference theWorkflowResultschema. - Outputs definition
Include an
outputssection in your workflow definition. This section contains human-readable key/value pairs that the UI will display.Structure of workflow:
id: my-workflow version: "0.8" specVersion: "0.8" name: My Workflow start: ImmediatelyEnd dataInputSchema: schemas/basic__main-schema.json extensions: - extensionid: workflow-output-schema outputSchema: schemas/workflow-output-schema.json functions: - name: print type: custom operation: sysout - name: successResult type: expression operation: '{ "result": { "message": "Project " + .projectName + " active", "outputs":[] } }' start: "successResult" states: - name: successResult type: operation actions: - name: setOutput functionRef: refName: successResult end: true
8.5.3.6.3. Unique workflow ID requirements to prevent duplicates
Unique workflow IDs prevent duplicate entries in RHDH. You must use distinct IDs for each deployment to avoid tracking conflicts and maintain clear workflow visibility.
- Understand how RHDH identifies workflows
- RHDH identifies each workflow by using its unique ID. When you deploy or update workflows, the system uses this ID to track, display, and manage workflow instances. If multiple workflows share the same ID, RHDH cannot distinguish between them, resulting in unexpected behavior.
- Follow workflow ID format requirements
Workflow identifiers must comply with RFC 1123 DNS label standards to function correctly across all deployment configurations. Your workflow IDs must meet these format requirements:
- Contain only lowercase letters (a-z), digits (0-9), and hyphens (-)
- Start and end with a lowercase letter or digit
Not contain underscores, uppercase letters, or leading or trailing hyphens
Valid workflow ID examples:
-
order-processing -
invoice123 -
customer-onboarding-flow flow-01Invalid workflow ID examples:
-
OrderProcessing(contains uppercase letters) -
order_processing(contains underscore) -
-orderflow(starts with hyphen) -
orderflow-(ends with hyphen)
- Maintain workflow ID consistency across configurations
You must use the same workflow identifier consistently across all configurations when you build and deploy your workflow. This requirement proves essential for operator-driven deployments that use the gitops profile.
For gitops profile deployments, the Kubernetes resource name must match the workflow ID field in your workflow definition file (
.sw.yamlor.sw.json). This consistency prevents deployment failures and maintains proper workflow tracking in RHDH.- Recognize version field limitations
Although the Serverless workflow specification allows you to define a workflow version attribute in your workflow definition, the current SonataFlow and RHDH ecosystem does not support multiple versions of a workflow that share the same ID.
ImportantDeploying multiple workflows with the same ID and different versions is not supported and results in unexpected behavior. Each workflow ID must be unique across all deployments.
The version field serves as metadata and appears in the RHDH UI for informational purposes to help you identify workflow definitions. The backend retrieves version information from the Data Index GraphQL schema and displays it in both the workflow list view and on individual workflow details pages. If you do not specify a version in your workflow definition, the field appears empty in the UI.
The system does not use the version field to differentiate between workflows or manage workflow versions. All workflow operations, including execution, deletion, and API calls, rely solely on the workflow ID.
- Avoid deploying workflows with duplicate IDs
Each workflow ID must be unique across all deployments, regardless of the configured version attribute. Deploying multiple workflows with the same ID and different versions is not supported and can result in the following issues:
- Duplicate workflow entries appear in the RHDH Orchestrator UI.
- Workflow deletion operations become unpredictable.
- Historical workflow data becomes difficult to interpret.
Workflow instance tracking becomes unreliable.
Duplicate entries can occur when you deploy workflows with the same ID to different runtime servers over time, or when you redeploy a workflow with a new version by using the same ID. Because the Data Index records all workflow executions regardless of which runtime server executed them, historical records from multiple deployments with the same ID appear as duplicate entries in the RHDH UI.
- Apply workflow version management best practices
To maintain different versions of a workflow, assign a new workflow ID for each version. Incorporate the version identifier into the workflow ID itself using a consistent naming convention.
Recommended naming pattern: Use a naming convention that clearly links related versions of the same workflow:
-
workflow-name-v1implements and deploys version 1 -
workflow-name-v2implements and deploys version 2 workflow-name-v3implements and deploys version 3Example workflow ID evolution:
id: customer-onboarding-v1 version: "1.0" name: Customer Onboarding Workflow
When you need to deploy an updated version:
id: customer-onboarding-v2 version: "2.0" name: Customer Onboarding Workflow
This approach provides clarity and prevents conflicts when you manage multiple iterations of a workflow.
-
- Manage workflow transitions between versions
When you transition from one workflow version to another:
-
Deploy the new workflow version with a unique ID (for example,
workflow-name-v2). - Verify the new workflow operates correctly.
- Monitor running instances of the old workflow version.
After all instances of the old workflow complete, remove the old workflow deployment.
This process helps you maintain workflow history and prevents disruption to running workflow instances.
-
Deploy the new workflow version with a unique ID (for example,
8.5.4. Deploy Red Hat Developer Hub for workflow automation
To automate CI/CD pipeline setup, deploy Red Hat Developer Hub with workflow orchestration by using predefined Operator configurations.
Prerequisites
- You have installed the Red Hat Developer Hub Operator in your OpenShift cluster.
- You have installed the required infrastructure components for Orchestrator.
- Optional: For production deployments, you have configured an external PostgreSQL database and created a Secret with connection credentials.
-
Optional: You have AMQ Streams (
Kafka) installed for event-driven workflow processing.
Procedure
Create a namespace for your Red Hat Developer Hub instance or use an existing namespace:
$ oc new-project my-rhdh-project
Create a Backstage CR with the Orchestrator deployment configuration:
$ cat <<EOF | oc -n my-rhdh-project create -f - apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: <backstage_instance_name> spec: flavours: - name: orchestrator enabled: true EOFWhere:
<backstage_instance_name>-
A name for your Red Hat Developer Hub instance, for example
developer-hub-orchestrator. spec.flavoursThe pre-configured settings array. Set
name: orchestratorwithenabled: trueto automatically configure workflow orchestration capabilities.NoteThis example uses the default local PostgreSQL database. For production deployments, Red Hat recommends using an external PostgreSQL database. If you configured an external database in the prerequisites, add the database configuration to the CR as shown in Configure external PostgreSQL databases.
ImportantIf you reference a custom
dynamic-pluginsconfig map usingspec.application.dynamicPluginsConfigMapName, custom plugin declarations override matching plugin declarations fromspec.flavoursbased on package name. To enable Orchestrator, you must setspec.flavours: [{name: orchestrator, enabled: true}]. You can use custom config map entries to customize the Orchestrator plugin settings. To disable Orchestrator, setspec.flavours: [{name: orchestrator, enabled: false}]. When you disable Orchestrator, the Operator excludes its plugins from the default configuration. Therefore, you must remove or disable those plugins in your customdynamic-pluginsconfig map, otherwise RHDH still loads them.Wait for the Operator to reconcile the Backstage CR:
$ oc get backstage <backstage_instance_name> -n my-rhdh-project -w
The deployment is ready when the
PHASEcolumn showsDeployed.
Verification
Verify that the Data Index service pod is running:
$ oc get pods -n my-rhdh-project | grep sonataflow
You should see the Data Index service pod. The Orchestrator backend plugin runs within the main Red Hat Developer Hub pod.
Access the Red Hat Developer Hub UI:
$ oc get route backstage-<backstage_instance_name> -n my-rhdh-project -o jsonpath='{.spec.host}'Go to the URL in your browser.
- Verify the Orchestrator plugin is displayed in the Red Hat Developer Hub navigation menu. Look for the Orchestrator option in the left navigation panel.
- Optional: Test workflow deployment by creating a sample workflow. For detailed workflow examples, see Orchestrator in Red Hat Developer Hub.
Troubleshooting
- If workflow pods fail to start
Verify the PostgreSQL connection by checking the Operator logs:
$ oc logs -n openshift-operators deployment/rhdh-operator -c manager
Ensure the database credentials in the Secret are correct and the database is accessible from the cluster.
- If the Data Index service fails
- Verify that the PostgreSQL user has permissions to create schemas and tables. The Orchestrator deployment configuration automatically initializes required database schemas.
8.5.5. Automate workflow deployments
8.5.5.1. Automate workflow deployments
Automate the software development lifecycle for serverless workflows by using Orchestrator software templates to bootstrap complete workflow projects with Git repositories, deployment configurations, and CI/CD pipelines.
8.5.5.2. Orchestrator workflow deployment components
The Orchestrator plugin integrates several components to automate the software development lifecycle for serverless workflows.
Use the rhdh namespace where the RHDH chart is installed.
The Orchestrator plugin integrates these components:
- RHDH Helm chart
- Installs the RHDH Orchestrator.
- Tekton or Red Hat OpenShift Pipelines
-
Manages the
Kubernetes-nativeCI pipeline to build images. - ArgoCD or Red Hat OpenShift GitOps
- Manages the CD pipeline to deploy the workflow on the RHDH instance.
- Quay.io
- Stores the container images generated by the pipelines.
- OpenShift Serverless Logic operator
- Implements serverless workflow specifications
8.5.5.3. Install Orchestrator Helm charts
8.5.5.3.1. Install Orchestrator Helm charts
Install Orchestrator software templates using Helm charts to enable workflow automation capabilities.
8.5.5.3.2. Install the Orchestrator Software Templates Infra chart
The orchestrator-software-templates-infra chart installs the Custom Resource Definitions (CRDs) and operators for Tekton (Red Hat OpenShift Pipelines) and Argo CD (Red Hat OpenShift GitOps). These are required to handle the CI/CD automation for serverless workflows.
Prerequisites
-
You have
cluster-adminprivileges. - You have installed the Helm CLI.
You have added the following plugins to the RHDH chart
values.yamlfile to include the following dynamic plugins:-
backstage-plugin-scaffolder-backend-module-github-dynamic -
backstage-plugin-scaffolder-backend-module-gitlab-dynamic -
backstage-plugin-kubernetes-backend-dynamic -
backstage-plugin-kubernetes -
backstage-community-plugin-tekton -
backstage-community-plugin-redhat-argocd -
backstage-community-plugin-argocd-backend roadiehq-scaffolder-backend-argocd-dynamicEdit the
values.yamland upgrade the chart.
-
Procedure
Install the infrastructure chart:
$ helm install <release_name> redhat-developer/redhat-developer-hub-orchestrator-infra
Verification
Verify the installation by running the following command:
$ helm test redhat-developer-hub-orchestrator-infra
8.5.5.3.3. Install the Orchestrator Software Templates chart
The orchestrator-software-templates chart loads the actual software templates into your RHDH instance. This allows users to select workflow templates from the RHDH Catalog.
Prerequisites
-
You have installed the
orchestrator-software-templates-infrachart to deploy OpenShift Pipelines (Tekton) operator and OpenShift GitOps (ArgoCD) operator in the same namespace as RHDH. You have labeled the
rhdhnamespace to enable GitOps sync:$ oc label ns rhdh rhdh.redhat.com/argocd-namespace=true
You have created a secret named
orchestrator-auth-secretin therhdhnamespace containing the following keys:-
BACKEND_SECRET: Backend authentication secret -
K8S_CLUSTER_TOKEN: Kubernetes cluster token -
K8S_CLUSTER_URL: Kubernetes cluster URL -
GITHUB_TOKEN: GitHub access token (optional) -
GITHUB_CLIENT_ID: GitHub OAuth client ID (optional) -
GITHUB_CLIENT_SECRET: GitHub OAuth client secret (optional) -
GITLAB_HOST: GitLab host URL (optional) -
GITLAB_TOKEN: GitLab access token (optional) -
ARGOCD_URL: ArgoCD server URL (optional) -
ARGOCD_USERNAME: ArgoCD username (optional) -
ARGOCD_PASSWORD: ArgoCD password (optional)
-
Procedure
Install the software templates chart:
$ helm repo add redhat-developer https://redhat-developer.github.io/rhdh-chart $ helm install my-orchestrator-templates redhat-developer/orchestrator-software-templates --version 0.2.0
Create your environment-specific values file:
Retrieve your RHDH route URL:
RHDH_ROUTE="https://$(oc get route -n {{ .Values.orchestratorTemplates.rhdhChartNamespace }} -o jsonpath='{.items[0].spec.host}')"Copy the template and replace placeholders
cp charts/orchestrator-software-templates/orchestrator-templates-values.yaml.template orchestrator-templates-values.yaml sed -i "s|RHDH_BASE_URL|$RHDH_ROUTE|g" orchestrator-templates-values.yaml
Backup your RHDH configuration:
helm show values charts/backstage \ -n {{ .Values.orchestratorTemplates.rhdhChartNamespace }} > current-backstage-values.yamlUpgrade the RHDH chart with both value files:
helm upgrade {{ .Values.orchestratorTemplates.rhdhChartReleaseName }} charts/backstage \ -n {{ .Values.orchestratorTemplates.rhdhChartNamespace }} \ -f current-backstage-values.yaml \ -f orchestrator-templates-values.yaml
Verification
- Wait for the deployment to complete.
- Open your RHDH instance and verify the new software templates appear in the Create menu.
8.5.5.3.4. Install Red Hat Developer Hub (RHDH) on OpenShift Container Platform with the Orchestrator using the Helm CLI
You can install Red Hat Developer Hub (RHDH) on OpenShift Container Platform with the Orchestrator by using the Helm CLI. The installation automatically enables the required dynamic plugins and integrates workflow infrastructure.
Prerequisites
- You are logged in as an administrator and have access to the Red Hat Developer Hub Helm chart repository.
You can install the necessary infrastructures resources, such as other OpenShift operators (OpenShift Serverless and OpenShift Serverless Logic), alongside RHDH in the same namespace.
This is a one-off requirement and must be completed before enabling the Orchestrator plugin.
Procedure
Manually approve the install plans for the Operators. You must run the
oc patch installplancommands provided in the output to approve their installation.ImportantBy default, Orchestrator Infrastructure for Red Hat Developer Hub Helm chart does not auto-approve the required Serverless Operators. You must manually approve the install plans.
As an administrator, install relevant cluster-wide resources.
$ helm repo add openshift-helm-charts https://charts.openshift.io/ $ helm install
<release_name>openshift-helm-charts/redhat-developer-hub-orchestrator-infraImportantYou must be an administrator to install the
redhat-developer-hub-orchestrator-infraHelm chart because it deploys additional cluster-scoped OpenShift Serverless and OpenShift Serverless Logic Operators. As an administrator, you must manually approve the install plans for OpenShift Serverless and Serverless Logic Operators.Install the Backstage chart with the orchestrator enabled as shown in the following example:
$ helm install <release_name> openshift-helm-charts/redhat-developer-hub --version 1.10.1 \ --set orchestrator.enabled=true
(Optional) Enable Notifications and Signals plugins by adding them to the
global.dynamic.pluginslist in yourvalues.yamlfile as shown in the following example:global: dynamic: plugins: - disabled: false package: "./dynamic-plugins/dist/backstage-plugin-notifications" - disabled: false package: "./dynamic-plugins/dist/backstage-plugin-signals" - disabled: false package: "./dynamic-plugins/dist/backstage-plugin-notifications-backend-dynamic" - disabled: false package: "./dynamic-plugins/dist/backstage-plugin-signals-backend-dynamic"(Optional) You can disable the Serverless Logic and Serverless Operators individually or together by setting their values to
false, as shown in the following example:$ helm install <release_name> openshift-helm-charts/redhat-developer-hub \ --version 1.10.1 \ --set orchestrator.enabled=true \ --set orchestrator.serverlessOperator=false \ --set orchestrator.serverlessLogicOperator=false
(Optional) To configure Orchestrator to use an external PostgreSQL database, follow the detailed instructions in Configure Orchestrator to connect to existing PostgreSQL infrastructure using Helm.
NoteConfiguring an external database for Orchestrator requires additional steps beyond standard RHDH external database configuration. You must create the
backstage_plugin_orchestratordatabase, configure theorchestrator.sonataflowPlatformvalues, and ensure proper service connectivity. See the detailed procedure for complete instructions.
Verification
- Verify that the Orchestrator plugin is visible in the Red Hat Developer Hub UI.
- Create and run sample workflows to confirm the orchestration is functioning correctly.
8.5.5.3.5. Install Red Hat Developer Hub (RHDH) using Helm from the OpenShift Container Platform web console
You can install Red Hat Developer Hub (RHDH) with the Orchestrator by using the (OpenShift Container Platform) web console. This method is useful if you prefer a graphical interface or want to deploy cluster-wide resources without using the Helm CLI.
Prerequisites
- You are logged in to the OpenShift Container Platform web console as an administrator.
- You have access to the Red Hat Developer Hub Helm chart repository.
- Your cluster has internet access or the Helm charts are mirrored in a disconnected environment.
Procedure
- In the OpenShift Container Platform web console, go to the Helm Charts and verify that the Red Hat Developer Hub Helm chart repository is available.
Search for the Orchestrator infrastructure for Red Hat Developer Hub and select Install.
ImportantYou must be an administrator to install the Orchestrator Infrastructure for Red Hat Developer Hub Helm chart because it deploys cluster-scoped resources. As an administrator, you must manually approve the install plans for OpenShift Serverless and Serverless Logic Operators.
As a regular user, search for the Red Hat Developer Hub chart and install it by setting the value of
orchestrator.enabledtotrue. Otherwise, the Orchestrator will not be deployed.- Wait until they are successfully deployed.
- Monitor the deployment status by navigating to Pods or releases.
Verification
After deployment completes:
- The orchestrator-related pods are running in the selected namespace.
- Cluster-wide resources are present.
- You can start connecting the orchestrator to your Red Hat Developer Hub UI.
8.5.5.4. Install Orchestrator in an air-gapped environment
8.5.5.4.1. Install Orchestrator in an air-gapped environment
You can configure Red Hat Developer Hub (RHDH) with the Orchestrator plugin in a fully disconnected or partially disconnected environment by using the Operator or Helm chart.
8.5.5.4.2. Install Red Hat Developer Hub with Orchestrator in a fully disconnected OpenShift Container Platform environment using the Operator
You can install Red Hat Developer Hub with Orchestrator plugin in a fully air-gapped environment using the Operator.
A disconnected installation prevents unauthorized access, data transfer, or communication with external sources.
You can use the helper script to install Red Hat Developer Hub by mirroring the Operator-related images to disk and transferring them to your disconnected environment without any connection to the internet.
Prerequisites
- You have mirrored the Red Hat Developer Hub Operator images to the local registry using the RHDH mirroring script. For more information, see Installing Red Hat Developer Hub in a fully disconnected environment with the Operator.
- You have set up your disconnected environment using a local registry.
- You have permissions to push OCI images to your internal container registry.
-
You have installed the
oc mirrortool, with a version corresponding to the version of your OpenShift Container Platform cluster.
Procedure
Create an
ImageSetConfigurationfile foroc mirror. You must include the images and operators required by the Serverless Logic Operator in theImageSetConfigurationfile, as shown in the following example:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: additionalimages: - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets@<digest> operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v<ocp-version> # For example: registry.redhat.io/redhat/redhat-operator-index:v4.21 packages: - name: logic-operator channels: - name: stable minVersion: 1.38.0 maxVersion: 1.38.0 - name: serverless-operator channels: - name: stable minVersion: 1.37.1 maxVersion: 1.37.1
where:
<digest>Locate the image digests for your version of RHDH in the
dynamic-plugins.default.yamlfile. You can extract this file from the plugin catalog index image to verify the default settings for your specific release:#!/bin/bash unpack () { local IMAGE="$1" DIR="${IMAGE//:/}" DIR="/tmp/${DIR//\//-}" rm -fr "$DIR"; mkdir -p "$DIR"; container_id=$(podman create "${IMAGE}") podman export $container_id -o /tmp/image.tar && tar xf /tmp/image.tar -C "${DIR}/"; podman rm $container_id; rm -f /tmp/image.tar echo "Unpacked $IMAGE into $DIR" cd $DIR; tree -d -L 3 -I "usr|root|buildinfo" } unpack "registry.access.redhat.com/rhdh/plugin-catalog-index:{product-version)" # you can then find thedynamic-plugins.default.yamlunder /tmp/registry.access.redhat.com/rhdh/plugin-catalog-index{product-version)/dynamic-plugins.default.yaml
Mirror the images in the
ImageSetConfiguration.yamlfile by running theoc mirrorcommand. For example:$ oc mirror --config=ImageSetConfiguration.yaml file:///path/to/mirror-archive --authfile /path/to/authfile --v2
Note-
The
--v2flag is required for OpenShift Container Platform 4.21 and later. -
The
oc mirrorcommand generates a local workspace containing the mirror archive files and the required cluster manifests.
-
The
-
Transfer the directory specified by
/path/to/mirror-archiveto a bastion host within your disconnected environment. From the bastion host which has access to the mirror registry, mirror the images from the disk directory to your target registry. For example:
$ oc mirror --v2 --from <mirror-archive-file> docker://<target-registry-url:port> --workspace file://<workspace folder> --authfile /path/to/authfile
where:
<mirror-archive-file>-
Enter the name of the transferred
tarfile. <target-registry-url:port>-
Enter your local registry, for example,
registry.localhost:5000.
Apply the cluster-wide resources generated during the push step to redirect all image pulls to your local registry, as shown in the following example:
$ cd <workspace folder>/working-dir/cluster-resources/ $ oc apply -f .
-
Install the OpenShift Serverless Operator and OpenShift Serverless Logic Operators using
OperatorHub. - Create a Backstage custom resource (CR).
Configure the Backstage CR for the Orchestrator as described in the Orchestrator plugin dependencies for Operator installation.
Create all the resources and configure the Backstage instance accordingly.
Verification
- Restart the RHDH pod and wait for the components to deploy properly.
- Once stable, go to the RHDH UI, and confirm that the Orchestrator UI is accessible and functioning correctly.
The successful accessibility of the Orchestrator UI confirms that the underlying components are running and the cluster recognizes the plugin.
8.5.5.4.3. Install Red Hat Developer Hub with Orchestrator in a partially disconnected OpenShift Container Platform environment using the Operator
You can install Red Hat Developer Hub with Orchestrator plugin in a partial air-gapped environment using the Operator.
A disconnected installation prevents unauthorized access, data transfer, or communication with external sources.
You can use the oc mirror command to mirror resources directly to your accessible local mirror registry and apply the generated cluster resources.
Prerequisites
- You have mirrored the Red Hat Developer Hub Operator images to the local registry using the RHDH mirroring script. For more information, see Installing Red Hat Developer Hub in a partially disconnected environment with the Operator.
- You have set up your disconnected environment using a local registry.
- You have permissions to push OCI images to your internal container registry.
-
You have installed the
oc mirrortool, with a version corresponding to the version of your OpenShift Container Platform cluster.
Procedure
Create an
ImageSetConfigurationfile foroc mirror. You must include the images and operators required by the Serverless Logic Operator in theImageSetConfigurationfile, as shown in the following example:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: additionalimages: - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets@<digest> operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v<ocp-version> # For example: registry.redhat.io/redhat/redhat-operator-index:v4.21 packages: - name: logic-operator channels: - name: stable minVersion: 1.38.0 maxVersion: 1.38.0 - name: serverless-operator channels: - name: stable minVersion: 1.37.1 maxVersion: 1.37.1
Where:
<digest>Locate the image digests for your version of RHDH in the
dynamic-plugins.default.yamlfile. You can extract this file from the plugin catalog index image to verify the default settings for your specific release:#!/bin/bash unpack () { local IMAGE="$1" DIR="${IMAGE//:/}" DIR="/tmp/${DIR//\//-}" rm -fr "$DIR"; mkdir -p "$DIR"; container_id=$(podman create "${IMAGE}") podman export $container_id -o /tmp/image.tar && tar xf /tmp/image.tar -C "${DIR}/"; podman rm $container_id; rm -f /tmp/image.tar echo "Unpacked $IMAGE into $DIR" cd $DIR; tree -d -L 3 -I "usr|root|buildinfo" } unpack "registry.access.redhat.com/rhdh/plugin-catalog-index:{product-version)" # you can then find thedynamic-plugins.default.yamlunder /tmp/registry.access.redhat.com/rhdh/plugin-catalog-index{product-version)/dynamic-plugins.default.yaml
Mirror the images in the
ImageSetConfiguration.yamlfile by running theoc mirrorcommand. For example:$ oc mirror --config=imagesetconfiguration.yaml docker://<registry URL:port> --workspace file://<workspace folder> --authfile /path/to/authfile --v2 $ cd <workspace folder>/working-dir/cluster-resources/ $ oc apply -f .
NoteThe
--v2flag is required for OpenShift Container Platform 4.21 and later.-
Install the OpenShift Serverless Operator and OpenShift Serverless Logic Operators using
OperatorHub. - Create a Backstage custom resource (CR).
Configure the Backstage CR for the Orchestrator as described in the Orchestrator plugin dependencies for Operator installation.
Create all the resources and configure the Backstage instance accordingly.
Verification
- Restart the RHDH pod and wait for the components to deploy properly.
- Once stable, go to the RHDH UI, and confirm that the Orchestrator UI is accessible and functioning correctly.
The successful accessibility of the Orchestrator UI confirms that the underlying components are running and the cluster recognizes the plugin.
8.5.5.4.4. Install Red Hat Developer Hub with Orchestrator in a fully disconnected OpenShift Container Platform environment using the Helm chart
You can install Red Hat Developer Hub (RHDH) with the Orchestrator plugin in a fully air-gapped OpenShift Container Platform environment using the Helm chart.
You can mirror images to an intermediary disk, and then mirror from the disk to your target local registry and apply the generated cluster resources.
Prerequisites
- You have set up your disconnected environment using a local registry.
- You have permissions to push OCI images to your internal container registry.
-
You have installed the
oc mirrortool, with a version corresponding to the version of your OpenShift Container Platform cluster.
Procedure
Create an
ImageSetConfiguration.yamlfile foroc mirror. You must use anImageSetConfigurationfile to include all mirrored images required, as shown in the following example:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: additionalimages: - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets@<digest> helm: repositories: - name: openshift-charts url: https://charts.openshift.io charts: - name: redhat-developer-hub version: "1.10.1" - name: redhat-developer-hub-orchestrator-infra version: "1.10.1" operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v<ocp-version> # For example: registry.redhat.io/redhat/redhat-operator-index:v4.21 packages: - name: logic-operator channels: - name: stable minVersion: 1.38.0 maxVersion: 1.38.0 - name: serverless-operator channels: - name: stable minVersion: 1.37.1 maxVersion: 1.37.1
where:
<digest>Locate the image digests for your version of RHDH in the
dynamic-plugins.default.yamlfile. You can extract this file from the plugin catalog index image to verify the default settings for your specific release:#!/bin/bash unpack () { local IMAGE="$1" DIR="${IMAGE//:/_}" DIR="/tmp/${DIR//\//-}" rm -fr "$DIR"; mkdir -p "$DIR"; container_id=$(podman create "${IMAGE}") podman export $container_id -o /tmp/image.tar && tar xf /tmp/image.tar -C "${DIR}/"; podman rm $container_id; rm -f /tmp/image.tar echo "Unpacked $IMAGE into $DIR" cd $DIR; tree -d -L 3 -I "usr|root|buildinfo" } unpack "registry.access.redhat.com/rhdh/plugin-catalog-index:1.10" # you can then find thedynamic-plugins.default.yamlunder /tmp/registry.access.redhat.com/rhdh/plugin-catalog-index_1.10/dynamic-plugins.default.yaml
Mirror the images in the
ImageSetConfiguration.yamlfile by running theoc mirrorcommand. For example:$ oc mirror --config=ImageSetConfiguration.yaml file:///path/to/mirror-archive --authfile /path/to/authfile --v2
Note-
The
--v2flag is required for OpenShift Container Platform 4.21 and later. -
The
oc mirrorcommand pulls the charts listed in theImageSetConfigurationfile and makes them available astgzarchives under the/path/to/mirror-archivedirectory.
-
The
Apply the cluster-wide resources generated during the push step to redirect all image pulls to your local registry, as shown in the following example:
$ cd <workspace folder>/working-dir/cluster-resources/ $ oc apply -f .
-
Transfer the generated mirror archive file, for example,
/path/to/mirror-archive/mirror_000001.tar, to a bastion host within your disconnected environment. From the bastion host in your disconnected environment, which has access to the mirror registry, mirror the images from the archive file to your target registry. For example:
$ oc mirror --v2 --from <mirror-archive-file> docker://<target-registry-url:port> --workspace file://<workspace folder> --authfile /path/to/authfile
where:
<mirror-archive-file>-
Enter the name of the transferred
tarfile. <target-registry-url:port>-
Enter your local registry, for example,
registry.localhost:5000.
-
Apply the
redhat-developer-hub-orchestrator-infraHelm chart and approve the install plans. See Air-gapped installation with Helm chart instructions for details. Apply the RHDH 1.10 Helm chart. Include the version 1.10.1 and enable the Orchestrator plugin, as shown in the following example:
orchestrator.enabled=true
The RHDH 1.10 Helm chart defaults to pulling Orchestrator plugins from the official Red Hat OCI registry using full URL references. Override this default behavior to point the chart to your local registry.
To configure the Orchestrator plugins to use a custom registry, complete the following steps:
-
Open your
values.yamlfile. List the Orchestrator plugin packages under the
orchestrator.pluginssection. You must replace the simplified package references with the full URLs that point to your custom OCI registry.ImportantYou must explicitly include the
pluginConfigconfiguration for each plugin as shown in the following example:orchestrator: plugins: - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@_<digest>_ disabled: true pluginConfig: orchestrator: dataIndexService: url: http://sonataflow-platform-data-index-service - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets@_<digest>_ disabled: true pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-orchestrator-form-widgets: {} - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@_<digest>_ disabled: true pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-orchestrator: appIcons: - importName: OrchestratorIcon name: orchestratorIcon dynamicRoutes: - importName: OrchestratorPage menuItem: icon: orchestratorIcon text: Orchestrator textKey: menuItem.orchestrator path: /orchestrator entityTabs: - path: /workflows title: Workflows titleKey: catalog.entityPage.workflows.title mountPoint: entity.page.workflows mountPoints: - mountPoint: entity.page.workflows/cards importName: OrchestratorCatalogTab config: layout: gridColumn: 1 / -1 if: anyOf: - IsOrchestratorCatalogTabAvailable - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator@_<digest>_ disabled: true pluginConfig: orchestrator: dataIndexService: url: http://sonataflow-platform-data-index-servicewhere:
<custom_registry_url>- Enter the address of your custom registry where the OCI images have been mirrored.
<digest>Locate the image digests for your version of RHDH in the
dynamic-plugins.default.yamlfile. You can extract this file from the plugin catalog index image to verify the default settings for your specific release:#!/bin/bash unpack () { local IMAGE="$1" DIR="${IMAGE//:/}" DIR="/tmp/${DIR//\//-}" rm -fr "$DIR"; mkdir -p "$DIR"; container_id=$(podman create "${IMAGE}") podman export $container_id -o /tmp/image.tar && tar xf /tmp/image.tar -C "${DIR}/"; podman rm $container_id; rm -f /tmp/image.tar echo "Unpacked $IMAGE into $DIR" cd $DIR; tree -d -L 3 -I "usr|root|buildinfo" } unpack "registry.access.redhat.com/rhdh/plugin-catalog-index:{product-version)" # you can then find the dynamic-plugins.default.yaml under /tmp/registry.access.redhat.com/rhdh/plugin-catalog-index{product-version)/dynamic-plugins.default.yaml
Verification
- Restart the RHDH Pod and wait for the components to deploy properly.
- After deployment is complete, go to the RHDH UI and confirm that the Orchestrator UI is accessible and functioning correctly.
The successful accessibility of the Orchestrator UI confirms that the underlying components are running and the cluster recognizes the plugin.
8.5.5.4.5. Install Red Hat Developer Hub with Orchestrator in a partially disconnected OpenShift Container Platform environment using the Helm chart
You can install Red Hat Developer Hub (RHDH) with the Orchestrator plugin in a partial OpenShift Container Platform environment using the Helm chart.
A disconnected installation prevents unauthorized access, data transfer, or communication with external sources.
You can use the oc mirror command to mirror resources directly to your accessible local registry and apply the generated cluster resources.
Prerequisites
- You have set up your disconnected environment using a local registry.
- You have permissions to push OCI images to your internal container registry.
-
You have installed the
oc mirrortool, with a version corresponding to the version of your OpenShift Container Platform cluster.
Procedure
Create an
ImageSetConfiguration.yamlfile foroc mirror. You must use anImageSetConfigurationfile to include all mirrored images required, as shown in the following example:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: additionalimages: - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator@<digest> - name: registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets@<digest> helm: repositories: - name: openshift-charts url: https://charts.openshift.io charts: - name: redhat-developer-hub version: "1.10.1" - name: redhat-developer-hub-orchestrator-infra version: "1.10.1" operators: - catalog: registry.redhat.io/redhat/redhat-operator-index:v<ocp-version> # For example: registry.redhat.io/redhat/redhat-operator-index:v4.21 packages: - name: logic-operator channels: - name: stable minVersion: 1.38.0 maxVersion: 1.38.0 - name: serverless-operator channels: - name: stable minVersion: 1.37.1 maxVersion: 1.37.1
Mirror the images in the
ImageSetConfiguration.yamlfile by running theoc mirrorcommand to pull images and charts, and push the images directly to the target registry. For example:$ oc mirror --config=imagesetconfiguration.yaml docker://<registry URL:port> --workspace file://<workspace folder> --authfile /path/to/authfile --v2
Note-
The
--v2flag is required for OpenShift Container Platform 4.21 and later. -
The
oc mirrorcommand pulls the charts listed in theImageSetConfigurationfile and makes them available astgzarchives under the<workspace folder>directory.
-
The
Apply the generated cluster resources to the disconnected cluster. For example:
$ cd <workspace folder>/working-dir/cluster-resources/ $ oc apply -f .
-
Apply the
redhat-developer-hub-orchestrator-infraHelm chart and approve the install plans. See Air-gapped installation with Helm chart instructions for details. Apply the RHDH 1.10 Helm chart. Include the version 1.10.1 and enable the Orchestrator plugin, as shown in the following example:
orchestrator.enabled=true
The RHDH 1.10 Helm chart defaults to pulling Orchestrator plugins from the official Red Hat OCI registry using full URL references. You must override this behavior to point to your local registry.
To configure the Orchestrator plugins to use a custom registry, complete the following steps:
-
Open your
values.yamlfile. Explicitly list the Orchestrator plugin packages under the
orchestrator.pluginssection.You must replace the simplified package references with the full URLs that point to your custom OCI registry. You must explicitly include the
pluginConfigconfiguration for each plugin as shown in the following example:orchestrator: plugins: - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@_<digest>_ disabled: true pluginConfig: orchestrator: dataIndexService: url: http://sonataflow-platform-data-index-service - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets@_<digest>_ disabled: true pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-orchestrator-form-widgets: {} - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator@_<digest>_ disabled: true pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-orchestrator: appIcons: - importName: OrchestratorIcon name: orchestratorIcon dynamicRoutes: - importName: OrchestratorPage menuItem: icon: orchestratorIcon text: Orchestrator textKey: menuItem.orchestrator path: /orchestrator entityTabs: - path: /workflows title: Workflows titleKey: catalog.entityPage.workflows.title mountPoint: entity.page.workflows mountPoints: - mountPoint: entity.page.workflows/cards importName: OrchestratorCatalogTab config: layout: gridColumn: 1 / -1 if: anyOf: - IsOrchestratorCatalogTabAvailable - - package: oci://<custom_registry_url>/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator@_<digest>_ disabled: true pluginConfig: orchestrator: dataIndexService: url: http://sonataflow-platform-data-index-serviceWhere:
<custom_registry_url>- Enter the address of your custom registry where the OCI images have been mirrored.
<digest>Locate the image digests for your version of RHDH in the
dynamic-plugins.default.yamlfile. You can extract this file from the plugin catalog index image to verify the default settings for your specific release:#!/bin/bash unpack () { local IMAGE="$1" DIR="${IMAGE//:/}" DIR="/tmp/${DIR//\//-}" rm -fr "$DIR"; mkdir -p "$DIR"; container_id=$(podman create "${IMAGE}") podman export $container_id -o /tmp/image.tar && tar xf /tmp/image.tar -C "${DIR}/"; podman rm $container_id; rm -f /tmp/image.tar echo "Unpacked $IMAGE into $DIR" cd $DIR; tree -d -L 3 -I "usr|root|buildinfo" } unpack "registry.access.redhat.com/rhdh/plugin-catalog-index:{product-version)" # you can then find thedynamic-plugins.default.yamlunder /tmp/registry.access.redhat.com/rhdh/plugin-catalog-index{product-version)/dynamic-plugins.default.yaml
-
Open your
Verification
- Restart the RHDH pod and wait for the components to deploy properly.
- After deployment is complete, go to the RHDH UI and confirm that the Orchestrator UI is accessible and functioning correctly.
The successful accessibility of the Orchestrator UI confirms that the underlying components are running and the cluster recognizes the plugin.
8.5.5.5. Create a serverless workflow project
Use the Orchestrator software templates to generate a project that includes workflow definitions, Kustomize configurations, and CI/CD pipelines.
Prerequisites
-
You have installed
orchestrator-software-templates-infraandorchestrator-software-templatesHelm charts to enable templates. - You have installed RHDH and the Orchestrator plugin by using the Helm chart.
-
You have a
Quay.ioorganization and repository for storing the workflow images. - You have a GitHub or Gitlab personal access token with repository creation permissions.
- You have configured a GitOps secret for the target cluster.
-
You have set the target namespace for both the pipeline and the workflow to the
rhdhnamespace.
Procedure
Prepare the image registry. Before creating the template, configure the target repository in
Quay.io.-
Log in to your
Quay.ioorganization (for example,orchestrator-testing). -
Create a new repository (for example,
serverless-workflow-demo). - Add robot account permissions to the repository settings.
-
Log in to your
Open the Red Hat Developer Hub Catalog.

- Select the Basic workflow bootstrap project template and click Launch Template.
- Follow the template form to enter required details, including the GitHub organization, source code repository name, and a unique Workflow ID.
- For the CI/CD method, select Tekton with Argo CD to generate GitOps resources.
-
Set the Workflow Namespace to
rhdhand the GitOps Namespace toorchestrator-gitops. -
Enter your
Quay.ioregistry details. Click Review, then click Create.

- Optional: Enable persistence and provide database connection details if the workflow requires a database schema.
Verification
The system creates the following repositories:
- Source code repository: Contains the serverless workflow project.
- GitOps repository: Contains GitOps configurations, Tekton pipeline templates, and bootstrap instructions.
Additional resources
8.5.5.6. Bootstrap GitOps resources and trigger pipelines
You must manually bootstrap the GitOps resources to trigger the continuous integration (CI) pipeline.
Procedure
- Open the generated GitOps repository.
Clone the repository and navigate to the
bootstrapdirectory:$ git clone https://token:<PAT>@${{ values.gitHost }}/${{ values.orgName }}/${{ values.repoName }}.git cd <repo_name>/bootstrapNoteIf you are not authenticated, you must use a personal access token (PAT) in the clone URL. Make sure the PAT has repository access permissions.
-
Open
${{values.workflowId}}-argocd-repo.yamland replace theREPLACE_SSH_PRIVATE_KEYstring with your SSH private key. Apply the manifests to the cluster:
$ kubectl apply -f .
Applying these manifests triggers the following automated sequence:
-
CI Pipeline (Tekton): Builds the workflow image and pushes it to your
Quay.ioregistry. - CD Pipeline (Argo CD): Deploys the serverless workflow manifests to the cluster.
-
CI Pipeline (Tekton): Builds the workflow image and pushes it to your
8.5.5.7. Verify the deployment
Verify the status of your continuous integration (CI) and continuous deployment (CD) pipelines in the RHDH component catalog.
Procedure
For CI:
-
In the RHDH Catalog, select your source code repository component (for example,
onboardings). - Click the CI tab and verify that the pipeline run status is Succeeded.
- If the pipeline status does not appear in the Red Hat Developer Hub console, verify the CI status directly in your Git provider (GitHub or GitLab).
- If the pipeline fails, click the run name to view the logs and identify build errors.
-
In the RHDH Catalog, select your source code repository component (for example,
For CD:
-
Open the GitOps Resources Repository component in the Catalog (for example,
onboarding-gitops). Click the CD tab and make sure the Kubernetes resources are synced and healthy. This confirms that ArgoCD deployed the workflow to the cluster.

-
Open the GitOps Resources Repository component in the Catalog (for example,
8.5.5.8. Event-driven workflow execution for enterprise messaging integration
Event-driven workflows enable RHDH Orchestrator to respond to business events from existing messaging systems. This architecture maintains loose coupling and integrates workflows into established enterprise event streams.
8.5.5.8.1. Why CloudEvents matter for workflow integration
When you integrate workflows with message-driven systems, you need a common event format that works across different platforms and services without custom adapters for each system.
CloudEvents is a Cloud Native Computing Foundation (CNCF) specification that standardizes how to describe event data across services, platforms, and systems. This common envelope format ensures that systems can produce and consume events without custom integration code for each platform.
A CloudEvent includes required metadata fields such as the event type, source, unique identifier, and specification version. Optional fields provide additional context such as content type, data schema, subject, and timestamp. The data field contains the event payload itself, which can include structured data relevant to the event type.
For example, a CloudEvent might describe a deployment request, a compliance check trigger, or a customer order placement. Because CloudEvents standardizes the event format, multiple systems can process these events by using common libraries and tools, reducing integration complexity.
8.5.5.8.2. How your workflows respond to CloudEvents
When you configure a workflow for event-driven execution, RHDH Orchestrator processes incoming CloudEvents sourced from Apache Kafka that match specific event types. The underlying SonataFlow engine natively supports CloudEvents, which means your workflows can consume events without additional transformation or middleware.
When a CloudEvent arrives:
- The workflow engine validates the CloudEvent structure and extracts the event metadata.
- The engine matches the event type to registered workflows configured to handle that event type.
- The workflow instance starts automatically, with the CloudEvent data available as workflow input.
- The workflow runs its defined steps, which can include calling APIs, orchestrating services, or emitting additional CloudEvents.
This event-driven model differs from HTTP-triggered workflows, where you explicitly call a workflow endpoint to start the workflow.
8.5.5.8.3. Event-driven versus HTTP-triggered workflow execution
Event-driven and HTTP-triggered workflows serve different integration patterns:
- HTTP-triggered workflows
- This approach is appropriate for synchronous operations where the caller needs immediate feedback or must wait for workflow completion. The caller sends an HTTP request to a specific workflow endpoint and receives a response indicating the workflow status. This pattern works well for user-initiated actions in web applications or API integrations that require request-response semantics.
- Event-driven workflows
- Use this approach when your event producers need to continue working immediately without waiting for workflow completion. Your producers publish CloudEvents to Apache Kafka, and workflows start automatically when events arrive, without blocking the producer. This pattern supports fire-and-forget semantics, enabling the producer to continue processing without blocking on the workflow. Event-driven workflows also provide better scalability for high-volume workloads and support complex event routing and filtering capabilities that the message broker provides.
8.5.5.8.4. Benefits of event-driven workflows
Integrating workflows with CloudEvents and message brokers provides several architectural advantages:
- Loose coupling
- Event producers do not need direct knowledge of workflow endpoints or RHDH infrastructure. They publish standardized CloudEvents to a message broker, and the workflow engine consumes events independently. This separation allows services to evolve independently without tight coupling.
- Asynchronous execution
- Event producers do not block waiting for workflows to complete. This improves system responsiveness and allows workflows to handle long-running operations without impacting the producing system.
- Architectural consistency
- Organizations that have standardized on message-oriented middleware can integrate RHDH workflows into existing event-driven architectures without creating HTTP-based exceptions. This maintains architectural consistency across the enterprise.
- Enterprise messaging standards
- CloudEvents specification provides a vendor-neutral event format that major cloud providers and messaging platforms support. This ensures portability and reduces vendor lock-in.
8.5.5.8.5. CloudEvent type to Kafka topic mapping
When you configure workflows to consume CloudEvents from Kafka, you decide how CloudEvent types map to Kafka topics based on your workflow design and organizational standards.
A common pattern maps each workflow to a specific Kafka topic, where the topic name corresponds to the CloudEvent type that triggers the workflow. For example, a workflow that processes deployment requests might subscribe to a deployment.request topic, and producers would publish CloudEvents with type: deployment.request to that topic.
You can organize workflows by business capability and route events to the appropriate workflow by using Kafka topic-based routing. You can also use Kafka consumer groups to scale workflow processing across multiple RHDH instances.
8.5.5.8.6. When to use CloudEvent triggering
Choose CloudEvent-based workflow triggering when:
- Your organization has standardized on message brokers such as Apache Kafka for system-to-system communication.
- Your workflows respond to business events produced by other systems in your architecture.
- You need asynchronous, fire-and-forget workflow execution.
- You want to decouple workflow callers from RHDH infrastructure.
- Your workflows integrate into existing event-driven architectural patterns.
Use HTTP-triggered workflows when:
- Your users need immediate workflow feedback or synchronous responses.
- Your workflows serve as APIs for external systems that expect request-response patterns.
- Your organization has not deployed message broker infrastructure.
- Your workflow execution is strictly on-demand rather than event-driven.
8.5.5.9. Enable event-driven workflows by configuring Kafka connectivity
Configure Apache Kafka connectivity in the Orchestrator backend to enable workflows triggered by CloudEvents. This configuration allows workflows to respond asynchronously to business events from your messaging infrastructure.
Prerequisites
- You have enabled Orchestrator plugins.
- You have deployed Apache Kafka broker infrastructure and ensured it is accessible from RHDH.
- You have Kafka broker URLs and connection credentials.
- You have verified network connectivity between RHDH and Kafka brokers.
Procedure
Locate your Developer Hub application configuration file.
The location depends on your deployment method:
-
For Operator deployments: The configuration is in a ConfigMap, typically named
my-rhdh-app-config. -
For Helm deployments: The configuration is in the
values.yamlfile or a custom configuration file referenced in your Helm values.
-
For Operator deployments: The configuration is in a ConfigMap, typically named
Add the
orchestrator.kafkaconfiguration section to yourapp-config.yamlfile.orchestrator: kafka: clientId: my-rhdh-orchestrator brokers: - kafka-broker-1.example.com:9092 - kafka-broker-2.example.com:9092 - kafka-broker-3.example.com:9092 # logLevel override for the orchestrator kafka services. Defaults to INFO which is 4 # logLevel values based on KafkaJS values https://kafka.js.org/docs/configuration#logging # logLevel: 5 // DEBUG logLevel: 4where:
clientId- Unique identifier for the RHDH Kafka client. This identifier is displayed in Kafka broker logs and metrics.
brokers- Array of Kafka broker URLs. Include multiple brokers for high availability.
logLevel-
Optional. Kafka client logging level. Valid numeric values based on KafkaJS values are
0(NOTHING),1(ERROR),2(WARN),4(INFO), or5(DEBUG). Default is4(INFO).
Apply the configuration changes.
For Operator deployments: Update the ConfigMap and restart the RHDH instance by scaling the deployment to zero and back to the target replica count, or by deleting the pod to trigger a restart.
Replace
<my_deployment_name>with the name of your deployment:$ oc rollout restart deployment/<my_deployment_name>
For Helm deployments: Upgrade the Helm release with the updated configuration.
$ helm upgrade my-rhdh-custom-resource redhat-developer/backstage -f values.yaml -n my-rhdh-project
Verification
Check the orchestrator-backend plugin logs for Kafka connection messages.
Replace
<my_deployment_name>with the name of your deployment:$ oc logs deployment/<my_deployment_name> | grep -i kafka
Successful connection logs include messages indicating the Kafka client has connected to the broker cluster.
- Navigate to the Orchestrator plugin in the RHDH UI.
Verify that the Run as Event button is displayed next to workflows.
The button is only visible when Kafka connectivity is successfully configured.
Troubleshooting
If the Run as Event button does not appear:
- Verify that the Kafka broker URLs are correct and accessible from the RHDH pod.
- Check the orchestrator-backend logs for connection errors or authentication failures.
- Confirm that network policies allow traffic between RHDH and the Kafka brokers.
-
Verify that the
orchestrator.kafkaconfiguration section is correctly formatted in the configuration file.
8.5.5.10. Run workflows asynchronously through the UI with CloudEvents
Publish CloudEvents to Apache Kafka from the RHDH UI to trigger workflows asynchronously. This method enables fire-and-forget operation without blocking on workflow completion.
Prerequisites
- You have configured Kafka connectivity for the Orchestrator.
- You have deployed an event-type workflow that appears in the Orchestrator plugin.
Procedure
- In the RHDH UI, navigate to the Orchestrator plugin.
- In the workflows list, locate the workflow you want to trigger.
Click the Run as Event button next to the workflow.
NoteThe Run as Event button appears only when you have configured Kafka connectivity and the workflow supports event-driven execution.
If the workflow requires input data, complete the workflow input form.
The form fields correspond to the workflow’s input schema. The CloudEvent data payload includes the values you provide.
Click Submit to send the CloudEvent to Kafka.
The RHDH UI transmits a CloudEvent to the configured Kafka broker with the workflow input data. The workflow starts when the Kafka broker delivers the event to the SonataFlow engine.
Monitor the workflow status.
After submitting the CloudEvent, one of two outcomes occurs:
- Immediate start
- If the workflow starts before the UI timeout period, the UI navigates to the workflow instance detail page, where you can monitor progress.
- Delayed start
-
If the workflow has not started when the UI timeout expires, the UI displays an informational message indicating that it sent the event to Kafka as a
kafkaEvent. The UI navigates to the workflow runs list, where the workflow instance appears when the workflow starts.
If the workflow does not start immediately, locate the workflow in the workflow runs list.
The workflow instance appears in the list when the Kafka broker delivers the CloudEvent and the workflow engine starts the workflow. Depending on Kafka broker latency and workflow engine processing time, this can take several seconds.
Troubleshooting
If the workflow does not appear in the workflow runs list after several minutes:
- Verify that the Kafka broker is running and accessible.
- Check the orchestrator-backend logs for errors related to Kafka message publishing.
- Confirm that you configured the workflow to consume CloudEvents from the correct Kafka topic.
- Verify that the CloudEvent type matches the workflow’s event type configuration.
8.5.5.11. CloudEvent structure reference for workflow design and troubleshooting
CloudEvent attribute specifications and Kafka topic mapping patterns help you design workflows that consume events from external systems. Understanding this structure is essential for troubleshooting event-driven workflow integration.
8.5.5.11.1. CloudEvent specification structure
CloudEvents use a standardized JSON structure with required and optional attributes.
| Attribute | Description | Required |
|---|---|---|
|
|
CloudEvents specification version. RHDH uses version |
Yes |
|
|
Event type identifier. This typically corresponds to the Kafka topic name and the workflow event type. |
Yes |
|
|
URI identifying the context in which the event occurred. For example, the service or system that produced the event. |
Yes |
|
|
Unique identifier for the event instance. Each CloudEvent must have a unique ID. |
Yes |
|
|
Content type of the data value. Common values are |
No |
|
|
URI of the schema that the data adheres to. |
No |
|
|
Subject of the event in the context of the event producer. For example, a resource identifier or entity name. |
No |
|
|
Timestamp when the event occurred, in RFC3339 format. |
No |
|
|
Event payload containing domain-specific data. This is where workflow input parameters are included. |
No |
8.5.5.11.2. Example CloudEvent payload
An example of a CloudEvent that triggers a deployment workflow:
{
"specversion": "1.0",
"type": "deployment.request",
"source": "/api/deployments",
"id": "a234-5678-9abc-def0",
"datacontenttype": "application/json",
"time": "2025-08-15T14:30:00Z",
"data": {
"applicationName": "my-application",
"environment": "production",
"version": "2.1.0",
"approver": "jane.doe@example.com"
}
}In this example:
-
The
typefield (deployment.request) identifies the event type and typically matches the Kafka topic name. -
The
sourcefield indicates the API endpoint that produced the event. -
The
idfield provides a unique identifier for this specific deployment request. -
The
datafield contains the workflow input parameters required to run the deployment.
8.5.5.11.3. How RHDH constructs CloudEvents
When you use the Run as Event button in the RHDH UI, the Orchestrator backend plugin constructs a CloudEvent automatically:
- The plugin generates a unique event ID by using UUID format.
-
The plugin sets the
typefield based on the workflow’s event type configuration. -
The plugin sets the
sourcefield to identify RHDH as the event producer. -
The plugin sets
specversionto1.0. -
The plugin includes the workflow input form data in the
datafield. - The plugin publishes the CloudEvent to the configured Kafka broker.
8.5.5.11.4. Workflow input data structure
When you design workflows that consume CloudEvents, the workflow input schema should match the structure of the CloudEvent data field.
For example, if your workflow requires the following input:
{
"applicationName": "string",
"environment": "string",
"version": "string"
}
The CloudEvent data field must provide these properties. When you trigger the workflow from the RHDH UI, the workflow input form collects these values and includes them in the data field of the published CloudEvent.
8.5.5.11.5. CloudEvent type and Kafka topic mapping
The mapping between CloudEvent types and Kafka topics depends on your workflow configuration and Kafka topic design:
- Single topic per workflow type
-
Each workflow subscribes to a dedicated Kafka topic, where the topic name matches the CloudEvent
typefield. For example, a workflow handlingdeployment.requestevents subscribes to thedeployment.requesttopic. This pattern provides clear separation between workflow types and simplifies event routing. - Shared topic with event filtering
-
Multiple workflow types subscribe to a shared Kafka topic, and each workflow filters events based on the
typefield. This pattern reduces the number of Kafka topics but requires workflows to include event filtering logic.
The SonataFlow workflow definition specifies which event types the workflow consumes, and the Kafka topic configuration determines where the workflow engine listens for events.
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
After an administrator configures TechDocs, a developer can add documentation by importing from a remote repository, creating standalone docs, or enabling docs for an existing catalog entity.
8.6.2. About TechDocs
Your organization can use the TechDocs plugin to create, find, and manage documentation in a central location and in a standardized way.
The Red Hat Developer Hub instance includes the TechDocs plugin preinstalled and enabled by default. You can also enhance your technical documentation experience with built-in TechDocs features and add-ons. For example:
- Docs-like-code approach
- Write your technical documentation in Markdown files that are stored inside your project repository along with your code.
- Documentation site generation
- Use MkDocs to create a full-featured, Markdown-based, static HTML site for your documentation that is rendered centrally in Developer Hub.
- Documentation site metadata and integrations
- See additional metadata about the documentation site alongside the static documentation, such as the date of the last update, the site owner, top contributors, open GitHub issues, Slack support channels, and Stack Overflow Enterprise tags.
- Built-in navigation and search
- Locate the information that you need within a document quickly and easily.
- Add-ons
- Make your documentation more functional and interactive with supported TechDocs add-ons. Some add-ons are preinstalled and enabled by default. To extend the default functionality, you can dynamically load external and third-party add-ons into your Red Hat Developer Hub instance. If you want to further customize your TechDocs experience, you can create add-ons that meet specific documentation needs for your organization.
8.6.3. Import documentation into TechDocs from a remote repository
Teams can store their documentation files in the same remote repository where they store their code files. You can import documentation into your TechDocs plugin from a remote repository that contains the documentation files that your team uses.
Prerequisites
- Your organization has documentation files stored in a remote repository.
-
You have a
mkdocs.yamlfile in the root directory of your repository. -
You have the
catalog.entity.createandcatalog.location.createpermissions to import documentation into TechDocs from a remote repository.
Procedure
- In your Red Hat Developer Hub instance, click Catalog > Self-service > Register Existing Component.
In the Select URL box, enter the URL to the
catalog-info.yamlfile that you want to import from your repository using the following format:https://github.com/<project_name>/<repo_name>/blob/<branch_name>/<file_directory>/catalog-info.yaml- Click Analyze
- Click Finish
Verification
- In the Developer Hub navigation menu, click Docs.
- Verify that the documentation that you imported is listed in the table on the Documentation page.
8.6.4. Search for relevant content
To quickly find the information needed for your services, search or filter the TechDocs catalog. Narrowing your search helps you find relevant resources without browsing many repositories.
Procedure
- In the Red Hat Developer Hub navigation menu, click Docs.
On the Documentation page, use the Search bar or filters to locate your document:
- Search: Enter keywords to find specific terms within documents.
- Filter by Owner: View documents owned by specific users or groups.
- Filter by Tags: Narrow results by specific labels or categories.
- Filter by Owned: View documents belonging to you or your group.
Filter by Starred: View your bookmarked favorites.
The results update automatically to show the number of documents that meet your criteria.
8.6.6. Make changes to project documentation in TechDocs
You can edit a document in your TechDocs plugin directly from the document book page. Any authorized user in your organization can edit a document regardless of whether or not they are the owner of the document.
Procedure
- In the Red Hat Developer Hub navigation menu, click Docs.
- In the Documentation table, click the name of the document that you want to edit.
- In the document, click the Edit this page icon to open the document in your remote repository.
- In your remote repository, edit the document as needed.
- Use the repository provider UI and your usual team processes to commit and merge your changes.
8.6.7. Add video content to enhance TechDocs
You can use <iframe> elements to add video content to enhance your experience with TechDocs.
Prerequisites
- An administrator has configured your AWS S3 bucket to store TechDocs sites.
-
An administrator has configured the appropriate
techdocs.sanitizer.allowedIframeHostsandbackend.cspsettings in yourapp-config.yamlfile.
Procedure
In the section of the TechDocs file that you want to embed a video into, add the following configuration:
<iframe width="<video_width>" height="<video_height>" src="<video_url>" title="<video_title>" frameborder="<frame_border>" allow="picture-in-picture" allowfullscreen> </iframe>
where
- <video_width>
-
Specifies the width of the video in number of pixels, for example,
672. - <video_height>
-
Specifies the height of the video in number of pixels, for example,
378. - <video_url>
-
Specifies the url of the video, for example,
https://www.youtube.com/watch?v=LB1w8hjBt5k. - <video_title>
-
Specifies the title of the video, for example,
Red Hat Developer Hub Overview Video. - <frame_border>
Specifies the size of the frame border in number of pixels, for example,
0. Use a value of0for no border.NoteTechDocs uses DOMPurify to sanitize HTML. To prevent DOMPurify from removing the
<iframe>elements, you must list every permitted video host, such as www.youtube.com, under thetechdocs.sanitizer.allowedIframeHostssection of yourapp-config.yamlfile. You must also add the video host to thebackend.cspsection of yourapp-config.yamlfile.
In the
frame-srcandallowedIframeHostsfields of yourapp-config.yamlfile, add any video hosts that you want to use. You can add multiple hosts. For example:backend: csp: connect-src: ['https:'] frame-src: ['https://www.youtube.com/'] techdocs: builder: external sanitizer: allowedIframeHosts: - www.youtube.com - <additional_video_host_url> publisher: type: awsS3 awsS3: bucketName: $AWS_S3_BUCKET_NAME} accountId: $AWS_ACCOUNT_ID} region: $AWS_REGION}
8.6.8. Configure TechDocs storage and CI/CD pipelines
8.6.8.1. Configure TechDocs storage and CI/CD pipelines
Configure storage and CI/CD pipelines for TechDocs to enable documentation publishing.
8.6.8.2. Create standalone documentation in TechDocs
You can create standalone documentation in TechDocs for content that is not tied to a specific codebase, such as onboarding guides, architecture overviews, or team runbooks.
Prerequisites
- An administrator has configured the TechDocs plugin.
-
You have the
catalog.entity.createandcatalog.location.createpermissions.
Procedure
Create a directory for your documentation project with the following structure:
my-documentation/ catalog-info.yaml mkdocs.yml docs/ index.mdCreate a
catalog-info.yamlfile that defines a documentation entity:apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-documentation description: Onboarding guide for new team members annotations: backstage.io/techdocs-ref: dir:. spec: type: documentation lifecycle: production owner: group:default/my-teamCreate an
mkdocs.ymlfile to configure the documentation site:site_name: My Documentation nav: - Home: index.md plugins: - techdocs-core
-
Create a
docs/directory containing at least anindex.mdfile with your documentation content in Markdown. - Commit and push the directory to a Git repository.
In your Developer Hub instance, register the documentation entity:
- Click Catalog > Self-service > Register Existing Component.
-
In the Select URL box, enter the URL to the
catalog-info.yamlfile in your repository. - Click Analyze, then click Finish.
Verification
- In the Developer Hub navigation menu, click Docs.
Verify that your standalone documentation appears in the table on the Documentation page.
NoteThe documentation might not appear immediately. Developer Hub refreshes catalog entities periodically, which can take up to 45 minutes. To trigger a refresh sooner, navigate to the entity in the software catalog and click the refresh button on the Overview tab.
8.6.8.3. Enable documentation for an existing entity
You can add TechDocs documentation to a component that is already registered in the Developer Hub software catalog but does not yet have documentation configured.
Prerequisites
- An existing entity is registered in the Developer Hub software catalog.
- You have write access to the entity’s source repository.
Procedure
Add the
backstage.io/techdocs-refannotation to thecatalog-info.yamlfile in your repository:apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: my-component annotations: backstage.io/techdocs-ref: dir:. spec: type: service lifecycle: production owner: group:default/my-teamCreate an
mkdocs.ymlfile in the repository root:site_name: My Component Documentation nav: - Home: index.md
NoteDeveloper Hub automatically adds the
techdocs-coreplugin tomkdocs.ymlif it is missing.-
Create a
docs/directory in the repository root containing at least anindex.mdfile with your documentation content in Markdown. - Commit, push, and merge the changes.
Verification
- In the Developer Hub software catalog, navigate to your component.
Verify that a Docs tab appears with your documentation.
NoteThe Docs tab might not appear immediately. Developer Hub refreshes catalog entities periodically, which can take up to 45 minutes. To trigger a refresh sooner, click the refresh button on the entity’s Overview tab.
8.6.8.4. Configuring storage for TechDocs files
The TechDocs publisher stores generated files in local storage or in cloud storage, such as AWS S3 or OpenShift Data Foundation.
8.6.8.5. Configure Amazon S3 or OpenShift Data Foundation buckets
8.6.8.5.1. Configure Amazon S3 or OpenShift Data Foundation buckets
Configure Amazon S3 or OpenShift Data Foundation for TechDocs file storage and make object storage accessible to containers.
8.6.8.5.2. Configure Amazon S3 for file storage
You can create a dedicated Amazon S3 bucket to store TechDocs sites. Red Hat Developer Hub uploads TechDocs to this bucket and serves them from the same location.
Prerequisites
- You are logged in to your AWS account as an administrator.
Procedure
On the AWS console, create an AWS S3 bucket.
- On the Create bucket page, enter a Bucket name and use the default selections for all other settings.
- Create an IAM policy to give authorized users permissions to generate and publish TechDocs for your organization.
On the Create policy > Specify permissions page, in the Policy editor, enter the following JSON content:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "TechDocsList", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::_<bucket_name>_" }, { "Sid": "TechDocsObjects", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject", "s3:DeleteObjectVersion" ], "Resource": "arn:aws:s3:::_<bucket_name>_/*" } ] }where
- <bucket_name>
- Specifies the name of your Amazon S3 bucket.
- On the Create policy > Specify permissions page, enter a Policy name.
- Assign the IAM policy to a new or existing user.
Generate a new access key and a new secret access key.
NoteYou can use the newly created access keys to generate a TechDocs pipeline with GitHub Actions.
From the OpenShift Container Platform web console, click Topology > Actions > Restart rollout to restart the pod.
NoteYou must restart the pod to apply the configuration changes.
Verification
- Go to your Amazon S3 bucket to see a set of static site files in your Objects list.
8.6.8.5.3. Configure OpenShift Data Foundation for file storage
You can configure OpenShift Data Foundation to store the files that TechDocs generates instead of relying on other cloud storage solutions.
OpenShift Data Foundation provides an ObjectBucketClaim custom resource (CR) that you can use to request an S3-compatible bucket backend. You must install the OpenShift Data Foundation Operator to use this feature.
For air-gapped environments, using OpenShift Data Foundation is the recommended storage for TechDocs.
Prerequisites
-
An OpenShift Container Platform administrator has installed the OpenShift Data Foundation Operator in Red Hat OpenShift Container Platform, created an OpenShift Data Foundation cluster and configured the
StorageSystemschema. For more information, see Deploying OpenShift Data Foundation using Amazon Web Services.
Procedure
Create an
ObjectBucketClaimCR where the generated TechDocs files are stored. For example:apiVersion: objectbucket.io/v1alpha1 kind: ObjectBucketClaim metadata: name: <rhdh_bucket_claim_name> spec: generateBucketName: <rhdh_bucket_claim_name> storageClassName: openshift-storage.noobaa.io
NoteCreating the Developer Hub
ObjectBucketClaimCR automatically creates both the Developer HubObjectBucketClaimconfig map and secret. The config map and secret have the same name as theObjectBucketClaimCR.After you create the
ObjectBucketClaimCR, you can use the information stored in the config map and secret to make the information accessible to the Developer Hub container as environment variables. Depending on the method that you used to install Developer Hub, you add the access information to either the Red Hat Developer Hub Helm chart or Operator configuration.
Additional resources
8.6.8.5.3.1. Make object storage accessible to containers by using the Helm chart
Add ObjectBucketClaim access information to the Helm chart configuration to make it accessible to the Developer Hub container as environment variables.
Creating an ObjectBucketClaim custom resource (CR) automatically generates both the Developer Hub ObjectBucketClaim config map and secret. The config map and secret contain ObjectBucket access information. The Helm chart uses the following environment variables:
-
BUCKET_NAME -
BUCKET_HOST -
BUCKET_PORT -
BUCKET_REGION -
BUCKET_SUBREGION -
AWS_ACCESS_KEY_ID -
AWS_SECRET_ACCESS_KEY
These variables are then used in the TechDocs plugin configuration.
Prerequisites
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Helm chart.
-
You have created an
ObjectBucketClaimCR for storing files generated by TechDocs. For more information see Using OpenShift Data Foundation for file storage
Procedure
In the
upstream.backstagekey in the Helm chart values, enter the name of the Developer HubObjectBucketClaimsecret as the value for theextraEnvVarsSecretsfield and theextraEnvVarsCMfield. For example:upstream: backstage: extraEnvVarsSecrets: - <rhdh_bucket_claim_name> extraEnvVarsCM: - <rhdh_bucket_claim_name>
8.6.8.5.3.1.1. Example TechDocs Plugin configuration for the Helm chart
The following example shows a Developer Hub Helm chart configuration for the TechDocs plugin.
global:
dynamic:
includes:
- 'dynamic-plugins.default.yaml'
plugins:
- disabled: false
package: ./dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic
pluginConfig:
techdocs:
builder: external
generator:
runIn: local
publisher:
awsS3:
bucketName: '${BUCKET_NAME}'
credentials:
accessKeyId: '$AWS_ACCESS_KEY_ID}'
secretAccessKey: '$AWS_SECRET_ACCESS_KEY}'
endpoint: 'https://${BUCKET_HOST}'
region: '${BUCKET_REGION}'
s3ForcePathStyle: true
type: awsS38.6.8.5.3.2. Make object storage accessible to containers by using the Operator
Add ObjectBucketClaim access information to the Operator configuration to make it accessible to the Developer Hub container as environment variables.
Creating an ObjectBucketClaim custom resource (CR) automatically generates both the Developer Hub ObjectBucketClaim config map and secret. The config map and secret contain ObjectBucket access information. The Operator uses the following environment variables:
-
BUCKET_NAME -
BUCKET_HOST -
BUCKET_PORT -
BUCKET_REGION -
BUCKET_SUBREGION -
AWS_ACCESS_KEY_ID -
AWS_SECRET_ACCESS_KEY
These variables are then used in the TechDocs plugin configuration.
Prerequisites
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Operator.
-
You have created an
ObjectBucketClaimCR for storing files generated by TechDocs.
Procedure
In your
BackstageCR, enter the name of the Developer HubObjectBucketClaimconfig map as the value for thespec.application.extraEnvs.configMapsfield and enter the Developer HubObjectBucketClaimsecret name as the value for thespec.application.extraEnvs.secretsfield. For example:apiVersion: rhdh.redhat.com/v1alpha5 kind: {backstage} metadata: name: <name> spec: application: extraEnvs: configMaps: - name: <rhdh_bucket_claim_name> secrets: - name: <rhdh_bucket_claim_name>
8.6.8.5.3.2.1. Example TechDocs Plugin configuration for the Operator
The following example shows a Red Hat Developer Hub Operator config map configuration for the TechDocs plugin.
kind: ConfigMap
apiVersion: v1
metadata:
name: dynamic-plugins-rhdh
data:
dynamic-plugins.yaml: |
includes:
- dynamic-plugins.default.yaml
plugins:
- disabled: false
package: ./dynamic-plugins/dist/backstage-plugin-techdocs-backend-dynamic
pluginConfig:
techdocs:
builder: external
generator:
runIn: local
publisher:
awsS3:
bucketName: '${BUCKET_NAME}'
credentials:
accessKeyId: '$AWS_ACCESS_KEY_ID}'
secretAccessKey: '$AWS_SECRET_ACCESS_KEY}'
endpoint: 'https://${BUCKET_HOST}'
region: '${BUCKET_REGION}'
s3ForcePathStyle: true
type: awsS38.6.8.6. Streamline documentation builds using GitHub Actions
For production use, deploy TechDocs by building documentation in CI/CD, publishing to external storage such as AWS S3, and configuring read-only mode. You can automate this workflow using GitHub Actions to generate and publish TechDocs when users update documentation files.
Prerequisites
- The TechDocs plugin is enabled and configured on your Red Hat Developer Hub instance.
- Your organization has documentation files stored in a remote repository.
- You have an mkdocs.yaml file located in the root directory of your repository.
-
You have the
catalog.entity.createandcatalog.location.createpermissions to import documentation into TechDocs from a remote repository. - You have an AWS S3 bucket to store your TechDocs sites.
- Minimal IAM Policies are configured for your S3 bucket, granting both Write and Read access.
- An administrator has created an IAM User, attached the necessary policy, and generated an access key in the AWS console.
Procedure
Set up the GitHub Actions workflow.
On GitHub, create a fork of the RHDH TechDocs Pipeline repository.
NoteThe
rhdh-techdocs-pipelinerepository contains agenerate-and-publish-techdocs.yamlworkflow that automatically generates TechDocs from the docs folder and publishes them to an Amazon S3 bucket.- Use the GitHub GUI to make sure that all of the permissions required to run the workflow are enabled.
Add the Repository secrets required to connect the workflow to your AWS account, for example,
TECHDOCS_S3_BUCKET_NAME,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY,AWS_REGION.NoteThe default
mkdocs.yamlfile in therhdh-techdocs-pipelineworkflow installs thetechdocs-coreandminifyplugins.-
Optional: Customize the default structure or files of the
rhdh-techdocs-pipelinerepository to meet the needs of your organization. -
Optional: Add other
mkdocsplugins that you want to use by adding the name of the plugins to thepluginssection of themkdocs.yamlfile and to thesteps.name: install mkdocs and mkdocs pluginssection of thegenerate-and-publish-techdocs.yamlfile.
-
. In the navigation menu of the OpenShift Container Platform console, click ConfigMaps and select your RHDH
app-config.yamlfile. Update the
app-config.yamlfile to enable your Amazon S3 bucket to serve TechDocs to your RHDH instance. For example:techdocs: builder: external publisher: type: awsS3 awsS3: bucketName: $AWS_S3_BUCKET_NAME} accountId: $AWS_ACCOUNT_ID} region: $AWS_REGION} aws: accounts: - accountId: $AWS_ACCOUNT_ID} accessKeyId: $AWS_ACCESS_KEY_ID} secretAccessKey: $AWS_SECRET_ACCESS_KEY} catalog: locations: - type: url target: https://github.com/<your_org>/rhdh-techdocs-pipeline/blob/main/catalog-info.yaml- Click Save.
In the navigation menu of the OpenShift Container Platform console, click Topology and restart the pod.
NoteChanges to the
docsfolder or themkdocs.yamlfile trigger therhdh-techdocs-pipelineworkflow to run. After therhdh-techdocs-pipelineworkflow runs successfully, the generated TechDocs are uploaded to your Amazon S3 bucket.
Verification
- Go to your RHDH instance and click Docs to see the TechDocs served from your Amazon S3 bucket.
8.6.9. Configuring CI/CD to generate and publish TechDocs sites
You can generate documentation on CI/CD and publish to cloud storage by using the techdocs-cli CLI tool.
TechDocs reads the static generated documentation files from a cloud storage bucket, such as OpenShift Data Foundation. The documentation site is generated on the CI/CD workflow associated with the repository that has the documentation files.
You can use the following example to create a script for TechDocs publication:
# Prepare REPOSITORY_URL='https://github.com/org/repo' git clone $REPOSITORY_URL cd repo # Install @techdocs/cli, mkdocs and mkdocs plugins npm install -g @techdocs/cli pip install "mkdocs-techdocs-core==1.*" # Generate techdocs-cli generate --no-docker # Publish techdocs-cli publish --publisher-type awsS3 --storage-name <bucket/container> --entity <Namespace/Kind/Name>
The TechDocs workflow starts the CI when a user makes changes in the repository containing the documentation files. You can configure the workflow to start only when files inside the docs/ directory or mkdocs.yml are changed.
8.6.10. Install TechDocs add-ons
8.6.10.1. Install TechDocs add-ons
Install and configure TechDocs add-ons to extend the functionality of the TechDocs plugin in Red Hat Developer Hub.
TechDocs add-ons supported by Red Hat are exported to the TechDocs plugin by the backstage-plugin-techdocs-module-addons-contrib plugin package, which is preinstalled on Red Hat Developer Hub and enabled by default. The <ReportIssue /> add-on is part of the default configuration of this plugin package and comes ready to use in the TechDocs plugin.
You can install other supported TechDocs add-ons by configuring the backstage-plugin-techdocs-module-addons-contrib plugin package in the Red Hat Developer Hub ConfigMap or Helm chart, depending on whether you use the Operator or Helm chart for installation. If you want to customize your TechDocs experience beyond the functions of the supported add-ons, you can install third-party add-ons on your TechDocs plugin, including add-ons that you create yourself.
8.6.10.2. Install external or third-party add-ons
8.6.10.2.1. Install external or third-party add-ons
Install external or third-party TechDocs add-ons using the Operator or Helm Chart.
8.6.10.2.2. Install and configure an external TechDocs add-on using the Operator
You can use a dynamic plugin to import TechDocs add-ons into your TechDocs plugin. If you use the Red Hat Developer Hub Operator to install the dynamic plugin, you can add TechDocs add-ons to the plugin package in your ConfigMap.
Preinstalled add-ons, such as ReportIssue, are included in the default backstage-plugin-techdocs-module-addons-contrib package configuration. External add-ons that are supported by Red Hat are installed by manually adding them to the techdocsAddons section of the configuration file.
Procedure
- From the Developer perspective in the OpenShift Container Platform web console, click ConfigMaps > Create ConfigMap.
- From the Create ConfigMap page, select the YAML view option in the Configure via field.
In the newly created ConfigMap, add the default
backstage-plugin-techdocs-module-addons-contribpackage configuration. For example: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-techdocs-module-addons-contrib disabled: false pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssueIn the
techdocsAddonssection of the ConfigMap, addimportName: <external_techdocs_add-on>for each external TechDocs add-on that you want to add from the specified plugin package. For example: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-techdocs-module-addons-contrib disabled: false pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssue - importName: <external_techdocs_add-on>where:
- <external_techdocs_add-on>
-
Specifies the external TechDocs add-on that you want to install, for example,
TextSizeorLightBox.
- Click Create.
- In the web console navigation menu, click Topology.
- Click the overflow menu for the Red Hat Developer Hub instance that you want to use and select Edit Backstage to load the YAML view of the Red Hat Developer Hub instance.
In your
BackstageCR, add thedynamicPluginsConfigMapName: <dynamic_plugins_configmap>key-value pair. For example:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: my-rhdh spec: application: # ... dynamicPluginsConfigMapName: <dynamic_plugins_configmap> # ...where:
- <dynamic_plugins_configmap>
-
Specifies the name of your dynamic plugins ConfigMap for your Red Hat Developer Hub instance, for example,
dynamic-plugins-rhdh.
- Click Save.
- In the web console navigation menu, click Topology and wait for the Red Hat Developer Hub pod to start.
- Click the Open URL icon to start using the Red Hat Developer Hub platform with the new configuration changes.
8.6.10.2.3. Install and configure an external TechDocs add-on using the Helm chart
You can use a dynamic plugin to import TechDocs add-ons into your TechDocs plugin. If you use the Red Hat Developer Hub Helm chart to install the dynamic plugin, you can add TechDocs add-ons to the plugin package in your Helm chart.
Preinstalled add-ons, such as ReportIssue, are included in the default backstage-plugin-techdocs-module-addons-contrib package configuration. External add-ons that are supported by Red Hat are installed by manually adding them to the techdocsAddons section of the configuration file.
Prerequisites
- The TechDocs plugin is installed and enabled.
Procedure
In your Helm chart, add the
global.dynamicparameters required to install a dynamic plugin, as shown in Installing dynamic plugins using the Helm chartNoteThe default configuration includes the
dynamic-plugins.default.yamlfile, which contains all of the dynamic plugins, including TechDocs add-ons, that are preinstalled in Red Hat Developer Hub, whether they are enabled or disabled by default.In your Helm chart, add the default
backstage-plugin-techdocs-module-addons-contribpackage configuration. For example:global: dynamic: plugins: - package: ./dynamic-plugins/dist/backstage-plugin-techdocs-module-addons-contrib disabled: false pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssueIn the
techdocsAddonssection of the Helm chart, addimportName: <external_techdocs_add-on>for each external TechDocs add-on that you want to add from the specified plugin package. For example:global: dynamic: plugins: - package: ./dynamic-plugins/dist/backstage-plugin-techdocs-module-addons-contrib disabled: false pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssue - importName: <external_techdocs_add-on>where:
- <external_techdocs_add-on>
-
Specifies the external TechDocs add-on that you want to install, for example,
TextSizeorLightBox.
8.6.10.2.4. Install and configure a third-party TechDocs add-on
You can install a compatible third-party TechDocs add-on on your Red Hat Developer Hub instance as a front-end dynamic plugin.
Prerequisites
-
The third-party TechDocs add-on has a valid
package.jsonfile in its root directory, containing all required metadata and dependencies. - The third-party plugin is packaged as a dynamic plugin in an OCI image. For alternative package types, see link:Installing third-party plugins in Red Hat Developer Hub.
-
You have installed the
yarnpackage manager. - The third-party plugin is packaged as a dynamic plugin in an OCI image.* You have installed and configured Node.js and NPM.
Procedure
Install the third-party plugin that you want to use to import your third-party add-on by entering the following command:
$ yarn install
- Obtain the source code for the third-party TechDocs add-on that you want to use.
Export the TechDocs add-on as a dynamic plugin using the following command:
$ npx @red-hat-developer-hub/cli@latest plugin export
NoteThe
@latesttag pulls the latest version of the @red-hat-developer-hub/cli package, which is compatible with the most recent features and fixes. Use a version that is compatible with your Red Hat Developer Hub version.To package the third-party TechDocs add-on as a dynamic plugin, navigate to the root directory where the plugin is stored (not the dist-dynamic directory) and run the
npxcommand with the--tagoption to specify the image name and tag. For example:$ npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/<user_name>/<techdocs_add-on_image>:latest
NoteThe output of the package-dynamic-plugins command provides the file path to the plugin for use in the
dynamic-plugin-config.yamlfile.- To publish the third-party TechDocs add-on to a Quay repository, push the image to a registry using one of the following commands, depending on your virtualization tool:
To use
podman, enter the following command:$ podman push quay.io/<user_name>/<techdocs_add-on_image>:latest
To use
docker, enter the following command:$ docker push quay.io/<user_name>/<techdocs_add-on_image>:latest
Open your
dynamic-plugins.yamlfile to view or modify the configuration for the third-party TechDocs add-on. For example:plugins: - package: oci://quay.io/<user_name>/<techdocs_add-on_image>:latest disabled: false pluginConfig: dynamicPlugins: frontend: <techdocs_add-on_package> techdocsAddons: - importName: <third-party_add-on_name> config: props: <techdocs_add-on_property_key>: <techdocs_add-on_property_value>where
- <user_name>
- Specifies your Quay user name or organization name.
- <techdocs_add-on_image>
-
Specifies the name of the image for the third-party add-on that you want to use, for example,
mermaid. - <techdocs_add-on_package>
-
Specifies the , for example,
backstage-plugin-techdocs-addon-mermaid. - <third-party_add-on_name>
-
Specifies the name of the third-party add-on that you want to use, for example,
Mermaid. - <techdocs_add-on_property_key>
-
Specifies the name of the custom property that can be passed to the third-party add-on, for example,
themeVariables. Properties are specific to each add-on. You can list multiple properties for an add-on. - <techdocs_add-on_property_value>
-
Specifies the value of a property key for the third-party add-on, for example,
lineColor: #000000.
8.6.10.3. Disable or remove TechDocs add-ons
8.6.10.3.1. Disable or remove TechDocs add-ons
Remove or disable installed TechDocs add-ons from your Red Hat Developer Hub instance by using the Operator or the Helm chart.
Administrators can remove installed TechDocs add-ons by using either the Operator or Helm chart, depending on the method used to install the add-on. If you used the Operator to install the add-on, remove it from the ConfigMap. If you used the Helm chart to install the add-on, remove it from the Helm chart.
If you want to disable a plugin instead of removing it from your Red Hat Developer Hub instance, you can disable the plugin that you are using to import the TechDocs add-on. Since the disabled status is controlled at the plugin level, disabling the plugin disables all of the TechDocs add-ons in the specified plugin package.
8.6.10.3.2. Remove an external TechDocs add-on from your ConfigMap
Disable or permanently remove an external TechDocs add-on from your Red Hat Developer Hub ConfigMap when you no longer need it.
The disabled status is controlled at the plugin level, therefore, disabling the plugin disables all of the TechDocs add-ons in the disabled plugin package.
Procedure
- From the Developer perspective in the OpenShift Container Platform web console, click ConfigMaps.
- From the ConfigMaps page, click the ConfigMap that contains the TechDocs add-on that you want to remove.
- Select the YAML view option in the Configure via field.
In the
pluginssection of the ConfigMap, do one of the following actions based on whether you want to disable or remove a TechDocs add-on:To temporarily disable all of the TechDocs add-ons in a particular plugin package, change the value of the
disabledfield totrue. For example: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-techdocs-module-addons-contrib disabled: true pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssue - importName: <external_techdocs_add-on>where:
- <external_techdocs_add-on>
-
Specifies the external TechDocs add-on that you want to remove, for example,
TextSize.
To remove one or more TechDocs add-ons from your Red Hat Developer Hub instance, delete
importName: <external_techdocs_add-on>for each external TechDocs add-on that you want to remove from thetechdocsAddonssection of your ConfigMap. For example: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-techdocs-module-addons-contrib disabled: false pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssue - importName: <external_techdocs_add-on>where:
- <external_techdocs_add-on>
-
Specifies the external TechDocs add-on that you want to remove, for example,
TextSize.
- Click Save.
- In the web console navigation menu, click Topology and wait for the Red Hat Developer Hub pod to start.
- Click the Open URL icon to start using the Red Hat Developer Hub platform with the new configuration changes.
8.6.10.3.3. Remove an external TechDocs add-on from your Helm chart
Disable or permanently remove an external TechDocs add-on from your Red Hat Developer Hub Helm chart when you no longer need it.
The disabled status is controlled at the plugin level, therefore, disabling the plugin disables all of the TechDocs add-ons in the disabled plugin package.
Procedure
In the
pluginssection of the Helm chart, do one of the following actions based on whether you want to disable or remove a TechDocs add-on:To temporarily disable all of the TechDocs add-ons in a particular plugin package, change the value of the
disabledfield totrue. For example:global: dynamic: plugins: - package: ./dynamic-plugins/dist/backstage-plugin-techdocs-module-addons-contrib disabled: true pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssue - importName: <external_techdocs_add-on>where:
- <external_techdocs_add-on>
-
Specifies the external TechDocs add-on that you want to remove, for example,
TextSize.
To remove one or more TechDocs add-ons from your Red Hat Developer Hub instance, delete
importName: <external_techdocs_add-on>for each external TechDocs add-on that you want to remove from thetechdocsAddonssection of your Helm chart. For example:global: dynamic: plugins: - package: ./dynamic-plugins/dist/backstage-plugin-techdocs-module-addons-contrib disabled: false pluginConfig: dynamicPlugins: frontend: backstage.plugin-techdocs-module-addons-contrib: techdocsAddons: - importName: ReportIssue - importName: <external_techdocs_add-on>where:
- <external_techdocs_add-on>
-
Specifies the external TechDocs add-on that you want to remove, for example,
TextSize.
8.6.10.4. Use enabled add-ons
8.6.10.4.1. Use enabled add-ons
After an administrator installs a TechDocs add-on in your Red Hat Developer Hub instance, you can use it to extend the functionality of the TechDocs plugin and enhance your documentation experience.
8.6.10.4.2. Use the ReportIssue TechDocs add-on
If you find an error in your organization’s TechDocs documentation, you can use the ReportIssue add-on to open a new GitHub or GitLab issue directly from the documentation. ReportIssue automatically imports the text that you highlight in the document into a new issue template in your repository.
Prerequisites
-
The
ReportIssueadd-on is installed and enabled in your TechDocs plugin. - You have permissions to create issues in the repository where documentation issues are reported.
Procedure
- In your TechDocs documentation, highlight the text that you want to report an issue for.
-
Click the text in the
ReportIssuebox, for example, Open new GitHub issue. From the new issue page in your repository, use the template to create the issue that you want to report.
NoteThe default issue title is Documentation feedback: <highlighted_text>, where <highlighted_text> is the text that you highlighted in your TechDocs documentation.
In the issue description, <highlighted_text> is the default value for the The highlighted text field.
Verification
- The issue that you created is listed on the issues page in your repository.
8.6.10.4.3. Use the TextSize TechDocs add-on
You can use the TextSize add-on to change the size of the text on either the TechDocs Reader page or an Entity page.
Prerequisites
-
The
TextSizeadd-on is installed and enabled in your TechDocs plugin.
Procedure
- In your TechDocs header, click the Settings icon.
Use the sliding scale to adjust the size of your documentation text.
Note- The default text size is 100%
- The minimize text size is 90%
- The maximum text size is 150%
8.6.10.4.4. Use the LightBox TechDocs add-on
Use the LightBox add-on to view enlarged images in a lightbox overlay window and navigate between images on a single documentation page.
Prerequisites
-
The
LightBoxadd-on is installed and enabled in your TechDocs plugin.
Procedure
- In your TechDocs documentation, click the image that you want to view in a lightbox.
- In the lightbox, you can do any of the following actions:
- Click the image or scroll to zoom in or zoom out.
- Click the arrow to navigate between images.
8.6.11. TechDocs add-ons
TechDocs add-ons are dynamic plugins that extend the functionality of the built-in TechDocs plugin. For example, you can use add-ons to report documentation issues, change text size, or view images in overlay in either the TechDocs Reader page or an Entity page.
The following table describes the TechDocs add-ons that are available for Red Hat Developer Hub 1.10:
| TechDocs Add-on | Package/Plugin | Description | Type |
|---|---|---|---|
|
|
|
Select a portion of text on a TechDocs page and open an issue against the repository that contains the documentation. The issue template is automatically populated with the selected text. |
Preinstalled |
|
|
|
Customize text size on documentation pages by increasing or decreasing the font size with a slider or buttons. The default value for font size is 100% and this setting is kept in the browser’s local storage whenever it is changed. |
External |
|
|
|
Open images in a light-box on documentation pages, to navigate to multiple images on a single page. The image size of the light-box image is the same as the image size on the document page. Clicking the zoom icon increases the image size to fit the screen. |
External |
The backstage-plugin-techdocs-module-addons-contrib plugin package exports both preinstalled and external add-ons supported by Red Hat to the TechDocs plugin. This plugin package is preinstalled on Red Hat Developer Hub and is enabled by default. If the plugin package is disabled, all of the TechDocs add-ons exported by the package as also disabled.
8.6.12. Create a TechDocs add-on
If your organization has documentation needs that are not met by the functions of existing TechDocs add-ons, developers can create a new add-on for your TechDocs plugin.
A TechDocs add-on is a React component that is imported from a front-end plugin. If you do not have an existing plugin that you can use to export your TechDocs add-on, you can create a new plugin by using backstage-cli to generate a default front-end plugin structure that you can customize.
The folder structure of a new plugin that can be used to import TechDocs add-ons into the TechDocs plugin looks similar to the following example:
<new_plugin_for_techdocs_add-on>/ dev/ index.ts src/ components/ <new_techdocs_add-on_component>/ <new_techdocs_add-on_component>.test.tsx <new_techdocs_add-on_component>.tsx index.ts <new_techdocs_add-on_fetch-component>/ <new_techdocs_add-on_fetch-component>.test.tsx <new_techdocs_add-on_fetch-component>.tsx index.ts index.ts plugin.test.ts plugin.ts routes.ts setupTests.ts .eslintrc.js package.json README.md
Prerequisites
-
The
yarnpackage manager is installed. - Docker v3.2.0 or later or Podman v3.2.0 or later is installed and running.
Procedure
- In the terminal, navigate to the root folder of the repository where you want to create your new plugin.
To create a new front-end plugin, run the following command:
$ yarn new
Example output:
? What do you want to create? plugin - A new frontend plugin ? Enter the ID of the plugin [required]
In the terminal prompt, type a name for the new plugin. For example:
? Enter the ID of the plugin [required] <new_plugin_for_techdocs_add-on>Example output:
Successfully created plugin
Upon completion of this action, a sub-directory with the same name that you gave to your plugin is automatically generated inside the
pluginsdirectory. The directory contains all of the files that you need to configure to create your new plugin.In the terminal, navigate to your new plugin directory. For example:
$ cd plugins/<new_techdocs_add-on_directory>Add the`@backstage/plugin-techdocs-react` package to get frontend utilities for TechDocs add-ons. For example:
$ yarn add @backstage/plugin-techdocs-react
-
In the directory containing the components of your custom TechDocs add-on, delete any default files or file components that are not required for your add-on, such as the
routes.tsfile or components of theindex.tsxandplugins.tsfiles. In the
plugins.tsfile, add the following code:$ import { createPlugin } from '@backstage/core-plugin-api'; $ import { createTechDocsAddonExtension } from '@backstage/plugin-techdocs-react'; $ export const <new_plugin_for_techdocs_add-on> = createPlugin({ id: '<new_techdocs_add-on>', }); /* * * @public */ $ export const <new_techdocs_add-on> = <new_plugin_for_techdocs_add-on>.provide( createTechDocsAddonExtension<_<new_techdocs_addon_props>_>({ name: '<new_techdocs_add-on>', location: TechDocsAddonLocations.Content, component: <new_techdocs_add-on_component>, }), );where
- <new_plugin_for_techdocs_add-on>
- Specifies the new plugin that you use to import the TechDocs add-on to your Red Hat Developer Hub instance.
- <new_techdocs_add-on>
- Specifies the custom TechDocs add-on that you want to create.
- <new_techdocs_addon_props> (Optional)
-
Specifies the
propsfor your new TechDocs add-on, as specified in your<new_techdocs_add-on>.tsxfile, if applicable. - <new_techdocs_add-on_component>
-
Specifies the React component for the custom TechDocs add-on that you want to create. You will create this component in a
.tsxfile in a later step.
In the
index.tsfile, export the custom TechDocs add-on that you want to create by adding the following code:$ export { <new_plugin_for_techdocs_add-on>, <new_techdocs_add-on> } from './plugin';-
Create a new
<new_techdocs_add-on>.tsxfile and add the code for your new TechDocs add-on component. Create a new
index.tsxfile and use it to export your new TechDocs add-on component by adding the following code:$ export { <new_techdocs_add-on>, type <new_techdocs_addon_props>} from './<new_techdocs_add-on_directory>'where
- <new_techdocs_addon_props> (Optional)
-
Specifies the
propsfor your new TechDocs add-on, as specified in your<new_techdocs_add-on>.tsxfile, if applicable.
-
In the
plugins.tsfile, import your new TechDocs add-on component. - Install and configure your new TechDocs add-on by following the steps in Install and configure a TechDocs add-on
Verification
- Restart the RHDH application and verify that the plugin is successfully activated and configured.
- Verify the application logs for confirmation and ensure the plugin is functioning as expected.
Chapter 9. Configure
9.1. Configure
Configure Red Hat Developer Hub to meet your infrastructure requirements, customize the user interface to reflect your organizational branding, and set up language localization for global accessibility.
9.2. Configure core parameters to meet infrastructure requirements
9.2.1. Configure core parameters to meet infrastructure requirements
Configure the core parameters of your Developer Hub deployment, including default configurations, custom config maps and secrets, routes, TLS connections, and corporate proxy settings.
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 configuration files overview
Overview of the configuration files and Kubernetes resources used to manage Red Hat Developer Hub instances across different deployment methods.
Developer Hub configuration files fall into two categories based on how they are consumed:
- Cluster-provisioned files
- Provisioned as Kubernetes resources, such as config maps or secrets, on the target cluster, typically by platform engineers. These files control the runtime behavior and deployment of your RHDH instance. While the source files can be stored in a Git repository, they must be applied to the cluster to take effect.
- Application-consumed files
- Authored by developers and committed to source repositories. RHDH reads these files directly from Git at runtime to populate the software catalog, execute templates, and build documentation.
9.2.2.2.1. Cluster-provisioned files
The following table lists configuration files that platform engineers create and provision as Kubernetes resources on the target cluster.
| File | Purpose | Format | Operator provisioning | Helm chart provisioning |
|---|---|---|---|---|
|
|
Main application configuration, including URLs, auth, catalog, database, plugin settings. |
YAML |
Config map referenced in the |
Inline through |
|
Secrets, such as, |
Authentication credentials, backend secret, database passwords, and other sensitive values. |
Kubernetes secret |
Secret referenced in the |
Referenced through |
|
|
Enable, disable, and configure dynamic plugins. |
YAML |
Config map referenced in the |
Inline through |
|
|
RBAC permission policies and role assignments (Casbin format). |
CSV |
Config map mounted as file, path configured in |
Same. |
|
|
RBAC conditional policies with criteria-based filtering. |
YAML |
Config map mounted as file, path configured in |
Same. |
|
|
Operator-side deployment configuration that references config files, routes, database, replicas. |
YAML Kubernetes custom resource |
Applied directly as a |
N/A |
|
Helm |
Helm-side deployment configuration, including image, replicas, resources, routes. |
YAML |
N/A |
Passed by using |
9.2.2.2.2. Application-consumed files
The following table lists configuration files that developers author and store in Git repositories. RHDH reads these files directly from Git at runtime.
| File | Purpose | Format | Stored in | Consumed by |
|---|---|---|---|---|
|
|
Entity descriptor that defines components, APIs, systems, and their metadata and annotations. |
YAML |
Root of a source repository. |
Software Catalog through catalog locations or discovery providers. |
|
|
Software template definition with scaffolding steps for creating new components. |
YAML |
Template repository. |
Software Templates (registered through |
|
|
TechDocs configuration that controls how documentation is built from Markdown. |
YAML |
Alongside source repository docs. |
TechDocs plugin. |
9.2.2.3. Application configuration file
The app-config.yaml file is the main Developer Hub configuration file. It controls application behavior including URLs, authentication, catalog sources, database connections, and plugin settings.
The following are key sections in app-config.yaml:
app- Frontend settings such as the application title and base URL.
backend- Backend settings including the base URL, CORS origin, database connection, authentication, and cache.
auth- Authentication provider configuration.
catalog- Software Catalog locations and entity providers.
techdocs- TechDocs builder and storage configuration.
proxy- Proxy endpoints for external services.
permission- RBAC permission framework configuration.
The app-config.yaml file supports ${VAR_NAME} syntax that resolves at runtime from environment variables. You can inject environment variables through Kubernetes secrets or config maps, which allows you to keep sensitive values such as credentials and tokens out of your configuration files.
You can provision the app-config.yaml file by using either the Operator or the Helm chart:
-
With the Operator: on OpenShift Container Platform, the Operator might automatically set
app.baseUrl,backend.baseUrl, andbackend.cors.originfrom the route in the default application configuration. Create a config map containing yourapp-config.yamland reference it in theBackstagecustom resource. -
With the Helm chart: set the base URL fields manually. You can inline your configuration in the Helm chart values at
upstream.backstage.appConfig, or reference external config maps throughupstream.backstage.extraAppConfig.
9.2.2.4. Backstage custom resource
When you use the Red Hat Developer Hub Operator, the Backstage custom resource is the central deployment configuration. It defines how the Operator creates and manages the Developer Hub instance, and references the config maps and secrets that contain your configuration files.
The following fields control key aspects of the deployment:
spec.application.appConfig.configMaps-
References config maps containing your
app-config.yamlfiles. spec.application.dynamicPluginsConfigMapName-
References the config map containing the
dynamic-plugins.yamlfile. spec.application.extraFiles- Mounts additional config maps, secrets, or PVCs as files in the Developer Hub container.
spec.application.extraEnvs- Injects environment variables from config maps, secrets, or inline values.
spec.application.route- Controls route or ingress configuration.
spec.database- Controls whether the built-in PostgreSQL database is enabled or disabled.
spec.deployment.patch- Applies a strategic merge patch to the Deployment resource for advanced customization.
9.2.2.5. Helm chart values file
When you deploy Developer Hub by using the Helm chart, the values.yaml file is the central deployment configuration. It controls how the Helm chart creates Kubernetes resources and can embed application configuration inline.
The following value paths control key aspects of the deployment:
upstream.backstage.appConfig-
Generates a config map with your application configuration. The Helm chart renders these values into an
app-config.yamlconfig map automatically. upstream.backstage.extraAppConfig-
References external config maps containing additional
app-config.yamlfiles. global.dynamic.plugins- Configures the dynamic plugins to enable, disable, or customize.
Use Helm values for deployment-level concerns, such as images, replicas, resources, and routes. Use app-config.yaml for application behavior, such as authentication, catalogs, and plugins.
Additional resources
9.2.2.6. Dynamic plugins configuration file
The dynamic-plugins.yaml file controls which dynamic plugins are enabled in your Developer Hub instance. It defines a list of plugins to install, disable, or configure.
The file contains the following two main sections:
includes-
References a base configuration file (
dynamic-plugins.default.yaml) that is included with Developer Hub. This file contains the default plugin configuration. plugins-
A list of plugin entries that override or extend the base configuration. Each entry specifies a
package(the plugin path), adisabledfield (boolean), and an optionalpluginConfigsection with plugin-specific YAML that is merged into the application configuration.
You can provision the dynamic-plugins.yaml file in different ways depending on your deployment method:
- With the Operator
-
Create a config map containing the
dynamic-plugins.yamldata and reference it in theBackstagecustom resource by usingspec.application.dynamicPluginsConfigMapName. - With the Helm chart
-
Configure plugins inline by using the
global.dynamic.pluginsHelm values.
Additional resources
9.2.2.7. Configuration precedence
When multiple configuration sources are available, Developer Hub merges them following specific precedence rules. Understanding these rules helps you predict how your configuration files interact.
Review these configuration precedence behaviors:
- Application configuration layering
-
When you provide multiple
app-config.yamlfiles (for example, through multiple config maps), Developer Hub deep-merges them. Later files override earlier files for the same keys. For object values, the merge is recursive. For array values, the later array replaces the earlier array entirely. - Dynamic plugins merge behavior
-
The
pluginslist from your configuration merges with thepluginslist from theincludesfile. If both lists contain an entry for the same plugin package, the fields in your configuration override the fields in theincludesfile. - Environment variable resolution
-
References using the
${VAR_NAME}syntax in any YAML configuration file resolve at runtime from environment variables. If a referenced environment variable is not set, Developer Hub fails to start. - Operator flavor merging
- When you enable multiple pre-configured settings (for example, Orchestrator and Lightspeed), the Operator merges their configurations automatically. Settings from both configurations merge without manual intervention.
9.2.2.8. Catalog entity descriptor file
The catalog-info.yaml file is a YAML descriptor that defines catalog entities such as components, APIs, systems, and resources. Developers author this file and commit it to their source repository.
The Software Catalog consumes catalog-info.yaml files through catalog.locations entries in app-config.yaml or through discovery providers (for example, GitHub or GitLab discovery).
Key annotations in catalog-info.yaml control how plugins interact with the entity (for example, backstage.io/techdocs-ref for TechDocs, argocd/app-name for Argo CD).
Additional resources
9.2.2.9. Software template definition file
The template.yaml file defines a software template that scaffolds new components, repositories, or infrastructure. Developers author this file and store it in a template repository.
Software templates are registered in Developer Hub by adding the template.yaml URL to the catalog.locations section of app-config.yaml.
A template defines input parameters, scaffolding steps, and output actions such as creating a repository or registering a catalog entity.
Additional resources
9.2.2.10. TechDocs configuration file
The mkdocs.yml file configures how TechDocs builds documentation from Markdown source files. Developers store this file alongside the docs/ directory in their component repository.
The mkdocs.yml file controls the documentation site structure, navigation, theme, and MkDocs plugins.
The TechDocs plugin in Developer Hub reads this file when building or serving documentation for a catalog entity.
Additional resources
9.2.2.11. Dynamic plugins cache
The dynamic plugins cache reduces platform boot time by storing already-installed plugins and skipping redundant downloads when the configuration does not change.
When you enable dynamic plugins cache:
-
The system calculates a checksum of each plugin’s YAML configuration (excluding
pluginConfig). -
The system stores the checksum in a file named
dynamic-plugin-config.hashwithin the plugin’s directory. - During boot, if a plugin’s package reference matches the earlier installation and the checksum does not change, the system skips the download.
- The system automatically removes plugins that you disabled since the earlier boot.
To enable the dynamic plugins cache in RHDH, the plugins directory dynamic-plugins-root must be a persistent volume.
9.2.2.12. Default configurations
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 Name | Resource Group/Version/Kind (GVK) | Resource Name | Description |
|---|---|---|---|
|
|
|
|
(Mandatory) The main Backstage application deployment. |
|
|
|
|
(Mandatory) The Backstage application service. |
|
|
|
|
The PostgreSQL database stateful set. Needed if |
|
|
|
|
The PostgreSQL database service. Needed if |
|
|
|
|
The PostgreSQL database credentials secret. Needed if |
|
|
|
|
The OpenShift Route to expose Backstage externally. (Optional) Applied to OpenShift only. |
|
|
|
|
(Optional) Specifies one or more Backstage |
|
|
|
|
(Optional) Specifies additional ConfigMaps to mount as files into the Backstage Pod. |
|
|
|
|
(Optional) Specifies additional ConfigMaps to expose as environment variables in the Backstage Pod. |
|
|
|
|
(Optional) Specifies additional Secrets to mount as files into the Backstage Pod. |
|
|
|
|
(Optional) Specifies additional Secrets to expose as environment variables in the Backstage Pod. |
|
|
|
|
(Optional) Specifies the dynamic plugins that the Operator installs into the Backstage instance. |
|
|
list of |
|
(Optional) The Persistent Volume Claim for PostgreSQL database. |
{cr-name} is the name of the Backstage Custom Resource, for example 'my-rhdh-instance' in the above example.
9.2.2.13. Automated Operator features
Use the Operator to automate key configuration processes for your Backstage application.
9.2.2.13.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.13.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.13.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.enabledfield in your Custom Resource (CR) tofalse, the Operator makes no changes. -
If you define
spec.application.route.hostin the Backstage CR, the Operator sets the base URLs tohttps://<spec.application.route.host>. -
If you specify the
spec.application.route.subdomainin the Backstage CR, the Operator sets the base URLs tohttps://<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://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
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.14. Time syntax
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 |
|
No |
|
Duration objects |
A structured object specifying time units. Matches the |
timeout:
minutes: 30
|
Yes |
|
ISO 8601 duration strings |
Standard ISO 8601 duration strings. |
|
Yes |
|
Format |
Description |
Example |
|
Cron |
An object containing a |
frequency:
cron: '*/30 * * * *'
|
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.2.15. Pre-configured settings for common use cases
To choose the appropriate configuration for your use case, review the available predefined settings, their infrastructure prerequisites, and minimal Custom Resource examples.
Red Hat Developer Hub Operator 1.10.0 and later includes pre-configured settings for common use cases. Each configuration automatically applies required plugins, dependencies, and app-config settings.
If you reference a custom dynamic-plugins config map using spec.application.dynamicPluginsConfigMapName, custom plugin declarations override matching plugin declarations from spec.flavours based on package name. When you enable a spec.flavours configuration, you can use custom config map entries to customize the plugin settings. When you disable a spec.flavours configuration, the Operator excludes its plugins from the default configuration. Therefore, you must remove or disable those plugins in your custom dynamic-plugins config map, otherwise RHDH still loads them.
| Name | Purpose | Infrastructure prerequisites | Default status |
|---|---|---|---|
|
|
Workflow automation for CI/CD pipelines |
OpenShift Serverless Operator, Knative Serving, Knative Eventing, OpenShift Serverless Logic Operator, PostgreSQL database, optional AMQ Streams |
Disabled by default - enable explicitly |
|
|
AI chat assistance for developers |
External LLM provider (OpenAI-compatible API) |
Enabled by default - disable to turn off |
9.2.2.15.1. Orchestrator
Enable workflow automation with automatic plugin configuration.
Automatically configured components:
-
Orchestrator front-end plugin (
red-hat-developer-hub-backstage-plugin-orchestrator) -
Orchestrator backend plugin (
red-hat-developer-hub-backstage-plugin-orchestrator-backend) -
Orchestrator backend module for Scaffolder (
red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator) -
Orchestrator form widgets plugin (
red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets) -
SonataFlowOperator integration - Data Index service
- Job service
Minimal CR example:
apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
name: developer-hub-orchestrator
spec:
flavours:
- name: orchestrator
enabled: trueThis example uses the default local PostgreSQL database. For production deployments, Red Hat recommends using an external PostgreSQL database. For configuration details, see Configure external PostgreSQL databases.
Prerequisites:
- OpenShift Serverless Operator, Knative Serving, Knative Eventing, and OpenShift Serverless Logic Operator
- PostgreSQL database (external database recommended for production)
Optional: AMQ Streams (Kafka) for event-driven workflows
For detailed steps, see Deploy Red Hat Developer Hub for workflow automation.
9.2.2.15.2. Developer Lightspeed for RHDH
Developer Lightspeed for RHDH is enabled by default in Red Hat Developer Hub 1.10.0 and later. Connect your LLM provider to use AI chat assistance.
Automatically configured components:
- Developer Lightspeed for RHDH front-end plugin
- Developer Lightspeed for RHDH backend plugin
- Lightspeed Core Service sidecar
Minimal CR example:
apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
name: developer-hub
spec:
application:
extraEnvs:
secrets:
- name: lightspeed-secrets
containers:
- lightspeed-core
Developer Lightspeed for RHDH is enabled by default. You do not need to set spec.flavours to enable AI assistance. To disable, set spec.flavours: [{name: lightspeed, enabled: false}].
Prerequisites:
- External LLM provider endpoint (OpenAI, Azure OpenAI, or compatible API)
LLM API credentials
For complete configuration details, provider-specific guidance, and troubleshooting, see Install and configure Red Hat Developer Lightspeed for Red Hat Developer Hub.
9.2.2.15.3. Multiple pre-configured settings
Enable both Orchestrator and Developer Lightspeed for RHDH in a single deployment:
apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
name: developer-hub-full
spec:
flavours:
- name: orchestrator
enabled: true
application:
extraEnvs:
secrets:
- name: lightspeed-secrets
containers:
- lightspeed-coreDeveloper Lightspeed for RHDH is enabled by default, so you only need to explicitly enable Orchestrator. Settings from both configurations merge automatically. For production deployments with external PostgreSQL database, add the database configuration as shown in Configure external PostgreSQL databases.
You must meet prerequisites for both: OpenShift Serverless components for Orchestrator and external LLM provider for Developer Lightspeed for RHDH.
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 configuration
Provision custom config maps and secrets on Red Hat OpenShift Container Platform (RHOCP) to configure Red Hat Developer Hub before running the application.
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
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.txtfile, with one secret per line inKEY=valueform.Author your custom
app-config.yamlfile. This is the main Developer Hub configuration file. You need a customapp-config.yamlfile to avoid the Developer Hub installer to revert user edits during upgrades. When your customapp-config.yamlfile 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.yamlfile 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 arebaseUrlin theappandbackendsections, andoriginin thebackend.corssubsection:Configuring the
baseUrlinapp-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:
Author your custom
dynamic-plugins.yamlfile 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.yamlincludes: - 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: falseProvision your custom configuration files to your OpenShift Container Platform cluster.
Create the <my-rhdh-project> project aimed at containing your Developer Hub instance.
$ oc create namespace my-rhdh-project
Create config maps for your
app-config.yamlanddynamic-plugins.yamlfiles 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.
Provision your
secrets.txtfile to themy-rhdh-secretssecret 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. Deploy a custom configuration using an Operator
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
Author your Backstage CR in a
my-rhdh-custom-resource.yamlfile to use your custom config maps and secrets.Minimal
my-rhdh-custom-resource.yamlcustom 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: truemy-rhdh-custom-resource.yamlcustom 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-configconfig map:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-configMount files in the
my-rhdh-app-configandrbac-policiesconfig maps:spec: application: appConfig: mountPath: /opt/app-root/src configMaps: - name: my-rhdh-app-config - name: rbac-policiesspec.application.extraEnvs.envsOptionally, enter your additional environment variables that are not secrets, such as your proxy environment variables.
Inject your
HTTP_PROXY,HTTPS_PROXYandNO_PROXYenvironment 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.secretsEnter 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-secretssecrets:spec: application: extraEnvs: secrets: - name: <my_product_secrets> - name: my-rhdh-database-secretsNote<my_product_secrets>is your preferred Developer Hub secret name, specifying the identifier for your secret configuration within Developer Hub.spec.application.extraFiles.secretsEnter your certificates files secret name and files list.
Mount the
postgres-crt.pem,postgres-ca.pem, andpostgres-key.keyfiles contained in themy-rhdh-database-certificates-secretssecret:spec: application: extraFiles: mountPath: /opt/app-root/src secrets: - name: my-rhdh-database-certificates-secrets key: postgres-crt.pem, postgres-ca.pem, postgres-key.keyspec.database.enableLocalDbEnable or disable the local PostgreSQL database.
Disable the local PostgreSQL database generation to use an external postgreSQL database:
spec: database: enableLocalDb: falseOn a development environment, use the local PostgreSQL database:
spec: database: enableLocalDb: truespec.deployment- Optionally, enter your deployment configuration.
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. Deploy a custom configuration using Helm Chart
Use the Red Hat Developer Hub Helm chart to deploy Developer Hub with a custom application configuration file on OpenShift Container Platform.
Prerequisites
- By using the OpenShift Container Platform web console, you have access with developer permissions, to an OpenShift Container Platform project named <my-rhdh-project>, aimed at containing your Developer Hub instance.
-
You have uploaded your custom configuration files and secrets in your
<my-rhdh-project>project.
Procedure
Configure Helm to use your custom configuration files in Developer Hub.
- Go to the Helm tab to see the list of Helm releases.
- Click the overflow menu on the Helm release that you want to use and select Upgrade.
- Use the YAML view to edit the Helm configuration.
Set the value of the
upstream.backstage.extraAppConfig.configMapRefandupstream.backstage.extraAppConfig.filenameparameters as follows:upstream: backstage: extraAppConfig: - configMapRef: my-rhdh-app-config filename: app-config.yaml- Click Upgrade.
Next steps
- Install Developer Hub by using Helm.
9.2.4. Customize your Red Hat Developer Hub base URL
Change the default Red Hat Developer Hub base URL to match your organization’s DNS configuration.
Prerequisites
- You know your required Developer Hub external URL: https://<my_developer_hub_domain>, and have configured DNS to point to your Red Hat OpenShift Container Platform cluster.
- Custom Developer Hub configuration.
Procedure
In your custom
app-config.yamlfile, enter your Developer Hub external URL, such as https://<my_developer_hub_domain>.app-config.yamlexcerptapp: baseUrl: https://<my_developer_hub_domain> backend: baseUrl: https://<my_developer_hub_domain> cors: origin: https://<my_developer_hub_domain>
9.2.5. Configure backend secrets to secure service-to-service communication
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, andpostgres-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
Backstagecustom resource by using thespec.application.extraEnvs.secretsfield to inject secrets as environment variables, or thespec.application.extraFiles.secretsfield to mount secrets as files, such as, TLS certificates. -
With the Helm chart: Reference secrets by using the
upstream.backstage.extraEnvVarsSecretsorupstream.backstage.extraEnvVarsfield with asecretKeyRef. You can also mount secrets as files by using both theupstream.backstage.extraVolumesandupstream.backstage.extraVolumeMountsvalues.
9.2.6. Customize Red Hat Developer Hub backend secret
The default Red Hat Developer Hub configuration defines the Developer Hub backend secret for service to service authentication.
You can define your custom Developer Hub backend secret.
Prerequisites
Procedure
To define the Developer Hub backend secret, add to your custom
<my_product_secrets>.txtfile theBACKEND_SECRETenvironment variable with a base64 encoded string. Use a unique value for each Developer Hub instance.$ echo >
<my_product_secrets>.txt"BACKEND_SECRET=$(node -p 'require("crypto").randomBytes(24).toString("base64")')"<my_product_secrets>.txtexampleBACKEND_SECRET=3E2/rIPuZNFCtYHoxVP8wjriffnN1q/z
Add your backend secret to your custom
app-config.yamlfile.app-config.yamlexcerpt defining the backend secretbackend: auth: externalAccess: - type: legacy options: subject: legacy-default-config secret: "${BACKEND_SECRET}"
9.2.7. Inject extra files and variables to secure external service connections
Inject extra files and environment variables into Backstage containers by mounting ConfigMaps and Secrets by using the mountPath field.
-
If you do not specify
keyandmountPath: The system mounts each key or value as afilenameor content with asubPath. -
If you specify
keywith or withoutmountPath: The system mounts the specified key or value with asubPath. -
If you specify only
mountPath: The system mounts a directory containing all the keys or values without asubPath. If you do not specify the
containersfield: The volume mounts only to thebackstage-backendcontainer. By default, files mount only to thebackstage-backendcontainer. You can also specify other targets, including a list of containers by name (such asdynamic-plugin-installorselectcustomsidecars) 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.
-
OpenShift Container Platform does not automatically update a volume mounted with
Procedure
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-pluginswhere:
spec.application.extraFiles.mountPath-
Specifies the default base mount path for files if you do not set a specific
mountPathfor 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.containersTargets only the listed container for the static environment variable injection.
NoteThe following explicit options are supported:
-
No or an empty field: Mounts only to the
backstage-backendcontainer. -
*(asterisk) as the first and only array element: Mounts to all containers. -
Explicit container names, for example,
install-dynamic-plugins: Mounts only to the listed containers.
-
No or an empty field: Mounts only to the
Verification
Verify the files mount with the following correct paths and container targets:
| Resource | Target type | Path(s) or name(s) | Container(s) |
|---|---|---|---|
|
ConfigMap ( |
File |
|
|
|
ConfigMap ( |
File |
|
All |
|
ConfigMap ( |
Directory |
|
|
|
Secret ( |
File |
|
|
|
Secret ( |
Directory |
|
|
|
PVC ( |
Directory |
|
|
|
ConfigMap ( |
Environment variable |
|
All |
|
Secret ( |
Environment variable |
|
|
|
Custom Resource Definition (CRD) ( |
Environment variable |
|
|
9.2.8. Configure mount paths to safely attach default secrets and storage
Configure custom mount paths for Secrets and PVCs by adding the rhdh.redhat.com/mount-path annotation to your resource.
Procedure
To specify a PVC mount path, add the
rhdh.redhat.com/mount-pathannotation 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/annotationWhere:
<my_claim>- The PVC to mount.
rhdh.redhat.com/mount-path-
The mount path for the PVC, in this case the
/mount/path/from/annotationdirectory.
To specify a Secret mount path, add the
rhdh.redhat.com/mount-pathannotation 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.9. Mount secrets to specific containers to isolate sensitive data
Mount secrets and PVCs to specific containers by adding the rhdh.redhat.com/containers annotation to your configuration file.
Procedure
To mount Secrets to all containers, set the
rhdh.redhat.com/containersannotation to*in your configuration file:apiVersion: v1 kind: Secret metadata: name: <my_secret> annotations: rhdh.redhat.com/containers:
*ImportantSet
rhdh.redhat.com/containersto*to mount it to all containers in the deployment.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"NoteThis configuration mounts the
<my_claim>PVC to theinit-dynamic-pluginsandbackstage-backendcontainers.
9.2.10. Patch deployment resources to customize Operator pod specifications
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:labelsAdd 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: truevolumesAdd an additional volume named
my-volumeand mount it under/my/pathin 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-volumeReplace the default
dynamic-plugins-rootvolume with a persistent volume claim (PVC) nameddynamic-plugins-root. Note the$patch: replacedirective, 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-rootcpurequestSet 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: 250mmy-sidecarcontainerAdd a new
my-sidecarsidecar 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.11. Configure TLS connections to encrypt external platform traffic
Configure RHDH with a TLS connection in Kubernetes to ensure secure connections with third-party applications and external databases.
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-idto label components -
backstage.io/kubernetes-namespaceto label namespaces
-
Procedure
Enable the Kubernetes plugins in the
dynamic-plugins-rhdh.yamlfile by settingdisabledtofalse: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 # ...NoteThe
backstage-plugin-kubernetesplugin is currently in Technology Preview. As an alternative, you can use the./dynamic-plugins/dist/backstage-plugin-topology-dynamicplugin, which is Generally Available (GA).Set the Kubernetes cluster details and configure the catalog sync options in the
app-config.yamlconfiguration 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-infocommand to get the base URL. skipTLSVerify-
Set the value of this parameter to
falseto 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_TOKENenvironment variable that you define in your<my_product_secrets>secret. caData-
Pass the CA data by using a
K8S_CONFIG_CA_DATAenvironment variable that you define in your<my_product_secrets>secret.
- Save the configuration changes.
Verification
Run the RHDH application to import your catalog:
$ kubectl -n rhdh-operator get pods -w
- Verify that the pod log shows no errors for your configuration.
- 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.
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.12. Configure the base URL to route frontend and backend traffic
To secure application traffic with your own certificate, configure the Developer Hub route to use a TLS certificate stored in a Kubernetes secret.
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/tlsin the same namespace as your Developer Hub instance, and the certificate is valid for the route host configured in yourBackstagecustom resource, for examplemy-rhdh.apps.example.com.
Procedure
Add the
spec.application.route.tls.externalCertificateSecretNamefield to yourBackstagecustom 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-certApply 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.13. Configure HTTP server timeouts
Adjust HTTP server timeouts to prevent connection drops behind load balancers or when handling long-running API requests.
If your Red Hat Developer Hub (RHDH) instance is deployed behind a load balancer or reverse proxy, you might need to adjust the backend HTTP server timeouts. For example, if the load balancer closes idle connections before the RHDH backend does, clients might experience unexpected disconnects. Similarly, long-running operations such as large catalog imports or slow upstream API calls might require longer request timeouts.
Procedure
In your
app-config.yamlconfiguration file, add or update thebackend.serversection:backend: server: keepAliveTimeout: minutes: 1 headersTimeout: minutes: 2 requestTimeout: minutes: 1 timeout: minutes: 5 maxHeadersCount: 2000 maxRequestsPerSocket: 100Where:
keepAliveTimeout- Maximum time an idle keep-alive connection stays open before the server closes it. Set this higher than your load balancer’s idle timeout to avoid premature disconnects.
headersTimeout-
Maximum time allowed to receive the complete HTTP request headers. Must be greater than
keepAliveTimeout. requestTimeout- Maximum time allowed for the entire HTTP request, including headers and body.
timeout- Socket inactivity timeout. Maximum time a socket can remain idle before being closed.
maxHeadersCount- Maximum number of incoming HTTP headers allowed per request.
maxRequestsPerSocketMaximum number of requests a socket can handle before the connection is closed.
When these settings are not configured, the Node.js defaults apply. Timeout values support multiple formats, including human-readable strings, duration objects, and ISO 8601 duration strings. For more information, see Time syntax in Red Hat Developer Hub.
Verification
- Verify that long-running requests or idle connections behave as expected with the new timeout values.
Additional resources
9.2.14. Configure the dynamic plugins cache
Configure the dynamic plugins cache by setting pull policy and download parameters in the dynamic-plugins.yaml file.
Procedure
To configure the dynamic plugins cache, set the following optional dynamic plugin cache parameters in your
dynamic-plugins.yamlfile:pullPolicy: IfNotPresent(default)- Download the artifact if it is not already present in the dynamic-plugins-root folder, without checking image digests.
pullPolicy: AlwaysCompare the image digest in the remote registry and downloads the artifact if it has changed, even if Developer Hub has already downloaded the plugin before.
When applied to the Node Package Manager (NPM) downloading method, download the remote artifact without a digest check.
Example
dynamic-plugins.yamlfile configuration to download the remote artifact without a digest check:plugins: - disabled: false pullPolicy: Always package: 'oci://quay.io/example-org/example-plugin:v1.0.0'forceDownload: false(default)- Older option to download the artifact if it is not already present in the dynamic-plugins-root folder, without checking image digests.
forceDownload: trueOlder option to force a reinstall of the plugin, bypassing the cache.
NoteThe
pullPolicyoption takes precedence over theforceDownloadoption.The
forceDownloadoption might become deprecated in a future Developer Hub release.
9.2.15. Optimize Operator memory usage for large clusters
In large clusters, the Red Hat Developer Hub Operator can consume substantial memory because the cache loads metadata for all Secrets and ConfigMaps cluster-wide. You can enable cache-level label filtering to restrict caching to only relevant resources.
Enabling cache label filtering is a breaking change. After activation, every Secret and ConfigMap that the Operator manages must carry the rhdh.redhat.com/external-config: "true" label. Any existing Developer Hub instances that reference unlabeled resources stop working until you add the required label to those resources.
Prerequisites
- An OpenShift Container Platform administrator has installed the Red Hat Developer Hub Operator.
- You have identified the secrets and config maps that your Developer Hub instances reference.
Procedure
To enable cache-level label filtering, edit the Operator subscription and add the
ENABLE_CACHE_LABEL_FILTERenvironment variable.spec: config: env: - name: "ENABLE_CACHE_LABEL_FILTER" value: "true"Alternatively, edit the
ClusterServiceVersion(CSV) resource to add the--enable-cache-label-filtercommand-line flag to themanagercontainer:spec: template: spec: containers: - name: manager args: - --enable-cache-label-filterLabel every secret and config map that your Developer Hub instances reference. This includes all resources listed in your
Backstagecustom resource underspec.application.$ oc label secret <secret_name> rhdh.redhat.com/external-config=true -n <namespace> $ oc label configmap <configmap_name> rhdh.redhat.com/external-config=true -n <namespace>
Alternatively, add the label directly in the resource YAML:
metadata: name: <resource_name> labels: rhdh.redhat.com/external-config: "true"
Verification
Verify that the Operator pod restarts and that your Developer Hub instances are running after enabling cache label filtering:
$ oc get pods -n rhdh-operator
9.2.16. Fix 404 error after cached dynamic plugins configuration change
When many Developer Hub replicas share a single dynamic plugins cache PVC, updating configurations with the Operator can trigger temporary 404 errors. This occurs because the replicas might access inconsistent cache states during the update process, before all replicas have synchronized.
The solution is to use an individual cache per pod.
Prerequisites
-
Your API version is
v1alpha5or later.
Procedure
In the
BackstageCustom Resource (CR) file, setspec.deploymentto use the optionalStatefulSetas a resource kind. For example:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: <CR_name> ... spec: deployment: kind: StatefulSet patch: spec: replicas: 2 template: spec: volumes: - $patch: replace name: dynamic-plugins-root persistentVolumeClaim: claimName: dynamic-plugins-root volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: dynamic-plugins-root spec: accessModes: - ReadWriteOnce resources: requests: storage: 1GiNoteUsing
StatefulSetwith a single replica can lead to downtime, while the application deletes the old pod and creates a new pod.-
Wait a few minutes until the Operator reconciles the CR and the
StatefulSetresource is ready. If you are updating an existing CR, remove the earlier
Deploymentresource from the cluster:oc delete deployment -l app.kubernetes.io/instance=<CR_name>NoteThe same requirement applies for changing the resource kind from
StatefulSettoDeployment. You must manually delete the resource created before from the cluster, because the Operator does not automatically remove the legacy resource.
9.2.17. Configure corporate proxy settings to enable external network access
9.2.17.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.17.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.
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_PROXYlist. For example,NO_PROXY="localhost,example.com", orNO_PROXY="localhost example.com", orNO_PROXY="localhost, example.com"would have the same effect. -
If
NO_PROXYhas no entries, configuring theHTTP(S)_PROXYsettings 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.comto1.2.3.4, settingNO_PROXY=1.2.3.4has no effect on requests sent toexample.com. Only requests sent to the IP address1.2.3.4bypass 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:1234would bypass the proxy for requests tohttp(s)://example.com:1234, but not for requests on other ports, such ashttp(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=localhostwould bypass the proxy for requests sent to URLs such ashttp(s)://localhost:7077andhttp(s)://localhost:8888. -
IP Address blocks in CIDR notation will not work. So setting
NO_PROXY=10.11.0.0/16will 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
::1will not work. -
Generally, the proxy is only bypassed if the hostname is an exact match for an entry in the
NO_PROXYlist. 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.
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.17.3. Configure proxy settings 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
- Perform one of the following steps based on your role:
As an administrator, set the proxy information in the Operator’s default ConfigMap file:
-
Search for a ConfigMap file named
backstage-default-configin the default namespacerhdh-operatorand open it. -
Find the
deployment.yamlkey. Set the value of the
HTTP_PROXY,HTTPS_PROXY, andNO_PROXYenvironment variables in theDeploymentspec 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'
-
Search for a ConfigMap file named
As a developer, set the proxy information in your
BackstageCR 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'- Save the configuration changes.
9.2.17.4. Configure proxy settings 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
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'
- 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
Customize the Developer Hub user interface by configuring themes and branding, the global header, quick starts, tech radar, learning paths, sidebar navigation, home page layout, and quick access cards.
9.3.2. Customize your Red Hat Developer Hub title
You can change the default Red Hat Developer Hub display name.
Prerequisites
Procedure
In your custom
app-config.yamlfile, enter your Developer Hub instance display name, such as <Red Hat Developer Hub>.app-config.yamlexcerptapp: title: My custom Red Hat Developer Hub title
9.3.3. Customize Learning Paths to integrate tailored e-learning content
9.3.3.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.3.2. Structured learning paths for developers onboarding
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.3.3. Customize 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
- 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.
Configure the Developer Hub proxy to access the Learning Paths data from the hosted JSON file, by adding the following to the
app-config.yamlfile: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'TipWhen also configuring the home page, due to the use of overlapping
pathRewritesfor both thelearning-pathandhomepagequick access proxies, create thelearning-pathsconfiguration (^api/proxy/developer-hub/learning-paths) before you create thehomepageconfiguration (^/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
Additional resources
9.3.3.4. Customize 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
-
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. Configure the Developer Hub proxy to use your dedicated service to provide the Learning Path data, add the following to the
app-config.yamlfile: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.3.5. Start and complete lessons
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
- In your Red Hat Developer Hub navigation menu, click Learning Paths.
Select the tile for the course you want to begin.
NoteThis action redirects you to the main page of the course in the Red Hat Developers site.
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.
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 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
integrationssection of theapp-config.yamlfile. For example, you have enabled Developer Hub integration with GitHub. -
You have enabled the
./dynamic-plugins/dist/backstage-community-plugin-tech-radarand/dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamicplugins.
Procedure
- 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.
Configure Developer Hub to access the Tech Radar data from the hosted JSON files, by adding the following to the
app-config.yamlfile:techRadar: url: <tech_radar_data_url><tech_radar_data_url>- Enter the Tech Radar data hosted JSON URL.
9.3.6.3. Customize 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
integrationssection of theapp-config.yamlfile. For example, you have enabled Developer Hub integration with GitHub. -
You have enabled the
./dynamic-plugins/dist/backstage-community-plugin-tech-radarand/dynamic-plugins/dist/backstage-community-plugin-tech-radar-backend-dynamicplugins.
Procedure
-
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. Add the dedicated service as an allowed host by adding the following code to the
app-config.yamlfile: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>.
Add the following to the
app-config.yamlfile: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. Configure the default theme mode
You can switch the RHDH interface between light, dark, or auto mode (which matches your system preference).
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
- From the Developer Hub web console, click Settings.
From the Appearance panel, select Light, Dark, or Auto to change the theme mode.

Verification
- The interface immediately updates to reflect the selected theme.
9.3.7.3. Configure the branding logo
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
brandingsection in theapp-config.yamlfile: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.
iconLogoEnter the logo on the collapsed (unpinned) sidebar as a base64 encoded image.
You can format the
BASE64_EMBEDDED_FULL_LOGOenvironment variable as follows:BASE64_EMBEDDED_FULL_LOGO: "data:_<media_type>_;base64,<base64_data>"The following example demonstrates how to customize the
BASE64_EMBEDDED_FULL_LOGOby using thedata:_<media_type>_;base64,<base64_data>format:SVGLOGOBASE64=$(base64 -i logo.svg) BASE64_EMBEDDED_FULL_LOGO="data:image/svg+xml;base64,$SVGLOGOBASE64"
Replace
image/svg+xmlwith the correct media type for your image (for example,image/pngandimage/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
fullLogoWidthfield in thebrandingsection, 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. Define custom color palettes
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.paletteanddark.paletteparameters in thebranding.themesection of theapp-config.yamlfile: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|darkEnter the theme name:
lightordark.palette.primary:main-
Enter the palette main primary color, such as
#fffffforwhite. 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
#FF0000orred. pageTheme:default:backgroundColor-
Enter the default page theme background color, such as
#fffffforwhite.
Additional resources
9.3.7.5. Configure the page theme header
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.themesection of theapp-config.yamlfile: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
lightordark. defaultEnter the default page theme configuration
backgroundColor-
Enter the page header background color, such as
#fffffforwhite. fontColor-
Enter the page header text color, such as
#000000orblack. shape-
Enter the page header pattern, such as
wave,round, ornone.apis::Enter the page id to configure, such asapisorhome.
9.3.7.6. Customize typography
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
typographysection of theapp-config.yamlfile: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 React theme for advanced UI overrides
You can load a custom Developer Hub theme from a dynamic plugin.
Procedure
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.
Configure Developer Hub to load the theme in the UI by using the
themesconfiguration field:dynamicPlugins: frontend: example.my-custom-theme-plugin: themes: - id: light title: Light variant: light icon: someIconReference importName: lightThemeProviderid-
Enter your theme ID, such as
my_theme. Enterdarkto override the default Developer Hub dark theme. Enterlightto 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
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 / mui9.3.7.9. Default Red Hat Developer Hub theme
You can use the default Red Hat Developer Hub theme configurations to make your Developer Hub instance look like a standard Red Hat Developer Hub instance. You can also modify the app-config.yaml file to customize or disable particular parameters.
9.3.7.9.1. Default Red Hat Developer Hub theme color palette
The app-config.yaml file uses the following configurations for the default Red Hat Developer Hub color palette:
app:
branding:
theme:
light:
variant: "rhdh"
mode: "light"
palette:
background:
default: "#F8F8F8"
paper: "#FFFFFF"
banner:
closeButtonColor: "#FFFFFF"
error: "#E22134"
info: "#2E77D0"
link: "#000000"
text: "#FFFFFF"
warning: "#FF9800"
border: "#E6E6E6"
bursts:
backgroundColor:
default: "#7C3699"
fontColor: "#FEFEFE"
gradient:
linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
slackChannelText: "#ddd"
errorBackground: "#FFEBEE"
errorText: "#CA001B"
gold: "#FFD600"
highlight: "#FFFBCC"
infoBackground: "#ebf5ff"
infoText: "#004e8a"
link: "#0A6EBE"
linkHover: "#2196F3"
mode: "light"
navigation:
background: "#222427"
indicator: "#0066CC"
color: "#ffffff"
selectedColor: "#ffffff"
navItem:
hoverBackground: "#3c3f42"
submenu:
background: "#222427"
pinSidebarButton:
background: "#BDBDBD"
icon: "#181818"
primary:
main: "#0066CC"
secondary:
main: "#8476D1"
status:
aborted: "#757575"
error: "#E22134"
ok: "#1DB954"
pending: "#FFED51"
running: "#1F5493"
warning: "#FF9800"
tabbar:
indicator: "#9BF0E1"
textContrast: "#000000"
textSubtle: "#6E6E6E"
textVerySubtle: "#DDD"
warningBackground: "#F59B23"
warningText: "#000000"
text:
primary: "#151515"
secondary: "#757575"
rhdh:
general:
disabledBackground: "#D2D2D2"
disabled: "#6A6E73"
searchBarBorderColor: "#E4E4E4"
formControlBackgroundColor: "#FFF"
mainSectionBackgroundColor: "#FFF"
headerBottomBorderColor: "#C7C7C7"
cardBackgroundColor: "#FFF"
sidebarBackgroundColor: "#212427"
cardBorderColor: "#C7C7C7"
tableTitleColor: "#181818"
tableSubtitleColor: "#616161"
tableColumnTitleColor: "#151515"
tableRowHover: "#F5F5F5"
tableBorderColor: "#E0E0E0"
tableBackgroundColor: "#FFF"
tabsBottomBorderColor: "#D2D2D2"
contrastText: "#FFF"
primary:
main: "#0066CC"
focusVisibleBorder: "#0066CC"
secondary:
main: "#8476D1"
focusVisibleBorder: "#8476D1"
cards:
headerTextColor: "#151515"
headerBackgroundColor: "#FFF"
headerBackgroundImage: "none"
dark:
variant: "rhdh"
mode: "dark"
palette:
background:
default: "#333333"
paper: "#424242"
banner:
closeButtonColor: "#FFFFFF"
error: "#E22134"
info: "#2E77D0"
link: "#000000"
text: "#FFFFFF"
warning: "#FF9800"
border: "#E6E6E6"
bursts:
backgroundColor:
default: "#7C3699"
fontColor: "#FEFEFE"
gradient:
linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
slackChannelText: "#ddd"
errorBackground: "#FFEBEE"
errorText: "#CA001B"
gold: "#FFD600"
highlight: "#FFFBCC"
infoBackground: "#ebf5ff"
infoText: "#004e8a"
link: "#9CC9FF"
linkHover: "#82BAFD"
mode: "dark"
navigation:
background: "#0f1214"
indicator: "#0066CC"
color: "#ffffff"
selectedColor: "#ffffff"
navItem:
hoverBackground: "#3c3f42"
submenu:
background: "#0f1214"
pinSidebarButton:
background: "#BDBDBD"
icon: "#404040"
primary:
main: "#1FA7F8"
secondary:
main: "#B2A3FF"
status:
aborted: "#9E9E9E"
error: "#F84C55"
ok: "#71CF88"
pending: "#FEF071"
running: "#3488E3"
warning: "#FFB84D"
tabbar:
indicator: "#9BF0E1"
textContrast: "#FFFFFF"
textSubtle: "#CCCCCC"
textVerySubtle: "#727272"
warningBackground: "#F59B23"
warningText: "#000000"
rhdh:
general:
disabledBackground: "#444548"
disabled: "#AAABAC"
searchBarBorderColor: "#57585a"
formControlBackgroundColor: "#36373A"
mainSectionBackgroundColor: "#0f1214"
headerBottomBorderColor: "#A3A3A3"
cardBackgroundColor: "#292929"
sidebarBackgroundColor: "#1b1d21"
cardBorderColor: "#A3A3A3"
tableTitleColor: "#E0E0E0"
tableSubtitleColor: "#E0E0E0"
tableColumnTitleColor: "#E0E0E0"
tableRowHover: "#0f1214"
tableBorderColor: "#515151"
tableBackgroundColor: "#1b1d21"
tabsBottomBorderColor: "#444548"
contrastText: "#FFF"
primary:
main: "#1FA7F8"
focusVisibleBorder: "#ADD6FF"
secondary:
main: "#B2A3FF"
focusVisibleBorder: "#D0C7FF"
cards:
headerTextColor: "#FFF"
headerBackgroundColor: "#0f1214"
headerBackgroundImage: "none"
Alternatively, you can use the following variant and mode values in the app-config.yaml file to apply the previous default configuration:
app:
branding:
theme:
light:
variant: "rhdh"
mode: "light"
dark:
variant: "rhdh"
mode: "dark"9.3.7.9.2. Default Red Hat Developer Hub page themes
The default Developer Hub header color is white in light mode and black in dark mode, as shown in the following app-config.yaml file configuration:
app:
branding:
theme:
light:
palette: {}
defaultPageTheme: default
pageTheme:
default:
backgroundColor: "#ffffff"
dark:
palette: {}
defaultPageTheme: default
pageTheme:
default:
backgroundColor: "#0f1214"9.3.7.10. Default Backstage theme
You can use the default Backstage theme configurations to make your Developer Hub instance look like a standard Backstage instance. You can also modify the app-config.yaml file to customize or disable particular parameters.
9.3.7.10.1. Default Backstage theme color palette
The app-config.yaml file uses the following configurations for the default Backstage color palette:
app:
branding:
theme:
light:
variant: "backstage"
mode: "light"
palette:
background:
default: "#F8F8F8"
paper: "#FFFFFF"
banner:
closeButtonColor: "#FFFFFF"
error: "#E22134"
info: "#2E77D0"
link: "#000000"
text: "#FFFFFF"
warning: "#FF9800"
border: "#E6E6E6"
bursts:
backgroundColor:
default: "#7C3699"
fontColor: "#FEFEFE"
gradient:
linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
slackChannelText: "#ddd"
errorBackground: "#FFEBEE"
errorText: "#CA001B"
gold: "#FFD600"
highlight: "#FFFBCC"
infoBackground: "#ebf5ff"
infoText: "#004e8a"
link: "#0A6EBE"
linkHover: "#2196F3"
navigation:
background: "#171717"
color: "#b5b5b5"
indicator: "#9BF0E1"
navItem:
hoverBackground: "#404040"
selectedColor: "#FFF"
submenu:
background: "#404040"
pinSidebarButton:
background: "#BDBDBD"
icon: "#181818"
primary:
main: "#1F5493"
status:
aborted: "#757575"
error: "#E22134"
ok: "#1DB954"
pending: "#FFED51"
running: "#1F5493"
warning: "#FF9800"
tabbar:
indicator: "#9BF0E1"
textContrast: "#000000"
textSubtle: "#6E6E6E"
textVerySubtle: "#DDD"
warningBackground: "#F59B23"
warningText: "#000000"
dark:
variant: "backstage"
mode: "dark"
palette:
background:
default: "#333333"
paper: "#424242"
banner:
closeButtonColor: "#FFFFFF"
error: "#E22134"
info: "#2E77D0"
link: "#000000"
text: "#FFFFFF"
warning: "#FF9800"
border: "#E6E6E6"
bursts:
backgroundColor:
default: "#7C3699"
fontColor: "#FEFEFE"
gradient:
linear: "linear-gradient(-137deg, #4BB8A5 0%, #187656 100%)"
slackChannelText: "#ddd"
errorBackground: "#FFEBEE"
errorText: "#CA001B"
gold: "#FFD600"
highlight: "#FFFBCC"
infoBackground: "#ebf5ff"
infoText: "#004e8a"
link: "#9CC9FF"
linkHover: "#82BAFD"
mode: "dark"
navigation:
background: "#424242"
color: "#b5b5b5"
indicator: "#9BF0E1"
navItem:
hoverBackground: "#404040"
selectedColor: "#FFF"
submenu:
background: "#404040"
pinSidebarButton:
background: "#BDBDBD"
icon: "#404040"
primary:
dark: "#82BAFD"
main: "#9CC9FF"
secondary:
main: "#FF88B2"
status:
aborted: "#9E9E9E"
error: "#F84C55"
ok: "#71CF88"
pending: "#FEF071"
running: "#3488E3"
warning: "#FFB84D"
tabbar:
indicator: "#9BF0E1"
textContrast: "#FFFFFF"
textSubtle: "#CCCCCC"
textVerySubtle: "#727272"
warningBackground: "#F59B23"
warningText: "#000000"
Alternatively, you can use the following variant and mode values in the app-config.yaml file to apply the previous default configuration:
app:
branding:
theme:
light:
variant: "backstage"
mode: "light"
dark:
variant: "backstage"
mode: "dark"9.3.7.10.2. Default Backstage page themes
The default Backstage header color is white in light mode and black in dark mode, as shown in the following app-config.yaml file configuration:
app:
branding:
theme:
light:
palette: {}
defaultPageTheme: default
pageTheme:
default:
backgroundColor: ['#005B4B'] # teal
fontColor: '#ffffff'
shape: wave
documentation:
backgroundColor: ['#C8077A', '#C2297D'] # pinkSea
fontColor: '#ffffff'
shape: wave2
tool:
backgroundColor: ['#8912CA', '#3E00EA'] # purpleSky
fontColor: '#ffffff'
shape: round
service:
backgroundColor: ['#006D8F', '#0049A1'] # marineBlue
fontColor: '#ffffff'
shape: wave
website:
backgroundColor: ['#0027AF', '#270094'] # veryBlue
fontColor: '#ffffff'
shape: wave
library:
backgroundColor: ['#98002B', '#8D1134'] # rubyRed
fontColor: '#ffffff'
shape: wave
other:
backgroundColor: ['#171717', '#383838'] # darkGrey
fontColor: '#ffffff'
shape: wave
app:
backgroundColor: ['#BE2200', '#A41D00'] # toastyOrange
fontColor: '#ffffff'
shape: shapes.wave
apis:
backgroundColor: ['#005B4B'] # teal
fontColor: '#ffffff'
shape: wave2
card:
backgroundColor: ['#4BB8A5', '#187656'] # greens
fontColor: '#ffffff'
shape: wave
dark:
palette: {}
defaultPageTheme: default
pageTheme:
default:
backgroundColor: ['#005B4B'] # teal
fontColor: '#ffffff'
shape: wave
documentation:
backgroundColor: ['#C8077A', '#C2297D'] # pinkSea
fontColor: '#ffffff'
shape: wave2
tool:
backgroundColor: ['#8912CA', '#3E00EA'] # purpleSky
fontColor: '#ffffff'
shape: round
service:
backgroundColor: ['#006D8F', '#0049A1'] # marineBlue
fontColor: '#ffffff'
shape: wave
website:
backgroundColor: ['#0027AF', '#270094'] # veryBlue
fontColor: '#ffffff'
shape: wave
library:
backgroundColor: ['#98002B', '#8D1134'] # rubyRed
fontColor: '#ffffff'
shape: wave
other:
backgroundColor: ['#171717', '#383838'] # darkGrey
fontColor: '#ffffff'
shape: wave
app:
backgroundColor: ['#BE2200', '#A41D00'] # toastyOrange
fontColor: '#ffffff'
shape: shapes.wave
apis:
backgroundColor: ['#005B4B'] # teal
fontColor: '#ffffff'
shape: wave2
card:
backgroundColor: ['#4BB8A5', '#187656'] # greens
fontColor: '#ffffff'
shape: wave9.3.10. Configure Quick access cards to surface frequently used links
9.3.10.1. Configure Quick access cards to surface frequently used links
You can customize the Quick access card on the Red Hat Developer Hub Home page by configuring a proxy in your app-config.yaml file. You can provide data from JSON files hosted on GitHub or GitLab, or from a dedicated service that provides the data in JSON format by using an API.
9.3.10.2. Use hosted JSON files to provide data
You can configure Developer Hub to fetch Quick access card data from JSON files hosted on external servers such as GitHub or GitLab by configuring a proxy endpoint in your Developer Hub configuration.
To display data in the Quick access card from a hosted JSON file, you must configure a proxy endpoint in your configuration file.
Prerequisites
- You have installed Red Hat Developer Hub by using the Operator or a Helm chart. For more information, see Installing Red Hat Developer Hub on OpenShift Container Platform.
Procedure
To access the data from the JSON files, add the following code to the
app-config.yamlDeveloper Hub configuration file:proxy: endpoints: # Other Proxies # customize developer hub instance '/developer-hub': target: <DOMAIN_URL> # i.e https://raw.githubusercontent.com/ pathRewrite: '^/api/proxy/developer-hub': <path to json file> # i.e /redhat-developer/rhdh/main/packages/app/public/homepage/data.json changeOrigin: true secure: true # Change to "false" in case of using self hosted cluster with a self-signed certificate headers: <HEADER_KEY>: <HEADER_VALUE> # optional and can be passed as needed i.e Authorization can be passed for private GitHub repo and PRIVATE-TOKEN can be passed for private GitLab repoThe icon field uses predefined system icons. Select the correct key for your service from the Common icons for customization table.
9.3.10.3. Use a dedicated service to provide data
You can deploy a dedicated customization service to provide Quick access card data to your Developer Hub instance. This approach allows you to use the same service for all configurable pages or different services for each page.
Prerequisites
- You have installed the Red Hat Developer Hub using Helm chart. For more information, see Installing Red Hat Developer Hub on OpenShift Container Platform with the Helm chart.
Procedure
- In the Red Hat OpenShift Container Platform web console, click +Add > Import from Git.
Enter the URL of your Git repository into the Git Repo URL field.
To use the
red-hat-developer-hub-customization-providerservice, add the URL for the red-hat-developer-hub-customization-provider repository or your fork of the repository containing your customizations.-
On the General tab, enter
red-hat-developer-hub-customization-providerin the Name field and click Create. On the Advanced Options tab, copy the value from Target Port.
NoteTarget Port automatically generates a Kubernetes or OpenShift Container Platform service to communicate with.
Add the following code to the
app-config.yamlfile:proxy: endpoints: # Other Proxies # customize developer hub instance '/developer-hub': target: ${HOMEPAGE_DATA_URL} # For example: http://<SERVICE_NAME>:8080, such as http://rhdh-customization-provider:8080 changeOrigin: true # Change to "false" in case of using self-hosted cluster with a self-signed certificate secure: trueNoteThe
red-hat-developer-hub-customization-providerservice contains the 8080 port by default. If you are using a custom port, you can specify it with the 'PORT' environmental variable in theapp-config.yamlfile.-
Replace the
HOMEPAGE_DATA_URLby adding the URL torhdh-secretsor by directly replacing it in your custom ConfigMap. - Delete the Developer Hub pod to ensure that the new configurations are loaded correctly.
Verification
To view the service, go to the OpenShift Container Platform web console and click Networking > Service.
NoteYou can also view Service Resources in the Topology view.
Ensure that the provided API URL for the Home page returns the data in JSON format as shown in the following example:
[ { "title": "Dropdown 1", "isExpanded": false, "links": [ { "iconUrl": "https://imagehost.com/image.png", "label": "Dropdown 1 Item 1", "url": "https://example.com/" }, { "iconUrl": "https://imagehost2.org/icon.png", "label": "Dropdown 1 Item 2", "url": "" } ] }, { "title": "Dropdown 2", "isExpanded": true, "links": [ { "iconUrl": "http://imagehost3.edu/img.jpg", "label": "Dropdown 2 Item 1", "url": "http://example.com" } ] } ]NoteIf the request call fails or is not configured, the Developer Hub instance falls back to the default local data.
If the images or icons do not load, then allowlist them by adding your image or icon host URLs to the Content Security Policy (CSP)
img-srcin your custom ConfigMap as shown in the following example:kind: ConfigMap apiVersion: v1 metadata: name: app-config.yaml data: app-config.yaml: | app: title: Red Hat Developer Hub backend: csp: connect-src: - "'self'" - 'http:' - 'https:' img-src: - "'self'" - 'data:' - <image host url 1> - <image host url 2> - <image host url 3> # Other Configurations
9.3.11. Customize the RHDH Metadata card on the Settings page
Override the default RHDH Metadata card on the Settings page to show custom build information about your Red Hat Developer Hub instance.
Procedure
In your app-config.yaml file, configure the
buildinfofield. For example:buildInfo: title: _<metadata_card_title>_ card: TechDocs builder: '_<techdocs_builder>_' Authentication provider: '_<authentication_provider>_' RBAC: disabled full: truewhere
- <metadata_card_title>
- Specifies the title that you want to display on the customized card.
- <techdocs_builder>
-
Specifies whether to generate and publish the docs or to only fetch the docs when using the default build strategy. Possible values are
localorexternal. If you want to generate and publish the docs, set thetechdocs.builderfield tolocalin your app-config.yaml file. If you only want to fetch the docs without generating and publishing them, set thetechdocs.builderfield toexternal. - <authentication_provider>
-
Specifies the authentication provider that you want to use. Example values are
GitHuborGitLab. full-
Specifies what information is shown on the customized card. Possible values are
trueorfalse. If set totrue, only the information specified in this configuration is shown on the card. If set tofalse, the specified information is shown on the card along with the build versions. The default value istrue.
Verification
The Settings page displays a card with a custom title and custom build information about your Red Hat Developer Hub instance.
9.4. Configure language localization to improve accessibility for global users
9.4.1. Configure language localization to improve accessibility for global users
Red Hat Developer Hub supports multiple languages through its localization framework, enabling international teams to use the platform in their preferred language.
9.4.2. Language detection
RHDH detects your language settings across multiple locations to select your RHDH default language.
The system determines the default language by using the following priority order:
- Browser language priority: The system first checks your browser language preferences.
-
Configuration priority: If no browser language matches the supported locales, the
defaultLocalefrom thei18nconfiguration in app-config.yaml is used as a fallback. -
Fallback priority: If neither browser preferences nor configuration provide a match, defaults to
en.
Once you pick a language, your selection is saved in the user settings. Later changes to the app-config.yaml file do not affect the selected language, because you are already using the system.
9.4.3. Language persistence
The RHDH UI persists your language selection to storage, restoring it on your next login or refresh.
Guest users cannot persist language preferences.
By default, Red Hat Developer Hub saves language settings to the database (database) and restores user language settings across browser sessions. Alternatively, you can configure the system to use browser local storage (browser) instead.
# Example configuration for browser storage userSettings: persistence: browser
Before making changes to language persistence in the user settings, make sure that plugin configurations are not affected.
9.4.4. Enable the localization framework
9.4.4.1. Enable the localization framework
Red Hat Developer Hub supports multiple languages through its localization framework. You can enable language selection, override default translations, and implement localization support in custom plugins.
9.4.4.2. Enable the localization framework in Developer Hub
Enabling localization enhances accessibility, improves the user experience for a global audience, and assists organizations in meeting language requirements in specific regions.
Learn how to enable the localization framework to add a localization feature to RHDH. The following languages are supported:
- English (en)
- French (fr)
- German (de)
- Italian (it)
- Japanese (ja)
- Spanish (es)
The default language for RHDH is English.
Procedure
Add the
i18nsection to your custom Developer Hubapp-config.yamlconfiguration file:app-config.yamlfragment with localizationi18nfields... i18n: locales: # List of supported locales. Must include
en, otherwise the translation framework will fail to load. - en - fr - de - it - ja - es defaultLocale: en # Optional. Defaults toenif not specified. ...
9.4.4.3. Override default translations using JSON maps
You can override plugin translation strings without modifying the plugin source code.
Prerequisites
- You have enabled localization in your RHDH application.
-
For an Operator-installed RHDH instance, you have installed the OpenShift CLI (
oc). For more information about installingoc, see Installing the OpenShift CLI.
Procedure
Create a JSON file containing the translation strings that you want to override, as shown in the following example. Supported languages include English (default), French, German, Italian, Japanese and Spanish.
allTranslations.jsonfragment with translation string overrides{ "plugin.global-header": { "en": { "applicationLauncher.developerHub": "{product-short} EN JSON" }, "fr": { "applicationLauncher.developerHub": "{product-short} French JSON" } } }Log in to your cluster and create a config map for your translations override strings:
$ oc create configmap all-translations \ --from-file=/<path_to>/allTranslations.jsonUpdate your deployment configuration based on your installation method:
NoteAs shown in the following examples, we recommend that you use the same mount path for your
allTranslations.jsonfile and any other override files that you create, for example/opt/app-root/src/translations.For an Operator-installed RHDH instance, update your
Backstagecustom resource (CR). For more information about configuring a CR, see Using the Red Hat Developer Hub Operator to run Developer Hub with your custom configuration.In the
spec.application.extraFilessection, add the translations custom app configuration as shown in the following example:Backstage custom resource fragment
apiVersion: rhdh.redhat.com/v1alpha5 kind: {product-custom-resource-type} spec: application: extraFiles: mountPath: /opt/app-root/src/translations configMaps: - name: all-translations
For a Helm-installed RHDH instance, update your Developer Hub
BackstageHelm chart to mount in the Developer Hub filesystem your files from theall-translationsconfig map:- In the Developer Hub Helm chart, go to Root Schema → Backstage chart schema → Backstage parameters → Backstage container additional volume mounts.
Select Add Backstage container additional volume mounts and add the following values:
- mountPath
-
/opt/app-root/src/translations - name
-
all-translations
Add the translations to the Backstage container additional volumes in the Developer Hub Helm chart:
- name
-
all-translations - configMap
- defaultMode
-
420 - name
-
all-translations
Update the
i18nsection to your custom Developer Hubapp-config.yamlconfiguration file to include the following translation override file:app-config.yamlfragment with localizationi18nfieldsi18n: locales: # List of supported locales. Must include
en, otherwise the translation framework will fail to load. - en - fr - de - it - ja - es defaultLocale: en # Optional. Defaults toenif not specified. overrides: # List of JSON translation files applied in order (last file wins). Each file may override/add translations for one or more plugins/locales - /opt/app-root/src/translations/all-translations.json
9.4.4.4. Implement localization in custom plugins
You can implement localization support in your custom RHDH plugins so that your plugins are accessible to a diverse, international user base and follow recommended best practices.
Procedure
Create the following translation files in your plugin’s
src/translations/directory:import { createTranslationRef } from "@backstage/core-plugin-api/alpha"; export const myPluginMessages = { page: { title: "My Plugin", subtitle: "Plugin description", }, common: { exportCSV: "Export CSV", noResults: "No results found", }, table: { headers: { name: "Name", count: "Count", }, }, }; export const myPluginTranslationRef = createTranslationRef({ id: "plugin.my-plugin", messages: myPluginMessages, });import { createTranslationMessages } from "@backstage/core-plugin-api/alpha"; import { myPluginTranslationRef } from "./ref"; const myPluginTranslationDe = createTranslationMessages({ ref: myPluginTranslationRef, messages: { "page.title": "Mein Plugin", "page.subtitle": "Plugin-Beschreibung", "common.exportCSV": "CSV exportieren", "common.noResults": "Keine Ergebnisse gefunden", "table.headers.name": "Name", "table.headers.count": "Anzahl", }, }); export default myPluginTranslationDe;import { createTranslationMessages } from "@backstage/core-plugin-api/alpha"; import { myPluginTranslationRef } from "./ref"; const myPluginTranslationFr = createTranslationMessages({ ref: myPluginTranslationRef, messages: { "page.title": "Mon Plugin", "page.subtitle": "Description du plugin", "common.exportCSV": "Exporter CSV", "common.noResults": "Aucun résultat trouvé", "table.headers.name": "Nom", "table.headers.count": "Nombre", }, }); export default myPluginTranslationFr;import { createTranslationResource } from "@backstage/core-plugin-api/alpha"; import { myPluginTranslationRef } from "./ref"; export const myPluginTranslations = createTranslationResource({ ref: myPluginTranslationRef, translations: { de: () => import("./de"), fr: () => import("./fr"), }, }); export { myPluginTranslationRef };Create translation hooks file, as follows:
import { useTranslationRef } from "@backstage/core-plugin-api/alpha"; import { myPluginTranslationRef } from "../translations"; export const useTranslation = () => useTranslationRef(myPluginTranslationRef);Update your plugin components to replace hard-coded strings with translation calls as shown in the following example:
const MyComponent = () => { return ( <div> <h1>My Plugin</h1> <button>Export CSV</button> </div> ); };import { useTranslation } from '../hooks/useTranslation'; const MyComponent = () => { const { t } = useTranslation(); return ( <div> <h1>{t('page.title')}</h1> <button>{t('common.exportCSV')}</button> </div> ); };(Optional) If your content contains variables, use interpolation:
// In your translation files 'table.pagination.topN': 'Top {{count}} items' // In your component const { t } = useTranslation(); const message = t('table.pagination.topN', { count: '10' });(Optional) If your content contains dynamic translation keys (for example, from your plugin configuration):
// Configuration object with translation keys const CARD_CONFIGS = [ { id: 'overview', titleKey: 'cards.overview.title' }, { id: 'details', titleKey: 'cards.details.title' }, { id: 'settings', titleKey: 'cards.settings.title' }, ]; // In your component const { t } = useTranslation(); const CardComponent = ({ config }) => { return ( <div> <h2>{t(config.titleKey as any)}</h2> {/* Use 'as any' for dynamic keys */} </div> ); };Export the translation resources
// Export your plugin export { myPlugin } from "./plugin"; // Export translation resources for the application export { myPluginTranslations, myPluginTranslationRef } from "./translations";Update your
dynamic-plugins.default.yamlfile, as follows:backstage-community.plugin-my-plugin: translationResources: - importName: myPluginTranslations ref: myPluginTranslationRef module: AlphaUpdate your
package.jsonfile as follows:"exports": { ".": "./src/index.ts", "./alpha": "./src/alpha.ts", "./package.json": "./package.json" }, "main": "src/index.ts", "types": "src/index.ts", "typesVersions": { "*": { "alpha": [ "src/alpha.ts" ], "package.json": [ "package.json" ] } }
Verification
To verify your translations, create a test mock file. For example:
Create the following test mock file src/test-utils/mockTranslations.ts:
import { myPluginMessages } from "../translations/ref";
function flattenMessages(obj: any, prefix = ""): Record<string, string> {
const flattened: Record<string, string> = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
const newKey = prefix ? `${prefix}.${key}` : key;
if (typeof value === "object" && value !== null) {
Object.assign(flattened, flattenMessages(value, newKey));
} else {
flattened[newKey] = value;
}
}
}
return flattened;
}
const flattenedMessages = flattenMessages(myPluginMessages);
export const mockT = (key: string, params?: any) => {
let message = flattenedMessages[key] || key;
if (params) {
for (const [paramKey, paramValue] of Object.entries(params)) {
message = message.replace(
new RegExp(`{{${paramKey}}}`, "g"),
String(paramValue),
);
}
}
return message;
};
export const mockUseTranslation = () => ({ t: mockT });Update your tests as follows:
import { mockUseTranslation } from "../test-utils/mockTranslations";
jest.mock("../hooks/useTranslation", () => ({
useTranslation: mockUseTranslation,
}));
// Your test code...9.4.4.5. Select a language
Use the Appearance panel to select a language for RHDH. Supported languages include English (default), French, German, Italian, Japanese and Spanish.
Prerequisites
- You are logged in to the Developer Hub web console.
- You have enabled the localization framework in your RHDH instance.
Procedure
- From the Developer Hub web console, click the down arrow next to your profile name, then click Settings.
From the Appearance panel, click the language dropdown to select your language of choice.

9.4.5. Localization best practices
These best practices help ensure a robust, type-safe localization workflow with reliable deployment across all targeted languages.
- Do not modify original English strings
- This preserves the source of truth for all translators, preventing unexpected changes that would invalidate existing translations and ensuring consistency across all versions.
- Use flat dot notation in translation files
-
Flat dot notation, for example
page.title, follows the standardi18nextlibrary convention, which optimizes runtime lookups and keeps the actual translation values concise and easy to manage for translation services. - Use nested objects in the reference file for TypeScript support
- This allows the TypeScript compiler to enforce structural type checking on your translation keys, catching errors during development rather than at runtime.
- Test with mocks to ensure translations work correctly
- This isolates the translation logic, guaranteeing the correct keys are passed and rendered without relying on a full environment setup or external translation files during unit testing.
- Add all languages to your application configuration
- This ensures that the RHDH application initializes and loads all necessary language resources at startup, making the locales immediately available for users to select in the UI.
Common patterns for using translation functions include simple text, variables, and dynamic keys:
| Use case | Pattern | Example |
|---|---|---|
|
Simple text |
|
|
|
With variables |
|
|
|
Dynamic keys |
|
|
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. 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 provisioning | Authentication |
|---|---|
|
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.
ImportantWithout this provisioning step, features such as displaying who owns a catalog entity might not function correctly.
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
dangerouslyAllowSignInWithoutUserInCatalogresolver option. This setting bypasses the check requiring a user to be in the catalog but still enforces authentication.
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
In the
app-config.yamlfile, set the authentication environment todevelopment:auth: environment: development
- Restart the Developer Hub application to apply the changes.
Verification
- Go to the login page of your Developer Hub instance.
- 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
In the
app-config.yamlfile, set the authentication environment toproduction:auth: environment: production
- Restart the Developer Hub application to apply the changes.
Verification
- Go to the login page of your Developer Hub instance.
- Verify that the option to log in as a guest is no longer available.
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 RHBK
Configure Red Hat Build of Keycloak (RHBK) as your Red Hat Developer Hub sign-in provider by enabling the OIDC authentication provider.
Prerequisites
- You have shared a secret with RHBK.
- You have provisioned users and groups to the software catalog.
Procedure
The OIDC provider authentication backend plugin requires Developer Hub to support sessions. Enable session support by adding the session secret to your
app-config.yamlfile:auth: session: secret: ${SESSION_SECRET}Add an OIDC provider section to your
app-config.yamlfile:auth: environment: production providers: oidc: production: metadataUrl: ${KEYCLOAK_BASE_URL} clientId: ${KEYCLOAK_CLIENT_ID} clientSecret: ${KEYCLOAK_CLIENT_SECRET} prompt: auto signInPage: oidcenvironment: production-
Mark the environment as
productionto hide the Guest login in the Developer Hub home page. metadataUrl,clientId,clientSecret- Configure the OIDC provider with your secrets.
promptEnter
autoto 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
oidcto enable the OIDC provider as default sign-in provider.
Optional: Add optional fields to the OIDC authentication provider section in your
app-config.yamlfile: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: oidccallbackUrl- 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.
signInresolversAfter 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
subparameter from OIDC to the RHBK user ID. Consider using this resolver for enhanced security. oidcLdapUuidMatchingAnnotationMatches 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.
preferredUsernameMatchingUserEntityNameMatches 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.
WarningIn production mode, configure only one resolver to make sure users are securely matched.
dangerouslyAllowSignInWithoutUserInCatalog: trueConfigure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.
WarningIn production mode, do not enable the
dangerouslyAllowSignInWithoutUserInCatalogoption.
sessionDuration-
Lifespan of the user session. Enter a duration in
mslibrary format (such as '24h', '2 days'), ISO duration, or "human duration" as used in code. backstageTokenExpirationEnter 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.
WarningIf 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.
- From the Configure section of the navigation menu, click Realm Settings.
- From the Realm Settings page, click the Tokens tab.
- From the Refresh tokens section of the Tokens tab, toggle the Revoke Refresh Token to the Enabled position.
To disable the guest login option, in the
app-config.yamlfile, set the authentication environment toproduction:auth: environment: production
Verification
- Go to the Developer Hub login page.
- Your Developer Hub sign-in page displays Sign in using OIDC and the Guest user sign-in is disabled.
- Log in with OIDC by using the saved Username and Password values.
10.2.6.3. Match users by LDAP UUID with RHBK
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
-
In the Red Hat Build of Keycloak admin console, go to Client scopes and click Create client scope. Name the scope
ldap_uuid. In the
ldap_uuidscope, 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
-
Name:
-
Go to Clients > your Red Hat Developer Hub client > Client scopes. Click Add client scope and add
ldap_uuidas a Default scope. Optional: Add the
oidcLdapUuidMatchingAnnotationresolver to yourapp-config.yamlfile, to replace the defaultldap_uuidresolver:auth: providers: oidc: production: signIn: resolvers: - resolver: oidcLdapUuidMatchingAnnotation ldapUuidKey: ldap_uuidldapUuidKey-
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.
- 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.
Prerequisites
- You have shared secrets with GitHub.
- You have provisioned users and groups to the software catalog.
Procedure
Add a GitHub authentication provider section to your
app-config.yamlfile:auth: environment: production providers: github: production: clientId: ${GITHUB_APP_CLIENT_ID} clientSecret: ${GITHUB_APP_CLIENT_SECRET} signInPage: githubenvironment-
Enter
productionto 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
githubto enable the GitHub provider as your Developer Hub sign-in provider.
Optional: Add optional fields to the GitHub authentication provider section in your
app-config.yamlfile: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: githubcallbackUrl- 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
mslibrary format (such as '24h', '2 days'), ISO duration, or "human duration". signInresolvers- 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.
WarningIn 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. dangerouslyAllowSignInWithoutUserInCatalogEnter
trueto configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.WarningIn production mode, do not enable
dangerouslyAllowSignInWithoutUserInCatalog.
To disable the guest login option, in the
app-config.yamlfile, set the authentication environment toproduction:auth: environment: production
Verification
- Go to the Developer Hub login page.
- Your Developer Hub sign-in page displays Sign in using GitHub and the Guest user sign-in is disabled.
- 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.
Prerequisites
Procedure
Add the Microsoft authentication provider to your
app-config.yamlfile:auth: environment: production providers: microsoft: production: clientId: ${MICROSOFT_CLIENT_ID} clientSecret: ${MICROSOFT_CLIENT_SECRET} tenantId: ${MICROSOFT_TENANT_ID} signInPage: microsoftenvironment-
Enter
productionto 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
microsoftto set the Azure provider as your Developer Hub sign-in provider.
Optional: Add optional fields to the Microsoft authentication provider section in your
app-config.yamlfile: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: microsoftdomainHintLeave 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
mslibrary (such as '24h', '2 days'), ISO duration, or "human duration" format. signIn.resolversAfter 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.
WarningIn production mode, configure only one resolver to make sure users are securely matched.
resolverEnter 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.
dangerouslyAllowSignInWithoutUserInCatalogEnter
trueto configure the sign-in resolver to bypass the user provisioning requirement in the Developer Hub software catalog.WarningIn production mode, do not enable
dangerouslyAllowSignInWithoutUserInCatalog.
To disable the guest login option, in the
app-config.yamlfile, set the authentication environment toproduction:auth: environment: production
Verification
- Go to the Developer Hub login page.
- Your Developer Hub sign-in page displays Sign in using Microsoft and the Guest user sign-in is disabled.
- 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.
Prerequisites
- You have shared secrets with GitLab.
- You have provisioned users and groups to the software catalog.
Procedure
Add a GitLab authentication provider section to your RHDH
app-config.yamlfile: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/frameaudience-
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
To disable the guest login option, in the
app-config.yamlfile, set the authentication environment toproduction:auth: environment: production
Verification
- Go to the Developer Hub login page.
- Your Developer Hub sign-in page displays Sign in using GitLab and the Guest user sign-in is disabled.
- 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
- You have administrative access to PingFederate with a configured LDAP Data Store.
- You have configured the LDAP catalog provider in Developer Hub.
- You have added a custom Developer Hub application configuration, and have enough permissions to modify it.
Procedure
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.
- In PingFederate, go to System > Data Stores and edit your LDAP store.
-
In Advanced options > LDAP Binary Attributes, add
objectGUIDto the list. -
In the Attribute Source lookup configuration, set the Encoding Type for
objectGUIDto Hex.
Create the Authentication Policy Contract.
The contract bridges the LDAP directory and the OIDC policy, transforming the binary GUID into a string format.
-
Create a new contract named
rhdh-contract. - Add an Attribute Source linked to your LDAP Data Store.
-
Set the Search Filter to
sAMAccountName=${username}. -
Expose the LDAP UUID attribute (for example,
objectGUIDfor Active Directory) within the contract. Under Contract Fulfillment, map thesubclaim to theobjectGUIDfrom LDAP by using an Expression source. 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.
-
Create a new contract named
Configure OAuth and OIDC scopes.
Ensure PingFederate allows the standard OIDC scopes requested by Developer Hub.
- Navigate to System > OAuth Scopes.
-
Ensure
emailandprofileare added to the Common Scopes list.
Bridge the contract to the OIDC policy.
Configure the policy to deliver the transformed UUID through the
subclaim in the ID token and UserInfo endpoint.-
Access Token Mapping: Map the
subfield fromrhdh-contractto your Access Token Manager. -
OIDC Policy Fulfillment: Fulfill the
subclaim by selecting Access Token as the source andsubas the value. -
Enable Delivery: In the OIDC Policy Attribute Contract, select the ID Token and UserInfo checkboxes for the
subclaim. -
Extend Contract: Add
ldap_uuidto the Attribute Contract and map it to thesubvalue by using the Access Token to ensure consistency.
-
Access Token Mapping: Map the
Create the OIDC client.
- In PingFederate, go to Applications > OAuth Clients and click Add Client.
- Under Client Authentication, select Client Secret, generate a secret, and save it.
-
Enter the Redirect URI:
https://<my_developer_hub_domain>/api/auth/oidc/handler/frame. - Under Allowed Grant Types, select Authorization Code.
- Under OpenID Connect > Policy, select the OIDC policy you created.
Save the following values for the next step:
- Client ID
- Client Secret
-
OIDC metadata URL: The
.well-known/openid-configurationendpoint URL for your PingFederate instance.
- Create a long, complex, and unique string to use as the Developer Hub session secret key.
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.
Enable session support by adding the session secret to your
app-config.yamlfile:auth: session: secret: ${SESSION_SECRET}Enable the PingFederate authentication provider with the LDAP UUID matching resolver by adding the OIDC provider section in your
app-config.yamlfile: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: oidcenvironment: production-
Mark the environment as
productionto 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_uuidclaim from the UserInfo endpoint to the LDAP catalog entity. ldapUuidKey-
Enter the claim key containing the LDAP UUID. Set to
subto use thesubclaim, which contains the transformed UUID from the PingFederate policy contract. signInPage-
Enter
oidcto enable the OIDC provider as the default sign-in provider.
Verification
- Go to the Developer Hub login page.
- Verify that the Developer Hub sign-in page displays Sign in using OIDC and the Guest user sign-in is disabled.
- Log in with OIDC by using your PingFederate user credentials.
10.2.6.8. Enable 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.
TipAlternatively, 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
Add the
auth.providers.githubsection to yourapp-config.yamlfile:auth: providers: github: production: clientId: ${GITHUB_APP_CLIENT_ID} clientSecret: ${GITHUB_APP_CLIENT_SECRET} disableIdentityResolution: truewhere:
clientId:: Enter the configured secret variable name:${GITHUB_APP_CLIENT_ID}.clientSecret-
Enter the configured secret variable name:
${GITHUB_APP_CLIENT_SECRET}. disableIdentityResolution-
Enter
trueto skip user identity resolution for this provider to enable sign-in from an auxiliary authentication provider.
WarningDo not enable this setting on the primary authentication provider you plan on using for sign-in and identity management.
To disable the guest login option, in the
app-config.yamlfile, set the authentication environment toproduction:auth: environment: production
Verification
- Go to the Developer Hub login page.
- Log in with your primary authentication provider account.
- In the top user menu, go to Settings > Authentication Providers.
- In the GitHub line, click the Sign in button and log in.
- In the GitHub line, the button displays Sign out.
Additional resources
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.
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. Use 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.yamlconfiguration 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
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.
-
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. Add the generated token or JWKS URL to your
app-config.yamlDeveloper 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
staticto specify that authentication is using a static token. optionsEnter 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.
Use the token in the
Authorizationheader of your service requests.When making requests from one service to another, include the static token in the
Authorizationheader 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
curlcommand, 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
subjectvalue as the actor.
10.2.7.2.3. Use 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.

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
Authorizationheader of requests to Developer Hub.
Procedure
Add the JWKS URL to your
app-config.yamlDeveloper 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
jwksto specify that authentication is using JWKS tokens. optionsEnter 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
issfield, such ashttp://your-idp.example.com. audience-
(Optional) Enter the expected audience claim in the token
audfield, such asmanagement. 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
Restrict access to specific plugins.
For example, to restrict access to the catalog plugin for the static tokens, add the following
accessRestrictionssection to yourapp-config.yamlDeveloper Hub configuration file:backend: auth: externalAccess: - type: static accessRestrictions: - plugin: catalogtype-
Specify whether this is a
jwksorstatictoken. plugin-
Specify the allowed plugin, such as
catalog,scaffolder, ortechdocs.
With this configuration:
-
The token is only allowed to make requests to the
catalogplugin. -
The token has unrestricted access to all actions within the
catalogplugin.
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
createandread.backend: auth: externalAccess: - type: jwks accessRestrictions: - plugin: catalog permissionAttribute: action: - create - readRestrict 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.readBy 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
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.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. 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.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.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.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.
Additional resources
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
To set the absolute session lifetime for an authentication provider, add the
sessionDurationparameter to yourapp-config.yamlfile:auth: providers: <name>: <env>: sessionDuration: 24hsessionDurationEnter 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.
- Restart the Red Hat Developer Hub application to apply the changes.
Additional resources
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.
Prerequisites
Procedure
Add the
auth.autologoutsection to your{my-app-config.yaml}file.auth: autologout: enabled: true idleTimeoutMinutes: 60 promptBeforeIdleSeconds: 10 useWorkerTimers: false logoutIfDisconnected: truewhere:
enabledEnter
trueto enable auto-logout.Enter
falseto 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
60minutes.promptBeforeIdleSeconds(Optional) Enter the number of seconds before the auto-logout occurs to prompt the user about the pending logout.
The default value is
10seconds.useWorkerTimers(Optional) Enter
falseto 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
trueto 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
trueto 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
falseto 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.
- Restart the Red Hat Developer Hub application to apply the changes.
Verification
- Log in to the Red Hat Developer Hub application.
-
Remain inactive for the duration specified in
idleTimeoutMinutes. -
Observe that a prompt is displayed before the auto-logout occurs, as specified in
promptBeforeIdleSeconds. - 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.yamlfile, setomitIdentityTokenOwnershipClaimtotrueas 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:
- Enable the RBAC feature and give authorized users access to the feature.
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. Role-based access control in Developer Hub
Administrators can authorize users to perform actions and define what users can do 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:
- Enable the RBAC feature and give authorized users access to the feature.
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.3. Enable the RBAC plugin
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.
Prerequisites
Procedure
The RBAC plugin is installed but disabled by default. To enable the
./dynamic-plugins/dist/backstage-community-plugin-rbacplugin, edit yourdynamic-plugins.yamlwith the following content.dynamic-plugins.yamlfragmentplugins: - package: ./dynamic-plugins/dist/backstage-community-plugin-rbac disabled: falseSee Installing and viewing plugins in Red Hat Developer Hub.
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-configconfig 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 theapp-config.yamlcontent:app-config.yamlfragmentpermission: enabled: true rbac: admin: users: - name: user:default/<your_policy_administrator_name>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.
To supply plugins by updating your application configuration, you can specify the plugins with permissions in your
app-config.yamlfile as follows:app-config.yamlfragmentpermission: enabled: true rbac: admin: users: - name: user:default/<your_policy_administrator_name> pluginsWithPermission: - catalog - scaffolder - permission- To specify the plugins with permissions by using the RBAC REST API permissions endpoint, see the RBAC REST API permissions endpoint.
Verification
- Sign out from the existing Red Hat Developer Hub session and log in again using the declared policy administrator account.
With RBAC enabled, most features are disabled by default.
- Navigate to the Catalog page in RHDH. The Create button is not visible. You cannot create new components.
- Navigate to the API page. The Register button is not visible.
Next steps
- Explicitly enable permissions to resources in Developer Hub.
10.3.4. Determine your policy 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.yamlconfiguration file, for instance to declare your policy administrators.The Configuration file pertains to the default
role:default/rbac_adminrole 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.NoteIn 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.ImportantReplace 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
GETrequest.
10.3.5. Design 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
denybasic rule overrides anallowbasic rule. -
An
allowconditional rule overrides adenybasic rule. -
A
denyconditional rule overrides anallowconditional rule.
Procedure
-
Use
allowrules to explicitly allow access. -
Avoid creating
denyrules unless you know precisely how they can affect existing basicallowrules and existing conditional rules.
10.3.6. Manage roles using the Web UI
10.3.6.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.6.2. Create a role
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
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.
- (Optional) Click any role to view the role information on the OVERVIEW page.
- Click CREATE to create a role.
- Enter the name and description of the role in the given fields and click NEXT.
- Add users and groups using the search field, and click NEXT.
- Select Plugin and Permission from the drop-downs in the Add permission policies section.
- Select or clear the Policy that you want to set in the Add permission policies section, and click NEXT.
- Review the added information in the Review and create section.
- Click CREATE.
Verification
The created role is displayed in the list available in the RBAC tab.
10.3.6.3. Edit a role
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.
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
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.
- (Optional) Click any role to view the role information on the OVERVIEW page.
- Select the edit icon for the role that you want to edit.
- Edit the details of the role, such as name, description, users and groups, and permission policies, and click NEXT.
- Review the edited details of the role and click SAVE.
Verification
- After saving the changes, you can view the edited details of the role on the OVERVIEW page of the role.
- 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.6.4. Delete a role
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.
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
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.
- (Optional) Click any role to view the role information on the OVERVIEW page.
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.
- Click DELETE.
10.3.7. Manage policies using the REST API
10.3.7.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.7.2. Send requests 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.
Prerequisites
Procedure
Find your Bearer token to authenticate to the REST API.
- In your browser, open the web console Network tab.
- In the main screen, reload the Developer Hub Homepage.
-
In the web console Network tab, search for the
query?term=network call. - Save the token in the response JSON for the next steps.
In a terminal, run the curl command and review the response:
GETrequest, orDELETErequest not requiring JSON body dataEnter 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>" \
POSTorPUTrequest, orDELETErequest requiring JSON body dataEnter 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, orPUTrequest, and might require with the HTTPDELETErequest.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:
200OK- The request was successful.
201Created- The request resulted in a new resource being successfully created.
204No Content- The request was successful, and the response payload has no more content.
400Bad Request- Input error with the request.
401Unauthorized- Lacks valid authentication for the requested resource.
403Forbidden- Refusal to authorize request.
404Not Found- Could not find requested resource.
409Conflict- Request conflict with the current state and the target resource.
10.3.7.3. Send requests 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.
Prerequisites
Procedure
Find your Bearer token to authenticate to the REST API.
- In your browser, open the web console Network tab.
- In the main screen, reload the Developer Hub Homepage.
-
In the web console Network tab, search for the
query?term=network call. - Save the token in the response JSON for the next steps.
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
POSTrequest.
10.3.7.4. Send requests 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
- You have access to the RBAC feature.
- The external service can send HTTP GET requests, and is authenticated by using a service-to-service token.
Procedure
-
The external service sends a GET request to the RBAC REST API with the service-to-service token in the
Authorizationheader. - 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.
- The RBAC REST API returns the response to the external service.
- The external service processes the response from the RBAC REST API.
10.3.7.5. Supported REST API endpoints
10.3.7.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.7.5.2. Roles
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.7.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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
The |
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, ornamefor a role in Developer Hub.
Request parameters: The request body contains the oldRole and newRole objects:
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
The |
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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Kind of the entity |
String |
Required |
|
|
Namespace of the entity |
String |
Required |
|
|
Name of the entity |
String |
Required |
|
|
Associated group information |
String |
Required |
Example response:
+
204
- [DELETE] /api/permission/roles/<kind>/<namespace>/<name>
- Deletes a specified role from Developer Hub.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Kind of the entity |
String |
Required |
|
|
Namespace of the entity |
String |
Required |
|
|
Name of the entity |
String |
Required |
Example response:
+
204
10.3.7.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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Kind of the entity |
String |
Required |
|
|
Namespace of the entity |
String |
Required |
|
|
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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Reference values of an entity including |
String |
Required |
|
|
Permission from a specific plugin, resource type, or name |
String |
Required |
|
|
Policy action for the permission, such as |
String |
Required |
|
|
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:
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Permission from a specific plugin, resource type, or name |
String |
Required |
|
|
Policy action for the permission, such as |
String |
Required |
|
|
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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Kind of the entity |
String |
Required |
|
|
Namespace of the entity |
String |
Required |
|
|
Name related to the entity |
String |
Required |
|
|
Permission from a specific plugin, resource type, or name |
String |
Required |
|
|
Policy action for the permission, such as |
String |
Required |
|
|
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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Kind of the entity |
String |
Required |
|
|
Namespace of the entity |
String |
Required |
|
|
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"]
}
]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.7.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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Always has the value |
String |
Required |
|
|
String entity reference to the RBAC role, such as |
String |
Required |
|
|
Corresponding plugin ID, such as |
String |
Required |
|
|
Array permission action, such as |
String array |
Required |
|
|
Resource type provided by the plugin, such as |
String |
Required |
|
|
Condition JSON with parameters or array parameters joined by criteria |
JSON |
Required |
|
|
Name of the role |
String |
Required |
|
|
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.
| Name | Description | Type | Presence |
|---|---|---|---|
|
|
Always has the value |
String |
Required |
|
|
String entity reference to the RBAC role, such as |
String |
Required |
|
|
Corresponding plugin ID, such as |
String |
Required |
|
|
Array permission action, such as |
String array |
Required |
|
|
Resource type provided by the plugin, such as |
String |
Required |
|
|
Condition JSON with parameters or array parameters joined by criteria |
JSON |
Required |
|
|
Name of the role |
String |
Required |
|
|
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.7.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.7.5.3. User statistics
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.8. Define policies in external files to provision permissions during cluster deployment
10.3.8.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.8.2. Define authorizations 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.
Prerequisites
Procedure
Define your policies in a
rbac-policies.csvCSV file by using the following format: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, orcatalog.entity.refresh, or permission resource type, such as:bulk-importorcatalog-entity.- <action>
-
Action type, such as:
use,read,create,update,delete. - <allow_or_deny>
-
Access granted:
allowordeny.
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
Define your conditional policies in a
rbac-conditional-policies.yamlYAML file by using the following format:result: CONDITIONAL roleEntityRef: <role_entity_reference> pluginId: <plugin_id> permissionMapping: - read - update - delete conditions: <conditions>
Upload your
rbac-policies.csvandrbac-conditional-policies.yamlfiles to arbac-policiesconfig 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.yamlUpdate your
Backstagecustom resource to mount in the Developer Hub filesystem your files from therbac-policiesconfig map:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage spec: application: extraFiles: mountPath: /opt/app-root/src configMaps: - name: rbac-policiesUpdate your Developer Hub
app-config.yamlconfiguration file to use therbac-policies.csvandrbac-conditional-policies.yamlexternal 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.8.3. Define authorizations by using the Helm Chart
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.
Prerequisites
Procedure
Define your policies in a
rbac-policies.csvCSV file by using the following format: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, orcatalog.entity.refresh, or permission resource type, such as:bulk-importorcatalog-entity.- <action>
-
Action type, such as:
use,read,create,update,delete. - <allow_or_deny>
-
Access granted:
allowordeny.
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
Define your conditional policies in a
rbac-conditional-policies.yamlYAML file by using the following format:result: CONDITIONAL roleEntityRef: <role_entity_reference> pluginId: <plugin_id> permissionMapping: - read - update - delete conditions: <conditions>
Upload your
rbac-policies.csvandrbac-conditional-policies.yamlfiles to arbac-policiesconfig 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.yamlUpdate your Developer Hub
BackstageHelm chart to mount in the Developer Hub filesystem your files from therbac-policiesconfig map:- In the Developer Hub Helm Chart, go to Root Schema → Backstage chart schema → Backstage parameters → Backstage container additional volume mounts.
Select Add Backstage container additional volume mounts and add the following values:
- mountPath
-
/opt/app-root/src/rbac - Name
-
rbac-policies
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
Update your Developer Hub
app-config.yamlconfiguration file to use therbac-policies.csvandrbac-conditional-policies.yamlexternal 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.8.4. Configure RBAC for Extensions
You can grant access to Extensions plugin management by adding permission policies to your RBAC CSV file.
Prerequisites
- You have enabled RBAC and assigned a policy administrator role.
- You manage authorizations by using external files.
-
You have added
extensionsto the list of authorized plugins under yourpermission.rbac.pluginsWithPermissionconfiguration.
Procedure
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, allowOptional: Restrict access to specific plugins by defining a conditional policy in the
rbac-conditional-policies.yamlfile 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:
pluginNamesEnter 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.
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.
Additional resources
10.3.9. Configure guest access
10.3.9.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.
Guest access is not recommended for production.
10.3.9.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-rbacplugin in Developer Hub. For more information, see Configuring dynamic plugins.
Procedure
Update the
app-config.yamlfile to enable the permission framework as shown:permission enabled: true rbac: admin: users: - name: user:default/guest pluginsWithPermission: - catalog - permission - scaffolderNoteThe
pluginsWithPermissionsection of theapp-config.yamlfile includes only three plugins by default. Update the section as needed to include any additional plugins that also incorporate permissions.
10.3.9.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-rbacplugin in Developer Hub. For more information, see Configuring dynamic plugins.
Procedure
In the
app-config.yamlfile, add the user entity reference to resolve and enable thedangerouslyAllowOutsideDevelopmentoption, as shown in the following example:auth: environment: development providers: guest: userEntityRef: user:default/guest dangerouslyAllowOutsideDevelopment: trueNoteYou can use
user:default/guestas the user entity reference to match the added user under thepermission.rbac.admin.userssection of theapp-config.yamlfile.
10.3.10. Permission policy parameters and definitions
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.11. Define conditional policies
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:
Parameter Type Description resultString
Always has the value
CONDITIONALroleEntityRefString
String entity reference to the RBAC role, such as
role:default/devpluginIdString
Corresponding plugin ID, such as
catalogpermissionMappingString array
Array permission actions, such as
['read', 'update', 'delete']resourceTypeString
Resource type provided by the plugin, such as
catalog-entityconditionsJSON
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:
$currentUserThis 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,
$currentUserbecomesuser:default/tom.Example conditional policy object with
$currentUseralias:{ "result": "CONDITIONAL", "roleEntityRef": "role:default/developer", "pluginId": "catalog", "resourceType": "catalog-entity", "permissionMapping": ["delete"], "conditions": { "rule": "IS_ENTITY_OWNER", "resourceType": "catalog-entity", "params": { "claims": ["$currentUser"] } } }$ownerRefsThis 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,
$ownerRefsbecomes['user:default/tom', 'group:default/team-a'].Example conditional policy object with
$ownerRefsalias:{ "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.12. Download user statistics
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-rbacand@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
- In Red Hat Developer Hub, navigate to Administration and select the RBAC tab.
- At the bottom of the RBAC page, click Download User List.
- Optional: Change the file name in the Save as field and click Save.
- To access the downloaded users list, go to the Downloads folder on your local machine and open the CSV file.
10.3.13. Manage Orchestrator plugin permissions using RBAC policies
You can configure Role-Based Access Control (RBAC) policies so that users can view workflow details without the permission to run those workflows. This configuration restricts user interaction to authorized workflows.
The Orchestrator plugin uses specific permission strings to control access to workflows and instances. After you enable the role-based access control (RBAC) plugin, you must grant the following permissions in your rbac-policy.csv file to view and manage workflows in the Orchestrator UI:
orchestrator.workflow(read)- Lists and views workflow definitions and their instances. If this permission is missing, the workflow list in the UI appears empty.
orchestrator.workflow.use(update)- Executes or aborts a workflow.
orchestrator.workflowAdminView(read)- Accesses the workflow definition editor and instance variables.
orchestrator.instanceAdminView(read)- Views all workflow instances, including those created by other users.
Prerequisites
-
You have identified the [
workflowId] for each workflow you want to restrict. - You have enabled the RBAC plugin.
-
You have configured the
policies-csv-filepath in yourapp-config.yaml.
Procedure
Identify the
workflowIdfrom your workflow definition file:id: greeting version: '1.0'
In your RBAC policy CSV file, define the permissions using the
p, role, permission, action, allowformat.NoteGeneric permissions (for example,
orchestrator.workflow) take precedence over specific permissions targeting aworkflowId, (for example,orchestrator.workflow.greeting). You cannot grant generic access and then selectively deny a specific ID.Add the following example policies to your CSV file to establish basic user and administrator roles:
# Minimal user role - can only view and run specific workflows p, role:default/workflowUser, orchestrator.workflow.greeting, read, allow p, role:default/workflowUser, orchestrator.workflow.use.greeting, update, allow # Support role - can view all workflows and instances, but not execute p, role:default/workflowSupport, orchestrator.workflow, read, allow p, role:default/workflowSupport, orchestrator.instanceAdminView, read, allow # Full admin role - complete access to all Orchestrator functions p, role:default/workflowAdmin, orchestrator.workflow, read, allow p, role:default/workflowAdmin, orchestrator.workflow.use, update, allow p, role:default/workflowAdmin, orchestrator.workflowAdminView, read, allow p, role:default/workflowAdmin, orchestrator.instanceAdminView, read, allow # Assign users to the roles g, user:default/example_user, role:default/workflowUser
In your RHDH
app-config.yamlfile, enable permissions by adding theorchestratorplugin to therbacsection and settingpolicyFileReloadtotrue.permission: enabled: true rbac: policies-csv-file: <absolute_path_to_the_policy_file> pluginsWithPermission: - orchestrator policyFileReload: true admin: users: - name: user:default/YOUR_USER- Restart the application to apply the changes.
Verification
-
Log in as a user assigned to the
workflowUserrole. - Navigate to the Orchestrator plugin and verify that the workflow appears in the list.
You can view dynamic permissions containing a workflowId in the RBAC UI, but you cannot modify them in the interface. You must use the policy CSV file or the RBAC API to manage these specific workflow permissions.
Additional resources
10.3.14. Orchestrator plugin permissions
The Orchestrator plugin uses the Red Hat Developer Hub permission mechanism and the Role-Based Access Control (RBAC) plugin to restrict access to backend endpoints. Orchestrator supports decoupling visibility (read) from running (update) using specific workflow IDs instead of generic permissions.
| Permission name | Resource Type | Policy | Description |
|---|---|---|---|
|
|
named resource |
read |
Lists and reads all workflow definitions. Lists and reads their instances |
|
|
named resource |
read |
Lists and reads a specific workflow definition. Lists and reads instances created for this particular workflow. |
|
|
named resource |
update |
Runs or aborts any workflow. |
|
|
named resource |
update |
Runs or aborts a specific workflow. |
|
|
named resource |
read |
Views instance variables and the workflow definition editor. |
|
|
named resource |
read |
Views all workflow instances, including those created by other users. |
Generic permissions override specific denial policies within the same action type. To maintain granular control, avoid granting generic permissions if you intend to restrict specific workflows.
-
Granting
orchestrator.workflow(read) prevents you from denying access toorchestrator.workflow.[workflowId](read). -
Granting
orchestrator.workflow.use(update) prevents you from denying access toorchestrator.workflow.use.[workflowId](update).
The [workflowId] must match the unique identifier in your workflow definition file. For example, in the workflow definition below, the identifier is greeting:
id: greeting
version: '1.0'
specVersion: '0.8'
name: Greeting workflow
description: YAML based greeting workflow
annotations:
- 'workflow-type/infrastructure'
dataInputSchema: 'schemas/greeting.sw.input-schema.json'
extensions:
- extensionid: workflow-output-schema
outputSchema: schemas/workflow-output-schema.json10.3.15. Delegate RBAC management to decentralize administration
10.3.15.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.15.2. Configure RBAC delegation
10.3.15.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.15.2.2. Delegate access 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
- Log in to your RHDH instance with administrator credentials.
- Navigate to Administration → RBAC.
-
Click Create Role and define a new role for team leads, such as
role:default/team_lead. -
In the Members section, add the user or group, such as
user:default/team_lead. Grant permissions required by team leads, such as:
policy.entity.create- To allow policy creation.
catalog-entity:read- To allow catalog access.
Apply conditions to limit access as follows:
IS_OWNER-
Use the
IS_OWNERrule to ensure team leads can only manage resources they own.
- 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.15.2.3. Delegate access using the 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
curlor another tool.
Procedure
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" } }'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" } ]'To ensure team leads can only manage what they own, use the
IS_OWNERconditional rule as follows:For example, to apply a conditional access policy by using the
IS_OWNERrule 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.
Log in to RHDH as team lead and verify the following:
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"
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" } }'NoteYou can set the ownership during creation, but you can also update the ownership at any time.
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" } ]'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
Monitor, troubleshoot, and maintain your Developer Hub deployment by configuring system logs and application metrics, managing telemetry collection, reviewing audit logs, centralizing workflow observability, and collecting diagnostic data.
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
Monitor Developer Hub by configuring log levels, enabling metrics monitoring on OpenShift Container Platform, and setting up platform-specific monitoring with Amazon Prometheus or Azure Monitor.
11.2.2. Configure log levels
11.2.2.1. Configure log levels
Control the amount and type of information that Developer Hub writes to its logs by configuring the LOG_LEVEL environment variable using the Operator or Helm chart.
11.2.2.2. Configure the log level with the Red Hat Developer Hub Operator
Configure the application log level through the LOG_LEVEL environment variable by using the Red Hat Developer Hub Operator to control the minimum severity level of events that your application logs.
Prerequisites
- You have access to the Backstage custom resource (CR) used to deploy the application.
Procedure
Include the environment variable
LOG_LEVELin your Backstage CR. For example:spec: # Other fields omitted application: extraEnvs: envs: - name: LOG_LEVEL value: debugYou can use any of the values in the following table.
Table 11.1.
LOG_LEVELvalues in order of increasing severityValue Description debugDetailed information, typically useful only when troubleshooting.
infoGeneral information about the operation of the application. This is the default level.
warnPotential issues or situations that might require attention.
errorErrors that occurred during the operation but are not critical.
criticalUnrecoverable errors that must be addressed immediately to restore functionality.
11.2.2.3. Configure the log level with the Red Hat Developer Hub Helm chart
Configure the application log level through the LOG_LEVEL environment variable by using the Red Hat Developer Hub Helm chart to control the minimum severity level of events that your application logs.
Prerequisites
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Helm chart.
Procedure
Add
LOG_LEVELto your Helm chartvalues.yamlfile. For example:upstream: backstage: # --- Truncated --- extraEnvVars: - name: LOG_LEVEL value: debugYou can use any of the values in the following table.
Table 11.2.
LOG_LEVELvalues in order of increasing severityValue Description debugDetailed information, typically useful only when troubleshooting.
infoGeneral information about the operation of the application. This is the default level.
warnPotential issues or situations that might require attention.
errorErrors that occurred during the operation but are not critical.
criticalUnrecoverable errors that must be addressed immediately to restore functionality.
11.2.3. Enable metrics monitoring on OpenShift Container Platform
11.2.3.1. Enable metrics monitoring on OpenShift Container Platform
Enable metrics monitoring for Developer Hub on OpenShift Container Platform by creating a ServiceMonitor custom resource (CR) to scrape metrics from the /metrics service endpoint.
11.2.3.1.1. Additional resources
11.2.3.2. Enable metrics monitoring in a Red Hat Developer Hub Operator installation on an OpenShift Container Platform cluster
Enable and view metrics for an Operator-installed Red Hat Developer Hub instance from the OpenShift Container Platform web console by setting the spec.monitoring.enabled field in your custom resource (CR).
Prerequisites
- Your OpenShift Container Platform cluster has monitoring for user-defined projects enabled.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Red Hat Developer Hub Operator.
-
You have installed the OpenShift CLI (
oc).
Procedure
Use the OpenShift CLI (
oc) to edit your existing Red Hat Developer Hub CR.$ oc edit Backstage <instance_name>
In the CR, locate the
specfield and add themonitoringconfiguration block.spec: monitoring: enabled: trueSave the RHDH CR. The RHDH Operator detects the configuration and automatically creates the corresponding
ServiceMonitorcustom resource (CR).NoteThe Operator automatically configures the
ServiceMonitorwith the correct labels (app.kubernetes.io/instanceandapp.kubernetes.io/name) that match your Backstage CR. TheServiceMonitorwill be namedmetrics-<cr_name>. No additional label configuration is required.
Verification
- From the OpenShift Container Platform web console, select the Observe view.
- Click the Dashboard tab to view metrics for Red Hat Developer Hub pods.
-
From the OpenShift Container Platform web console, click Project > Services and verify the labels for
backstage-developer-hub.
11.2.3.3. Enable metrics monitoring in a Helm chart installation on an OpenShift Container Platform cluster
Enable and view metrics for a Red Hat Developer Hub Helm deployment from the OpenShift Container Platform web console by configuring metrics monitoring during a chart upgrade.
Prerequisites
- Your OpenShift Container Platform cluster has monitoring for user-defined projects enabled.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Helm chart.
Procedure
- From the OpenShift Container Platform web console, select the Topology view.
Click the overflow menu of the Red Hat Developer Hub Helm chart, and select Upgrade.

On the Upgrade Helm Release page, select the YAML view option in Configure via, then configure the
metricssection in the YAML, as shown in the following example:upstream: # ... metrics: serviceMonitor: enabled: true path: /metrics # ...- Click Upgrade.
Verification
- From the OpenShift Container Platform web console, select the Observe view.
- Click the Dashboard tab to view metrics for Red Hat Developer Hub pods.
11.2.4. Configure AWS monitoring
11.2.4.1. Configure AWS monitoring
Configure Developer Hub to use Amazon Prometheus for metrics monitoring and Amazon CloudWatch for logging when hosting on Amazon Web Services (AWS) infrastructure.
11.2.4.2. Configure annotations for monitoring with Amazon Prometheus by using the Red Hat Developer Hub Operator
Configure the required pod annotations by using the Red Hat Developer Hub Operator to enable monitoring with Amazon Prometheus.
Prerequisites
- You have configured Prometheus for your Elastic Kubernetes Service (EKS) clusters.
- You have created an Amazon managed service for the Prometheus workspace.
- You have configured Prometheus to import the Developer Hub metrics.
- You have ingested Prometheus metrics into the created workspace.
Procedure
As an administrator of the Red Hat Developer Hub Operator, edit the default configuration to add Prometheus annotations as follows:
# Update OPERATOR_NS accordingly $ OPERATOR_NS=rhdh-operator $ kubectl edit configmap backstage-default-config -n "${OPERATOR_NS}"Find the
deployment.yamlkey in the config map and add the annotations to thespec.template.metadata.annotationsfield as follows:deployment.yaml: |- apiVersion: apps/v1 kind: Deployment # --- truncated --- spec: template: # --- truncated --- metadata: labels: rhdh.redhat.com/app: # placeholder for 'backstage-<cr_name>' # --- truncated --- annotations: prometheus.io/scrape: 'true' prometheus.io/path: '/metrics' prometheus.io/port: '9464' prometheus.io/scheme: 'http' # --- truncated ---- Save your changes.
Verification
To verify if the scraping works:
Use
kubectlto port-forward the Prometheus console to your local machine as follows:$ kubectl --namespace=prometheus port-forward deploy/prometheus-server 9090
-
Open your web browser and navigate to
http://localhost:9090to access the Prometheus console. -
Monitor relevant metrics, such as
process_cpu_user_seconds_total.
11.2.4.3. Configure annotations for monitoring with Amazon Prometheus by using the Red Hat Developer Hub Helm chart
Configure the required pod annotations by using the Red Hat Developer Hub Helm chart to enable monitoring with Amazon Prometheus.
Prerequisites
- You have configured Prometheus for your Elastic Kubernetes Service (EKS) clusters.
- You have created an Amazon managed service for the Prometheus workspace.
- You have configured Prometheus to import the Developer Hub metrics.
- You have ingested Prometheus metrics into the created workspace.
Procedure
To annotate the backstage pod for monitoring, update your
values.yamlfile as follows:upstream: backstage: # --- TRUNCATED --- podAnnotations: prometheus.io/scrape: 'true' prometheus.io/path: '/metrics' prometheus.io/port: '9464' prometheus.io/scheme: 'http'
Verification
To verify if the scraping works:
Use
kubectlto port-forward the Prometheus console to your local machine as follows:$ kubectl --namespace=prometheus port-forward deploy/prometheus-server 9090
-
Open your web browser and navigate to
http://localhost:9090to access the Prometheus console. -
Monitor relevant metrics, such as
process_cpu_user_seconds_total.
11.2.4.4. Retrieve logs from Amazon CloudWatch
Retrieve and query logs from your Developer Hub instance by using Amazon CloudWatch Container Insights and Logs Insights.
Prerequisites
- CloudWatch Container Insights is used to capture logs and metrics for Amazon Elastic Kubernetes Service. For more information, see Logging for Amazon Elastic Kubernetes Service documentation.
- To capture the logs and metrics, install the Amazon CloudWatch Observability EKS add-on in your cluster. Following the setup of Container Insights, you can access container logs using Logs Insights or Live Tail views.
CloudWatch names the log group where all container logs are consolidated in the following manner:
/aws/containerinsights/<cluster_name>/application
Procedure
To retrieve logs from the Developer Hub instance, run a query such as:
fields @timestamp, @message, kubernetes.container_name | filter kubernetes.container_name in ["install-dynamic-plugins", "backstage-backend"]
11.2.5. Configure Azure monitoring
11.2.5.1. Configure Azure monitoring
Monitor resource utilization, diagnose issues, and collect logs for Developer Hub on Azure Kubernetes Service (AKS) by using Managed Prometheus Monitoring and Azure Monitor.
11.2.5.2. Enable Azure Monitor metrics
Enable managed Prometheus monitoring for your Azure Kubernetes Service (AKS) cluster to collect metrics and monitor Developer Hub performance through Azure Monitor.
Prerequisites
- You have an AKS cluster.
- You have the Azure CLI installed.
Procedure
To enable managed Prometheus monitoring, use the
--enable-azure-monitor-metricsoption with either theaz aks createoraz aks updatecommand:$ az aks create/update --resource-group <your_resource_group> --name <your_cluster> --enable-azure-monitor-metrics
This command installs the metrics add-on, which gathers Prometheus metrics.
Verification
- In the Azure portal, navigate to Monitoring → Insights to view the monitoring results. For more information, see Monitor Azure resources with Azure Monitor.
11.2.5.3. Configure annotations for AKS monitoring by using the Operator
Configure the pod annotations for monitoring Developer Hub specific metrics on Azure Kubernetes Service (AKS) by using the Red Hat Developer Hub Operator.
Procedure
As an administrator of the Operator, edit the default configuration to add Prometheus annotations:
# Update OPERATOR_NS accordingly OPERATOR_NS=rhdh-operator $ kubectl edit configmap backstage-default-config -n "${OPERATOR_NS}"Find the
deployment.yamlkey in the ConfigMap and add the annotations to thespec.template.metadata.annotationsfield:deployment.yaml: |- apiVersion: apps/v1 kind: Deployment # --- truncated --- spec: template: # --- truncated --- metadata: labels: rhdh.redhat.com/app: # placeholder for 'backstage-<cr_name>' # --- truncated --- annotations: prometheus.io/scrape: 'true' prometheus.io/path: '/metrics' prometheus.io/port: '9464' prometheus.io/scheme: 'http' # --- truncated ---- Save your changes.
Verification
- Navigate to the corresponding Azure Monitor Workspace and view the metrics under Monitoring → Metrics.
11.2.5.4. Configure annotations for AKS monitoring by using the Helm chart
Configure the pod annotations for monitoring Developer Hub specific metrics on Azure Kubernetes Service (AKS) by using the Helm chart.
Procedure
Update your
values.yamlfile to annotate the backstage pod for monitoring:upstream: backstage: # --- TRUNCATED --- podAnnotations: prometheus.io/scrape: 'true' prometheus.io/path: '/metrics' prometheus.io/port: '9464' prometheus.io/scheme: 'http'
Verification
- Navigate to the corresponding Azure Monitor Workspace and view the metrics under Monitoring → Metrics.
11.2.5.5. View live logs with Azure Kubernetes Service (AKS)
Access live data logs generated by Kubernetes objects for your Developer Hub instance on AKS.
Prerequisites
- You have deployed Developer Hub on AKS.
For more information, see Installing Red Hat Developer Hub on Microsoft Azure Kubernetes Service (AKS).
Procedure
- Navigate to the Azure Portal.
-
Search for the resource group
<your_resource_group>and locate your AKS cluster<your_cluster>. - Select Kubernetes resources → Workloads from the menu.
-
Select the
<your_rhdh_cr>-developer-hub(in case of Helm Chart installation) or<your_rhdh_cr>-backstage(in case of Operator-backed installation) deployment. - Click Live Logs in the left menu.
Select the pod.
NoteThere must be only single pod.
Verification
- Live log data is collected and displayed.
11.2.5.6. View real-time log data with Azure Kubernetes Service (AKS)
View real-time log data from the Container Engine for your Developer Hub instance on AKS.
Prerequisites
- You have deployed Developer Hub on AKS.
For more information, see Installing Red Hat Developer Hub on Microsoft Azure Kubernetes Service (AKS).
Procedure
- Navigate to the Azure Portal.
-
Search for the resource group
<your_resource_group>and locate your AKS cluster<your_cluster>. - Select Monitoring → Insights from the menu.
- Go to the Containers tab.
- Find the backend-backstage container and click it to view real-time log data as it is generated by the Container Engine.
11.3. Manage telemetry collection to balance data insights with privacy requirements
11.3.1. Telemetry data collection and analysis
Red Hat Developer Hub collects and analyzes telemetry data by default to improve your experience.
Red Hat collects and analyzes the following data:
- Web Analytics
Web Analytics use the Segment tool. It is the tracking of user behavior and interactions with Red Hat Developer Hub. Specifically, it tracks the following:
- Events of page visits and clicks on links or buttons.
- System-related information, for example, locale, time zone, user agent including browser and operating system details.
- Page-related information, for example, title, category, extension name, URL, path, referrer, and search parameters.
-
Anonymous IP addresses, recorded as
0.0.0.0. - Anonymous username hashes, which are unique identifiers used solely to identify the number of unique users of the RHDH application.
- System Observability
System Observability uses the OpenTelemetry tool. It is the tracking of the performance of the RHDH. Specifically, it tracks the following metrics:
- Key system metrics such as CPU usage, memory usage, and other performance indicators.
- Information about system components, such as the locale, time zone, and user agent (including details of the browser and operating system).
- Traces and logs monitor system processes, allowing you to troubleshoot potential issues impacting the performance of RHDH.
With RHDH, you can customize the Web Analytics and System Observability configuration based on your needs.
11.3.2. Disable telemetry collection
11.3.2.1. Disable telemetry collection
You can disable telemetry data collection by disabling the analytics-provider-segment plugin. Use either the Helm chart or the Red Hat Developer Hub Operator.
For example, in an air-gapped environment, you can disable this feature to avoid outbound requests that affect the responsiveness of the RHDH application.
11.3.2.2. Disable telemetry data collection using the Operator
You can disable the telemetry data collection feature by using the Operator.
Prerequisites
- You have logged in as an administrator in the OpenShift Container Platform web console.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Operator.
Procedure
- Perform one of the following steps:
-
If you have created the
dynamic-plugins-rhdhConfigMap file and not configured theanalytics-provider-segmentplugin, add the plugin to the list of plugins and set itsplugins.disabledparameter totrue. -
If you have created the
dynamic-plugins-rhdhConfigMap file and configured theanalytics-provider-segmentplugin, search the plugin in the list of plugins and set itsplugins.disabledparameter totrue. If you have not created the ConfigMap file, create it with the following YAML code:
kind: ConfigMap apiVersion: v1 metadata: name: dynamic-plugins-rhdh data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: './dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment' disabled: trueSet the value of the
dynamicPluginsConfigMapNameparameter to the name of yourdynamic-plugins-rhdhconfig map in yourBackstagecustom resource:# ... spec: application: dynamicPluginsConfigMapName: dynamic-plugins-rhdh # ...- Save the configuration changes.
11.3.2.3. Disable telemetry data collection using the Helm chart
You can disable the telemetry data collection feature by using the Helm chart.
Prerequisites
- You have logged in as an administrator in the OpenShift Container Platform web console.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Helm chart.
Procedure
- In the Developer perspective of the OpenShift Container Platform web console, go to the Helm view to see the list of Helm releases.
Click the overflow menu on the Helm release that you want to use and select Upgrade.
NoteYou can also create a new Helm release by clicking the Create button and edit the configuration to disable telemetry.
Use either the Form view or YAML view to edit the Helm configuration:
Using Form view
- Expand Root Schema → global → Dynamic plugins configuration. → List of dynamic plugins that should be installed in the backstage application.
- Click the Add list of dynamic plugins that should be installed in the backstage application. link.
Perform one of the following steps:
If you have not configured the plugin, add the following value in the Package specification of the dynamic plugin to install. It should be usable by the npm pack command. field:
./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment
-
If you have configured the plugin, find the Package specification of the dynamic plugin to install. It should be usable by the npm pack command. field with the
./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segmentvalue.
- Select the Disable the plugin checkbox.
- Click Upgrade.
Using YAML view
Perform one of the following steps:
If you have not configured the plugin, add the following YAML code in your
values.yamlHelm configuration file:# ... global: dynamic: plugins: - package: './dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment' disabled: true # ...-
If you have configured the plugin, search it in your Helm configuration and set the value of the
plugins.disabledparameter totrue.
- Click Upgrade.
11.3.3. Enable telemetry collection
11.3.3.1. Enable telemetry collection
Red Hat Developer Hub enables the telemetry data collection feature by default. However, if you have disabled the feature and want to re-enable it, you must enable the analytics-provider-segment plugin by using the Helm chart or the Red Hat Developer Hub Operator configuration.
11.3.3.2. Enable telemetry data collection using the Operator
You can enable the telemetry data collection feature by using the Operator.
Prerequisites
- You have logged in as an administrator in the OpenShift Container Platform web console.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Operator.
Procedure
- Perform one of the following steps:
-
If you have created the
dynamic-plugins-rhdhConfigMap file and not configured theanalytics-provider-segmentplugin, add the plugin to the list of plugins and set itsplugins.disabledparameter tofalse. -
If you have created the
dynamic-plugins-rhdhConfigMap file and configured theanalytics-provider-segmentplugin, search the plugin in the list of plugins and set itsplugins.disabledparameter tofalse. If you have not created the ConfigMap file, create it with the following YAML code:
kind: ConfigMap apiVersion: v1 metadata: name: dynamic-plugins-rhdh data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: './dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment' disabled: falseSet the value of the
dynamicPluginsConfigMapNameparameter to the name of yourdynamic-plugins-rhdhconfig map in yourBackstagecustom resource:# ... spec: application: dynamicPluginsConfigMapName: dynamic-plugins-rhdh # ...- Save the configuration changes.
11.3.3.3. Enable telemetry data collection using the Helm chart
You can enable the telemetry data collection feature by using the Helm chart.
Prerequisites
- You have logged in as an administrator in the OpenShift Container Platform web console.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Helm chart.
Procedure
- In the Developer perspective of the OpenShift Container Platform web console, go to the Helm view to see the list of Helm releases.
Click the overflow menu on the Helm release that you want to use and select Upgrade.
NoteYou can also create a new Helm release by clicking the Create button and edit the configuration to enable telemetry.
Use either the Form view or YAML view to edit the Helm configuration:
Using Form view
- Expand Root Schema → global → Dynamic plugins configuration. → List of dynamic plugins that should be installed in the backstage application.
- Click the Add list of dynamic plugins that should be installed in the backstage application. link.
Perform one of the following steps:
If you have not configured the plugin, add the following value in the Package specification of the dynamic plugin to install. It should be usable by the npm pack command. field:
./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment-
If you have configured the plugin, find the Package specification of the dynamic plugin to install. It should be usable by the npm pack command. field with the
./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segmentvalue.
- Clear the Disable the plugin checkbox.
- Click Upgrade.
Using YAML view
Perform one of the following steps:
If you have not configured the plugin, add the following YAML code in your Helm configuration file:
# ... global: dynamic: plugins: - package: './dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment' disabled: false # ...-
If you have configured the plugin, search it in your Helm configuration and set the value of the
plugins.disabledparameter tofalse.
- Click Upgrade.
11.3.4. Customize the Segment source
11.3.4.1. Customize the Segment source
The analytics-provider-segment plugin sends the collected web analytics data to Red Hat by default. However, you can configure a new Segment source that receives web analytics data based on your needs. For configuration, you need a unique Segment write key that points to the Segment source.
Create your own web analytics data collection notice for your application users.
11.3.4.2. Customize Segment source using the Operator
You can configure integration with your Segment source by using the Red Hat Developer Hub Operator.
Prerequisites
- You have logged in as an administrator in the OpenShift Container Platform web console.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Operator.
Procedure
Add the following YAML code in your
Backstagecustom resource (CR):# ... spec: application: extraEnvs: envs: - name: SEGMENT_WRITE_KEY value: <segment_key> # ...Replace
<segment_key>with a unique identifier for your Segment source.- Save the configuration changes.
11.3.4.3. Customize Segment source using the Helm chart
You can configure integration with your Segment source by using the Red Hat Developer Hub Helm chart.
Prerequisites
- You have logged in as an administrator in the OpenShift Container Platform web console.
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Helm chart.
Procedure
- In the Developer perspective of the OpenShift Container Platform web console, go to the Helm view to see the list of Helm releases.
- Click the overflow menu on the Helm release that you want to use and select Upgrade.
Use either the Form view or YAML view to edit the Helm configuration:
Using Form view
- Expand Root Schema → Backstage Chart Schema → Backstage Parameters → Backstage container environment variables.
- Click the Add Backstage container environment variables link.
Enter the name and value of the Segment key.

- Click Upgrade.
Using YAML view
Add the following YAML code in your Helm configuration file:
# ... upstream: backstage: extraEnvVars: - name: SEGMENT_WRITE_KEY value: <segment_key> # ...Replace
<segment_key>with a unique identifier for your Segment source.- Click Upgrade.
11.4. Capture and review audit logs to trace user activities and maintain accountability
11.4.1. Audit logs overview
Audit logs are a chronological set of records documenting the user activities, system events, and data changes that affect your Red Hat Developer Hub users, administrators, or components.
Administrators can view Developer Hub audit logs in the OpenShift Container Platform web console to monitor scaffolder events, changes to the RBAC system, and changes to the Catalog database. Audit logs include the following information:
- Name of the audited event
- Actor that triggered the audited event, for example, terminal, port, IP address, or hostname
- Event metadata, for example, date, time
-
Event status, for example,
success,failure -
Severity levels, for example,
info,debug,warn,error
You can use the information in the audit log to achieve the following goals:
- Enhance security
- Trace activities, including those initiated by automated systems and software templates, back to their source. Know when software templates are executed, and the details of application and component installations, updates, configuration changes, and removals.
- Automate compliance
- Use streamlined processes to view log data for specified points in time for auditing purposes or continuous compliance maintenance.
- Debug issues
- Use access records and activity details to fix issues with software templates or plugins.
Audit logs are not forwarded to the internal log store by default because the internal log store does not offer secure storage. You are responsible for ensuring that the system to which you forward audit logs is compliant with your organizational and governmental regulations, and is properly secured.
11.4.2. Configure audit logs for Developer Hub on OpenShift Container Platform
Configure logging deployment, log collector, and log forwarding components to enable audit logging for Developer Hub on OpenShift Container Platform.
Prerequisites
- You have access to the OpenShift Container Platform web console.
-
You have
cluster-adminprivileges.
Procedure
Configure the logging deployment, including both the CPU and memory limits for each logging component.
For more information, see Red Hat OpenShift Container Platform - Configuring your Logging deployment.
To configure the logging collector, configure the
spec.collectionstanza in theClusterLoggingcustom resource (CR) to use a supported modification to the log collector and collect logs fromSTDOUT.For more information, see Red Hat OpenShift Container Platform - Configuring the logging collector.
To configure log forwarding, send logs to specific endpoints inside and outside your OpenShift Container Platform cluster by specifying a combination of outputs and pipelines in a
ClusterLogForwarderCR.For more information, see Red Hat OpenShift Container Platform - Enabling JSON log forwarding and Red Hat OpenShift Container Platform - Configuring log forwarding.
11.4.3. Forward Red Hat Developer Hub audit logs to Splunk
Forward audit logs from Developer Hub to Splunk by using the OpenShift Logging Operator and a ClusterLogForwarder instance.
Prerequisites
- You have a cluster running on a supported OpenShift Container Platform version.
-
You have an account with
cluster-adminprivileges. - You have a Splunk Cloud account or Splunk Enterprise installation.
Procedure
- Log in to your OpenShift Container Platform cluster.
Install the OpenShift Logging Operator in the
openshift-loggingnamespace and switch to the namespace:$ oc project openshift-logging
Create a
serviceAccountnamedlog-collector:$ oc create sa log-collector
Bind the
collect-application-logsrole to theserviceAccount:$ oc create clusterrolebinding log-collector --clusterrole=collect-application-logs --serviceaccount=openshift-logging:log-collector
-
Generate a
hecTokenin your Splunk instance. Create a key/value secret in the
openshift-loggingnamespace and verify the secret:$ oc -n openshift-logging create secret generic splunk-secret --from-literal=hecToken=<HEC_Token>
$ oc -n openshift-logging get secret/splunk-secret -o yaml
Create a basic `ClusterLogForwarder`resource YAML file as follows:
apiVersion: logging.openshift.io/v1 kind: ClusterLogForwarder metadata: name: instance namespace: openshift-logging
For more information, see Creating a log forwarder.
Define the following
ClusterLogForwarderconfiguration using OpenShift web console or OpenShift CLI:Specify the
log-collectorasserviceAccountin the YAML file:serviceAccount: name: log-collector
Configure
inputsto specify the type and source of logs to forward. The following configuration enables the forwarder to capture logs from all applications in a provided namespace:inputs: - name: my-app-logs-input type: application application: includes: - namespace: my-rhdh-project containerLimit: maxRecordsPerSecond: 100For more information, see Forwarding application logs from specific pods.
Configure outputs to specify where to send the captured logs. In this step, focus on the
splunktype. You can either use thetls.insecureSkipVerifyoption if the Splunk endpoint uses self-signed TLS certificates (not recommended) or supply the certificate chain by using a Secret.outputs: - name: splunk-receiver-application type: splunk splunk: authentication: token: key: hecToken secretName: splunk-secret index: main url: 'https://my-splunk-instance-link' rateLimit: maxRecordsPerSecond: 250For more information, see Forwarding logs to Splunk in OpenShift Container Platform documentation.
Optional: Filter logs to include only audit logs:
filters: - name: audit-logs-only type: drop drop: - test: - field: .message notMatches: isAuditEventFor more information, see Filtering logs by content in OpenShift Container Platform documentation.
Configure pipelines to route logs from specific inputs to designated outputs. Use the names of the defined inputs and outputs to specify
inputRefsandoutputRefsin each pipeline:pipelines: - name: my-app-logs-pipeline detectMultilineErrors: true inputRefs: - my-app-logs-input outputRefs: - splunk-receiver-application filterRefs: - audit-logs-only
Run the following command to apply the
ClusterLogForwarderconfiguration:$ oc apply -f <ClusterLogForwarder-configuration.yaml>
Optional: To reduce the risk of log loss, configure your
ClusterLogForwarderpods using the following options:Define the resource requests and limits for the log collector as follows:
collector: resources: requests: cpu: 250m memory: 64Mi ephemeral-storage: 250Mi limits: cpu: 500m memory: 128Mi ephemeral-storage: 500MiDefine
tuningoptions for log delivery, includingdelivery,compression, andRetryDuration. You can apply tuning per output as needed.tuning: delivery: AtLeastOnce compression: none minRetryDuration: 1s maxRetryDuration: 10s
AtLeastOnce-
The
AtLeastOncedelivery mode ensures that if the log forwarder crashes or restarts, the forwarder re-sends any logs read but not yet delivered to their destination. The forwarder might duplicate some logs after a crash.
Verification
- Verify that your Splunk instance receives logs by viewing them in the Splunk dashboard.
- Troubleshoot any issues using OpenShift Container Platform and Splunk logs as needed.
11.4.4. View audit logs in Developer Hub
You can view, search, filter, and manage audit log data directly from the Red Hat OpenShift Container Platform web console. To isolate these logs from other data types, filter your results by using the isAuditEvent field.
Prerequisites
- You are logged in as an administrator in the OpenShift Container Platform web console.
Procedure
- From the Developer perspective of the OpenShift Container Platform web console, click the Topology tab.
- From the Topology view, click the pod that you want to view audit log data for.
- From the pod panel, click the Resources tab.
- From the Pods section of the Resources tab, click View logs.
-
From the Logs view, enter
isAuditEventinto the Search field to filter audit logs from other log types. You can use the arrows to browse the logs containing theisAuditEventfield.
11.4.5. Review RBAC audit log events
The Role-Based Access Control (RBAC) backend plugin in Red Hat Developer Hub provides audit logging to track administrative changes, permission evaluations, and policy updates.
Administrators can use these logs to monitor who performed an action, when it occurred, and the outcome of the operation. Each audit log entry includes an eventId that represents a logical group of actions.
11.4.5.1. RBAC audit log events
role-write- Tracks the creation, modification, or removal of RBAC roles via the REST API, CSV file, or configuration.
role-read- Tracks requests to retrieve information about one or all existing RBAC roles.
policy-write- Tracks when permission policies are created, updated, or deleted.
policy-read- Tracks requests to retrieve or list defined permission policies.
condition-write- Tracks when conditional policies (logic-based rules) are modified via YAML or API.
condition-read- Tracks requests to retrieve conditional policy definitions.
permission-evaluation-
Tracks when the RBAC system evaluates a user’s identity against policies to
allowordenyan action on a resource. plugin-policies-read- Tracks requests to list the available permission policies supported by installed plugins.
plugin-ids-write- Tracks updates to the list of plugins that are integrated with the permission framework.
11.4.5.2. RBAC audit log metadata fields
RBAC audit logs contain a meta object with event-specific details:
source-
The origin of the event, such as
rest,csv-file,configuration, orexternalProviderPluginId. actionType-
The specific operation performed:
create,update,delete, orcreate_or_update. roleEntityRef- The entity reference of the specific role affected by the event.
members- A list of users or groups associated with the role when the event occurs.
decision-
In evaluation events, indicates the policy decision:
allowordeny. result-
The final outcome of a permission check, such as
AuthorizeResult.
11.4.5.3. Example audit log entries
The following examples show how RBAC events appear in the Developer Hub logs.
An RBAC role creation event with status="initiated":
[backend]: 2025-03-25T17:24:17.438Z permission info permission.role-write isAuditEvent=true eventId="role-write" severityLevel="medium" actor={"actorId":"user:default/admin","ip":"::1"} request={"url":"/api/permission/roles","method":"POST"} meta={"actionType":"create", "source":"rest"} status="initiated"
An RBAC role creation event with status="succeeded":
[backend]: 2025-03-25T17:24:17.458Z permission info permission.role-write isAuditEvent=true eventId="role-write" severityLevel="medium" actor={"actorId":"user:default/admin"} request={"url":"/api/permission/roles","method":"POST"} meta={"actionType":"create", "source":"rest","roleEntityRef":"role:default/test-role"} status="succeeded"11.5. Centralize workflow observability
11.5.1. Centralize workflow observability
Monitor and troubleshoot serverless workflows by deploying observability manifests, diagnosing failures with centralized logging, optimizing performance with distributed tracing, and filtering workflow data by trace attributes.
11.5.2. Apply deployment manifests
11.5.2.1. Apply deployment manifests
Deploy a complete observability stack for SonataFlow workflows with ready-to-use Jaeger and Loki manifests. These pre-configured examples help you monitor workflow performance and logs immediately without manual setup.
11.5.2.2. Jaeger distributed tracing deployment manifests
Deploy Jaeger to visualize distributed traces from SonataFlow workflows. Use these manifests to set up trace collection with pre-configured OTLP endpoints and resource limits for development or production environments.
Jaeger provides distributed tracing visualization for SonataFlow workflows.
apiVersion: v1
kind: Namespace
metadata:
name: jaeger-system
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jaeger
namespace: jaeger-system
labels:
app: jaeger
spec:
replicas: 1
selector:
matchLabels:
app: jaeger
template:
metadata:
labels:
app: jaeger
spec:
containers:
- name: jaeger
image: jaegertracing/all-in-one:1.59
env:
- name: COLLECTOR_OTLP_ENABLED
value: "true"
ports:
- containerPort: 16686
name: query
- containerPort: 4317
name: otlp-grpc
- containerPort: 4318
name: otlp-http
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
readinessProbe:
httpGet:
path: /
port: 14269
initialDelaySeconds: 5
livenessProbe:
httpGet:
path: /
port: 14269
initialDelaySeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: jaeger-collector
namespace: jaeger-system
labels:
app: jaeger
spec:
selector:
app: jaeger
ports:
- name: otlp-grpc
port: 4317
targetPort: 4317
- name: otlp-http
port: 4318
targetPort: 4318
type: ClusterIP
---
apiVersion: v1
kind: Service
metadata:
name: jaeger-query
namespace: jaeger-system
labels:
app: jaeger
spec:
selector:
app: jaeger
ports:
- name: query-http
port: 16686
targetPort: 16686
type: ClusterIPapiVersion: route.openshift.io/v1
kind: Route
metadata:
name: jaeger-query
namespace: jaeger-system
spec:
to:
kind: Service
name: jaeger-query
port:
targetPort: query-http
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect
Add these properties to the application.properties file of your workflow:
# Direct connection to Jaeger quarkus.otel.exporter.otlp.endpoint=http://jaeger-collector.jaeger-system.svc.cluster.local:4317 quarkus.otel.exporter.otlp.protocol=grpc quarkus.otel.traces.exporter=cdi # Additional Jaeger-specific propagation quarkus.otel.propagators=tracecontext,baggage,jaeger
For production environments, use the Jaeger Operator with Elasticsearch storage:
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: jaeger-production
namespace: observability
spec:
strategy: production
storage:
type: elasticsearch
elasticsearch:
nodeCount: 3
storage:
storageClassName: gp3
size: 50Gi
resources:
requests:
cpu: 500m
memory: 4Gi
limits:
cpu: 1000m
memory: 8Gi
collector:
replicas: 2
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi11.5.2.3. Loki log aggregation deployment manifests
Deploy Loki to aggregate logs from SonataFlow workflows using OpenTelemetry Protocol. These manifests include pre-configured OTLP settings, structured metadata support, and resource limits for immediate log collection.
Loki supports OpenTelemetry Protocol (OTLP) for direct log ingestion from SonataFlow workflows.
apiVersion: v1
kind: ConfigMap
metadata:
name: loki-config
namespace: observability
data:
loki-config.yaml: |
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /loki
storage:
filesystem:
chunks_directory: /loki/chunks
rules_directory: /loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
distributor:
otlp_config:
# Default resource attributes as index labels
default_resource_attributes_as_index_labels:
- service.name
- service.namespace
- deployment.environment
- k8s.namespace.name
- k8s.cluster.name
limits_config:
# Enable structured metadata (default in Loki 3.0+)
allow_structured_metadata: true
# Maximum number of index labels per stream
max_label_names_per_series: 15
schema_config:
configs:
- from: 2024-01-01
store: tsdb
object_store: filesystem
schema: v13 # Required for OTLP support
index:
prefix: index_
period: 24hapiVersion: apps/v1
kind: Deployment
metadata:
name: loki
namespace: observability
labels:
app: loki
spec:
replicas: 1
selector:
matchLabels:
app: loki
template:
metadata:
labels:
app: loki
spec:
securityContext:
fsGroup: 10001
runAsUser: 10001
runAsNonRoot: true
containers:
- name: loki
image: grafana/loki:3.0.0
args:
- -config.file=/etc/loki/loki-config.yaml
ports:
- containerPort: 3100
name: http-metrics
- containerPort: 9096
name: grpc
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
volumeMounts:
- name: config
mountPath: /etc/loki
- name: storage
mountPath: /loki
livenessProbe:
httpGet:
path: /ready
port: 3100
initialDelaySeconds: 45
readinessProbe:
httpGet:
path: /ready
port: 3100
initialDelaySeconds: 45
volumes:
- name: config
configMap:
name: loki-config
- name: storage
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: loki
namespace: observability
labels:
app: loki
spec:
selector:
app: loki
ports:
- name: http-metrics
port: 3100
targetPort: 3100
- name: grpc
port: 9096
targetPort: 9096
type: ClusterIPTo route logs to Loki and traces to Jaeger, use the following configuration:
# OpenTelemetry Configuration
quarkus.otel.enabled=true
quarkus.otel.traces.enabled=true
quarkus.otel.metrics.enabled=true
quarkus.otel.logs.enabled=true
# OTLP Exporter - Send logs to Loki, traces to Jaeger
quarkus.otel.exporter.otlp.logs.endpoint=http://loki.observability.svc.cluster.local:3100/otlp
quarkus.otel.exporter.otlp.traces.endpoint=http://jaeger-collector.observability.svc.cluster.local:4317
quarkus.otel.exporter.otlp.protocol=grpc
# JSON Logging for better structure
quarkus.log.console.json=true
quarkus.log.console.json.pretty-print=false
# Include trace correlation in logs
quarkus.log.console.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) traceId=%X{traceId}, spanId=%X{spanId} %s%e%n
# Resource attributes for Loki labels
quarkus.otel.resource.attributes=\
service.name=greeting-workflow,\
service.namespace=workflows,\
deployment.environment=production11.5.2.4. OpenTelemetry Collector deployment manifest
Deploy an OpenTelemetry Collector to route workflow telemetry to multiple backends. Use this intermediate layer for advanced log filtering, processing, and multi-destination export beyond direct workflow integration.
Deploy an OpenTelemetry collector between workflows and backends for advanced log processing, filtering, and multi-destination export.
# Collector routes to both Jaeger and Loki
exporters:
otlp/jaeger:
endpoint: jaeger-collector:4317
otlphttp/loki:
endpoint: http://loki:3100/otlp
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlp/jaeger]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp/loki]11.5.3. Diagnose workflow failures using centralized logging
11.5.3.1. Diagnose workflow failures using centralized logging
Search all workflow logs from a single dashboard in Red Hat Developer Hub to diagnose failures quickly. Use structured logging to connect process instances with traces and set up automated alerts for workflow failures.
11.5.3.2. Enable JSON logging to search logs instantly without manual parsing
Output logs as JSON instead of plain text so log platforms can automatically filter by process instance, error level, or trace ID. Structured logging eliminates manual parsing and enables instant searches across millions of log entries.
SonataFlow workflows support structured JSON logging with automatic process instance correlation through:
-
Process instance context: Automatic
processInstanceIdcorrelation in all log entries - Structured format: JSON logs optimized for machine processing and aggregation
- Multi-tenancy support: Log isolation by workflow and process instance
Prerequisites
- You have deployed SonataFlow workflow by using the SonataFlow Operator on OpenShift or Kubernetes.
-
You have included the
io.quarkus:quarkus-logging-jsonextension in your workflowQUARKUS_EXTENSIONSenvironment variable. -
You have
cluster-adminpermissions for deploying log aggregation stack.
Procedure
Update your workflow build configuration to include the JSON logging extension:
export QUARKUS_EXTENSIONS="${QUARKUS_EXTENSIONS},io.quarkus:quarkus-logging-json"-
Open the
{workflow-name}-propsConfigMap for your workflow. Add the following properties to the
application.propertiessection:# Enable JSON logging with Quarkus JSON logging extension quarkus.log.console.json=true quarkus.log.console.json.pretty-print=false # Include all MDC context fields in JSON output # - processInstanceId: Set automatically by SonataFlow/Kogito # - traceId, spanId: Set by Quarkus OpenTelemetry (requires quarkus.otel.enabled=true) quarkus.log.console.json.print-details=true # Set log levels for workflow components quarkus.log.category."org.kie.kogito".level=DEBUG quarkus.log.category."io.serverlessworkflow".level=INFO # Optional: Enable additional context logging quarkus.log.category."org.kie.kogito.services.context".level=DEBUG
Save the ConfigMap and restart the workflow pod.
The following is an example of a workflow ConfigMap with an enabled JSON logging:
apiVersion: v1 kind: ConfigMap metadata: name: greetings-props namespace: sonataflow-infra data: application.properties: | # JSON logging configuration quarkus.log.console.json=true quarkus.log.console.json.pretty-print=false quarkus.log.console.json.print-details=true # Log levels quarkus.log.category."org.kie.kogito".level=DEBUG quarkus.log.category."io.serverlessworkflow".level=INFO
Verification
Check the pod logs to verify the JSON format and the presence of the
processInstanceId:oc logs <workflow_pod_name> | grep processInstanceId
{"timestamp":"...","level":"INFO","message":"...","mdc":{"processInstanceId":"abc-123-..."}}
If the Mapped Diagnostic Context (MDC) fields are empty, verify the following:
- The workflow has processed at least one instance.
- The SonataFlow version matches the required configuration for MDC propagation.
11.5.3.3. Rotate logs automatically to prevent pod crashes from full disks
Automatically archive old logs before the disk fills up and crashes your workflow pods. Log rotation keeps recent logs available for debugging while preventing storage from becoming a production incident.
When using file-based logging in Kubernetes, mount the log directory to a volume to prevent data loss or pod instability.
Prerequisites
-
You have configured a shared Kubernetes volume in the
SonataFlowcustom resource. - Your workflow image includes the JSON logging extension.
Procedure
Add the following properties to the workflow ConfigMap to enable file-based JSON output:
quarkus.log.file.enable=true quarkus.log.file.path=/var/log/sonataflow/workflow.log quarkus.log.file.json=true
Configure log rotation settings to manage disk usage:
quarkus.log.file.rotation.max-file-size=10M quarkus.log.file.rotation.max-backup-index=5 quarkus.log.file.rotation.rotate-on-boot=true
This configuration does the following:
- Rotates logs when they reach 10MB
- Keeps up to 5 backup files
- Adds date suffix to rotated files
- Rotates on application startup
Set log level for file output:
quarkus.log.file.level=INFO
Update the
SonataFlowcustom resource (CR) to mount the volume at the log path:spec: podTemplate: container: volumeMounts: - name: shared-logs mountPath: /var/log/sonataflow volumes: - name: shared-logs emptyDir: sizeLimit: 500MiAfter applying the configuration, restart your workflow pod and check the log output:
# Get workflow pod name oc get pods -n sonataflow-infra -l sonataflow.org/workflow-app=your-workflow # Check logs for JSON format oc logs -n sonataflow-infra your-workflow-pod-name | head -5
Verification
Access the workflow container and verify the log file exists and is receiving JSON data:
oc exec <pod_name> -- ls -l /var/log/sonataflow/workflow.log
Verify that the file contains JSON data:
oc exec <pod_name> -- head -n 5 /var/log/sonataflow/workflow.log
11.5.3.4. Link logs to traces for complete failure diagnosis
Click a trace ID in any log entry to see the complete timeline of what happened across all services. Log-to-trace correlation turns a single error message into a full execution diagram showing every step and service call.
Prerequisites
- You have deployed an OpenTelemetry-compliant collector (for example, Jaeger) in the cluster.
-
You have set
quarkus.log.console.json.print-details=truetotrue.
Procedure
Add the OpenTelemetry exporter and service identification properties to your workflow ConfigMap:
# Enable OpenTelemetry integration quarkus.otel.enabled=true quarkus.otel.exporter.otlp.traces.endpoint=http://jaeger-collector:4317 quarkus.otel.service.name=${workflow.name}Set the resource attributes to filter traces in your observability dashboard:
quarkus.otel.resource.attributes=service.namespace=sonataflow-infra
- Restart the workflow pod to apply the new configuration.
Verification
- Trigger a workflow execution.
Check the logs for trace identifiers:
oc logs <pod_name> | grep traceId
-
Make sure the
mdcblock in the JSON output containstraceIdandspanIdfields with non-empty values.
11.5.3.5. Centralize logs for workflow troubleshooting
Query logs from all workflow pods in your Red Hat Developer Hub cluster using a single Grafana dashboard. Centralized logging allows you to search by process ID, error type, or time range from a browser.
Prerequisites
- You have running Loki and Grafana instances in the cluster.
- You have configured workflow for file-based JSON logging.
-
You have
cluster-adminpermissions.
Procedure
Deploy the PLG stack by using Helm:
# Add Grafana Helm repository helm repo add grafana https://grafana.github.io/helm-charts helm repo update # Create namespace oc new-project sonataflow-observability # Deploy Loki stack helm install loki-stack grafana/loki-stack \ --namespace sonataflow-observability \ --set loki.persistence.enabled=true \ --set loki.persistence.size=20Gi \ --set promtail.config.logLevel=info \ --set grafana.enabled=true
NoteFor production deployments, use a custom
values.yamlfile with appropriate resource limits and security contexts.Create a ConfigMap for the Promtail sidecar by selecting the configuration that matches your logging method:
Scrape container stdout
Use this configuration to collect logs from container
stdoutby using Kubernetes service discovery:apiVersion: v1 kind: ConfigMap metadata: name: promtail-config namespace: sonataflow-observability data: config.yml: | server: http_listen_port: 3101 clients: - url: http://loki:3100/loki/api/v1/push scrape_configs: - job_name: sonataflow-workflows kubernetes_sd_configs: - role: pod namespaces: names: ["sonataflow-infra"] relabel_configs: - source_labels: [__meta_kubernetes_pod_label_sonataflow_org_workflow_app] action: keep regex: (.+) - source_labels: [__meta_kubernetes_pod_name] target_label: pod - source_labels: [__meta_kubernetes_pod_label_sonataflow_org_workflow_app] target_label: workflow pipeline_stages: - json: expressions: timestamp: timestamp level: level logger: logger message: message processInstanceId: mdc.processInstanceId traceId: mdc.traceId spanId: mdc.spanId - labels: level: logger: processInstanceId: traceId:Scrape JSON log files
If you use
[file-based JSON logging](#file-based-json-logging), configure Promtail to read from the shared log volume:apiVersion: v1 kind: ConfigMap metadata: name: promtail-sidecar-config namespace: sonataflow-infra data: config.yml: | server: http_listen_port: 3101 clients: - url: http://loki.sonataflow-observability.svc.cluster.local:3100/loki/api/v1/push positions: filename: /var/log/positions.yaml scrape_configs: - job_name: sonataflow-json-files static_configs: - targets: - localhost labels: job: sonataflow-workflows __path__: /var/log/sonataflow/*.log pipeline_stages: - json: expressions: timestamp: timestamp level: level logger: loggerName message: message processInstanceId: mdc.processInstanceId traceId: mdc.traceId spanId: mdc.spanId - labels: level: logger: processInstanceId: traceId: - timestamp: source: timestamp format: RFC3339Nano
Add the Promtail sidecar container to your
SonataFlowcustom resource:apiVersion: sonataflow.org/v1alpha08 kind: SonataFlow metadata: name: my-workflow namespace: sonataflow-infra spec: podTemplate: container: volumeMounts: - name: shared-logs mountPath: /var/log/sonataflow containers: - name: promtail-sidecar image: grafana/promtail:2.9.0 args: - -config.file=/etc/promtail/config.yml volumeMounts: - name: shared-logs mountPath: /var/log/sonataflow readOnly: true - name: promtail-config mountPath: /etc/promtail - name: positions mountPath: /var/log resources: requests: cpu: 50m memory: 64Mi limits: cpu: 100m memory: 128Mi volumes: - name: shared-logs emptyDir: sizeLimit: 500Mi - name: promtail-config configMap: name: promtail-sidecar-config - name: positions emptyDir: {}Querying logs in Grafana: After deploying the stack, use the following LogQL queries in the Grafana Explore view:
Filter logs by process instance
{job="sonataflow-workflows"} | json | processInstanceId="abc-123-def-456"Find workflow errors:
{job="sonataflow-workflows", workflow="onboarding"} | json | level="ERROR"Trace correlation:
{job="sonataflow-workflows"} | json | traceId="4bf92f3577b34da6a3ce929d0e0e4736"Process instance timeline:
{job="sonataflow-workflows"} | json | processInstanceId="abc-123-def-456" | line_format "{{.timestamp}} [{{.level}}] {{.message}}"
Verification
- Access the Grafana Explore view.
Run the following LogQL query, replacing
<instance_id>with a valid ID:{job="sonataflow-workflows"} | json | processInstanceId="<instance_id>"Confirm that Grafana displays the log entries associated with the specified process instance.
11.5.3.6. Monitor workflow health with automated alerts
Set up automated alerts to notify your team when workflows fail at high rates, process instances become stuck, or runtimes exceed thresholds. Proactive alerting reduces mean time to detection for production issues.
Prerequisites
- You have enabled a structured JSON logging to provide metadata for LogQL and PromQL queries.
- You have installed a monitoring stack, such as Prometheus or Loki with Alertmanager in the cluster.
Procedure
Create a configuration file containing the following alert rule groups based on your monitoring requirements:
To monitor failure rates:
- alert: WorkflowHighErrorRate expr: rate({job="sonataflow-workflows", level="ERROR"}[5m]) > 0.1 for: 2m labels: severity: warning annotations: summary: "High error rate in SonataFlow workflows"To identify stalled process instances:
- alert: WorkflowInstanceStuck expr: | time() - max by (process_instance_id) ( {job="sonataflow-workflows"} | json | unwrap timestamp[1h] ) > 3600 labels: severity: criticalTo identify long-running workflows:
- alert: LongRunningWorkflow expr: | time() - min by (process_instance_id) ( {job="sonataflow-workflows"} | json | message="Workflow started" | unwrap timestamp[24h] ) > 7200 labels: severity: warning annotations: summary: "Workflow {{ $labels.process_instance_id }} running longer than 2 hours"
- Apply the alert rules to your cluster.
Verification
- Access the monitoring dashboard, such as the Prometheus or OpenShift Console.
- Verify that the alerts appear in the list under the Alerts tab.
11.5.3.7. Route alerts to existing tools to reduce response time
Receive failure notifications where your team already monitors incidents instead of checking a separate dashboard. Routing alerts to existing channels ensures on-call engineers see critical workflow issues immediately.
Prerequisites
- You have a valid webhook URL for the notification service (for example, Slack webhook).
Procedure
Define a receiver and a routing path in your Alertmanager configuration:
route: group_by: ['alertname', 'workflow'] group_wait: 10s group_interval: 10s repeat_interval: 1h receiver: 'web.hook' receivers: - name: 'web.hook' slack_configs: - api_url: 'YOUR_SLACK_WEBHOOK_URL' channel: '#workflow-alerts' title: 'SonataFlow Alert' text: '{{ range .Alerts }}{{ .Annotations.summary }}{{ end }}'- Reload the Alertmanager configuration to apply the changes.
Verification
- Trigger a test alert in your workflow environment.
-
Monitor the external notification service (for example, the Slack channel
#workflow-alerts). A notification appears in the external service containing the summary and details of the triggered alert.
11.5.3.8. Diagnose missing observability data to restore visibility
To restore monitoring visibility in Red Hat Developer Hub, you must identify why logs or traces are missing. Use these diagnostic steps to resolve issues with plain text logs, empty process instance IDs, or missing traces in Jaeger.
Prerequisites
-
You have access to the OpenShift (
oc) CLI. -
You have administrator permissions for the
sonataflow-infraandsonataflow-observabilitynamespaces. -
You have access to the workflow project
pom.xmland ConfigMap files.
Procedure
Verify JSON log formatting.
If logs appear as plain text instead of structured JSON, verify the following:
-
The
io.quarkus:quarkus-logging-jsonextension is defined in thepom.xmlfile. -
The
quarkus.log.console.json=trueproperty is set in the{workflow-name}-propsConfigMap. - The workflow image was rebuilt and redeployed after adding the extension.
- The workflow pod was restarted after applying ConfigMap changes.
Diagnose missing process instance context.
If logs are in JSON format but the
processInstanceIdfield is missing or empty, verify the following:- Workflow instances are actively running.
The following property is set in the workflow ConfigMap:
quarkus.log.console.json.print-details=true
- The SonataFlow version in use supports automatic Mapped Diagnostic Context (MDC) population.
Resolve log collection failures in Loki.
If logs are generated but do not appear in Loki or the aggregation dashboard, verify the following:
- The Promtail or Fluent Bit label selector matches the workflow pod labels.
- The collector has the required Role-Based Access Control (RBAC) permissions to read logs from the workflow namespace.
-
The
scrape_configsin the collector configuration include the correct namespace. Check the collector logs for permission errors:
oc logs -l app=promtail -n sonataflow-observability
Mitigate high resource usage.
If JSON logging causes performance degradation or high storage costs, implement the following changes:
Increase the log level for verbose categories to reduce output volume:
quarkus.log.category."org.kie.kogito".level=WARN
Enable asynchronous logging to reduce the impact on workflow execution time:
quarkus.log.console.async=true
- Configure log rotation and retention policies in the aggregation backend.
Verification
- After applying a fix, trigger a workflow execution.
Inspect the latest log entries. The logs appear in JSON format and include valid
processInstanceId,traceId, andspanIdfields:oc logs <workflow_pod_name> --tail=10
11.5.3.9. Integrate Loki logs for Orchestrator workflows
To troubleshoot and debug errors, integrate Loki logs into the Red Hat Developer Hub interface. You must install the Loki backend module and configure the connection details.
Prerequisites
- You have enabled the Orchestrator plugins in your Red Hat Developer Hub instance.
- You have a running Loki instance.
- You have stored your Orchestrator logs in the Loki instance.
Procedure
Enable the Loki backend module in the
redhat-developer-hub-dynamic-pluginsConfigMap.
- Open the ConfigMap and select the YAML view.
Add the Loki backend module to the
pluginssection:- disabled: false package: oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend-module-loki:{{inherit}}
- Save the file.
In your application
app-config.yamlConfigMap file, add the Loki workflow log provider integration to the orchestrator section:
NoteThe base URl might vary depending on where you store and access the Loki logs.
To obtain the base URL, run the following command:
LOKI_HOST=$(oc get route logging-loki -n openshift-logging -o jsonpath='{.spec.host}') echo "https://$LOKI_HOST/api/logs/v1/application/"orchestrator: workflowLogProvider: loki: baseUrl: <LOKI_BASE_URL> token: <AUTH_TOKEN> rejectUnauthorized: false # logPipelineFilters: # - '| filter1' # - '|= filter2' # logStreamSelectors: # - label: 'app' # value: '=~".+"'where:
baseUrl: Specifies the base URL of your Loki instance. This value is required.token: The access token for authentication. This value is required. To find your current token, run theoc whoami -tcommand.rejectUnauthorized: Set tofalseif using self-signed certificates.- Optional Parameters
logPipelineFilters: Multiple Log Pipeline Filters can be specified in thelogPipelineFilterssection. See the Loki documentation to learn more about the log pipeline filters and their values and usage.logStreamSelectors: Specifies log stream selectors to filter the logs. By default, the plugin retrieves logs with theopenshift_log_type="application". For more information about selector syntax, see the Grafana Loki documentation.
- Save the ConfigMap.
- Restart the Red Hat Developer Hub pod to apply the changes.
Verification
- Navigate to the Orchestrator plugin in the RHDH interface.
- Select a workflow instance.
- Click View Logs to display the workflow instance logs.
11.5.3.10. OpenTelemetry configurations
Configuration properties that control where traces are sent, how often they are sampled, and which service name appears in your monitoring dashboard. Reference this table to tune telemetry behavior for your environment.
| Property | Description | Default |
|---|---|---|
|
|
Enables or disables OpenTelemetry support. |
|
|
|
Specify the service name that appears in the trace backend. |
|
|
|
The URL of the OTLP-compatible collector. | |
|
|
The transport protocol. Supported values are |
|
|
|
The sampling strategy. For example, |
|
11.5.4. Optimize workflow performance
11.5.4.1. Optimize workflow performance
To maintain high performance in Red Hat Developer Hub, you must identify and resolve execution delays. Use distributed tracing to visualize the execution path and workflows and determine where time is spent across service boundaries.
11.5.4.2. Collect traces to monitor workflow performance
To monitor workflows in Red Hat Developer Hub, you must enable distributed tracing. Distributed tracing shows the executed path of workflow steps and identifies where failures occur.
To enable observability features such as tracing and metrics in the SonataFlow runtime, you must add the OpenTelemetry addon and configure the workflow properties. The sonataflow-addons-quarkus-opentelemetry addon provides a standard configuration with minimal setup required.
The OpenTelemetry integration for SonataFlow includes the following capabilities:
- Distributed tracing: Track workflow execution across services and steps.
- Metrics collection: Monitor performance, duration, and success rates.
- Log aggregation: Centralize logs with trace correlation.
- Context propagation: Maintain trace context across workflow boundaries and asynchronous operations.
Prerequisites
- You have installed and configured the SonataFlow Operator.
-
You have
cluster-adminor equivalent permissions to deploy observability infrastructure and modify ConfigMaps. - A Kubernetes or OpenShift cluster is available.
Procedure
Add the OpenTelemetry addon to the
QUARKUS_EXTENSIONSenvironment variable during the image build process:export QUARKUS_EXTENSIONS="${QUARKUS_EXTENSIONS},org.apache.kie.sonataflow:sonataflow-addons-quarkus-opentelemetry"-
Open the
{workflow-name}-propsConfigMap for your workflow. In the
application.propertiessection, enable the OpenTelemetry integration and configure the service attributes:# Application Identity quarkus.application.name=my-workflow quarkus.application.version=1.0.0 # OpenTelemetry Configuration quarkus.otel.enabled=true quarkus.otel.traces.enabled=true quarkus.otel.metrics.enabled=true quarkus.otel.logs.enabled=true # Service Resource Attributes quarkus.otel.resource.attributes=\ service.name=my-workflow,\ service.namespace=workflows,\ service.version=1.0.0,\ deployment.environment=production # SonataFlow Specific Configuration # Master switch for SonataFlow OpenTelemetry integration sonataflow.otel.enabled=true # Service identification (uses Quarkus application name/version as defaults) sonataflow.otel.service-name=${quarkus.application.name:kogito-workflow-service} sonataflow.otel.service-version=${quarkus.application.version:unknown} # Enable span creation for workflow states sonataflow.otel.spans.enabled=true # Enable process lifecycle events (start, complete, error, state transitions) sonataflow.otel.events.enabled=true- Save the ConfigMap and restart the workflow pod to apply the changes.
Verification
Verify that the OpenTelemetry addon is loaded by checking the pod logs:
oc logs -n workflows deployment/onboarding-workflow | grep "sonataflow-addons-quarkus-opentelemetry"
Verify the trace report status:
oc logs -n workflows deployment/greeting | grep -i "export\|batch"
Confirm that the observability backend, such as
Jaeger, is receiving data:oc logs -n observability deployment/jaeger | grep -i "span\|trace"
11.5.4.3. Connect traces to existing monitoring to avoid tool sprawl
Route workflow traces to the observability tools your team already uses instead of learning a new system. Exporter configuration sends telemetry data to Jaeger, Grafana, or any OTLP-compatible platform.
Prerequisites
- You have enabled OpenTelemetry in your workflow.
- An observability platform (Jaeger or OpenTelemetry Collector) is available in your cluster.
Procedure
Configure an export strategy based on your environment requirements:
Configure the OTLP exporter with batch processing (Recommended)
For production environments, use an OTLP exporter with batch processing to reduce network overhead and improve performance:
# OTLP exporter - Direct to Jaeger quarkus.otel.exporter.otlp.endpoint=http://jaeger-collector.observability.svc.cluster.local:4317 quarkus.otel.exporter.otlp.protocol=grpc quarkus.otel.traces.exporter=cdi # Batch processing for production quarkus.otel.bsp.schedule.delay=5s quarkus.otel.bsp.max.export.batch.size=512 quarkus.otel.bsp.export.timeout=2s quarkus.otel.bsp.max.queue.size=2048
Configure direct export to an external platform
For development or simple integrations, use a direct export configuration:
# Example: Direct export to Jaeger quarkus.otel.exporter.otlp.endpoint=http://jaeger-collector:4317 quarkus.otel.exporter.otlp.protocol=grpc quarkus.otel.traces.exporter=cdi
Externalize the configuration for production deployments by using environment variables. This ensures that your deployment remains secure and flexible across environments.
# Externalized Configuration quarkus.otel.exporter.otlp.endpoint=${OTEL_EXPORTER_OTLP_ENDPOINT:http://localhost:4317} quarkus.otel.exporter.otlp.headers=${OTEL_EXPORTER_OTLP_HEADERS:} quarkus.application.name=${OTEL_SERVICE_NAME:my-workflow} quarkus.otel.resource.attributes=${OTEL_RESOURCE_ATTRIBUTES:deployment.environment=dev}
11.5.4.4. Troubleshooting reference for trace connectivity and authentication issues
Symptom-to-solution reference table for missing traces, authentication failures, and broken context propagation. Use this troubleshooting guide when traces fail to appear in Jaeger, authentication errors occur, or telemetry delivery stops working.
| Symptom | Potential cause | Resolution |
|---|---|---|
|
Traces do not appear in the dashboard. |
OpenTelemetry is disabled or the endpoint is unreachable. |
Verify the |
|
Authentication errors ( |
Missing or invalid authorization headers. |
Configure the |
|
High memory usage in the collector. |
Large telemetry batches or high traffic volume. |
Implement a |
|
Context is lost between workflow steps. |
Incorrect propagator configuration. |
Ensure |
11.5.4.4.1. Diagnose missing traces
Verify that OpenTelemetry is enabled in the workflow ConfigMap:
oc get cm {workflow-name}-props -n workflows -o yamlCheck the pod logs for initialization errors:
oc logs deployment/{deployment-name} -n workflows | grep -i "otel"Test the connection to the Jaeger collector from within the workflow pod:
oc exec deployment/{deployment-name} -- curl -v http://jaeger-collector:4317
Configure authentication headers. If your observability platform requires authentication, add the following property to your
application.propertiesfile:quarkus.otel.exporter.otlp.headers=authorization=Bearer ${API_TOKEN}- Resolve context propagation issues. To ensure trace IDs are maintained across service boundaries, configure the following propagators and enable JSON logging to verify the IDs in the output:
# Include required propagators quarkus.otel.propagators=tracecontext,baggage,jaeger # Enable JSON logging to verify trace IDs quarkus.log.console.json=true
11.5.5. Trace attribute definitions and filtering keys
Automatic span attributes that identify workflow executions, instances, and states. Use these attributes in Jaeger queries to locate specific workflow runs, filter by version, or trace process instances through various execution states.
To locate specific workflow executions or trace a process through various states, use the automatic span attributes generated by SonataFlow. Each span includes the following specific attributes:
-
sonataflow.process.id: Indicates the ID of the workflow definition. -
sonataflow.process.instance.id: Indicates the unique ID for the specific execution instance. -
sonataflow.process.version: Indicates the version of the workflow definition. -
sonataflow.workflow.state: Indicates the name of the current workflow state, for example,StartEvent. -
sonataflow.process.instance.state: Indicates the current state of the process instance, such asACTIVE,COMPLETED,ERROR, orSUSPENDED. -
sonataflow.transaction.id: Indicates the ID used to correlate multiple workflows in a single business transaction. -
sonataflow.tracker.*: Indicates custom attributes converted fromX-TRACKER-*headers. -
service.nameandservice.version: Indicates the service identification details from the configuration.
11.6. Collect diagnostic data to troubleshoot platform issues
11.6.1. Diagnostic data collection overview
The must-gather tool collects diagnostic data and logging information from your cluster, which helps Red Hat Support resolve your deployment issues efficiently.
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.
Use must-gather when you open a support ticket with Red Hat Global Support Services, troubleshoot deployment issues, or capture deployment state before RHDH upgrades.
Typical collection size ranges from 10 MB to 50 MB for basic collections and 500 MB to 2 GB when including heap dumps. Plan for adequate storage and bandwidth when collecting for support tickets.
The must-gather output might contain sensitive information such as configuration values, environment variables, application logs, and resource definitions. While the tool automatically sanitizes known secret types, you should review the output before sharing it with support to check for domain-specific sensitive data.
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
Run the must-gather tool on OpenShift Container Platform or Kubernetes clusters to collect diagnostic data for troubleshooting Developer Hub deployments. You can also collect diagnostic data from air-gapped clusters by using a mirrored must-gather image.
11.6.2.2. Run must-gather on OpenShift to collect diagnostic data
Collect diagnostic data from RHDH deployments on OpenShift Container Platform.
Prerequisites
- You have deployed Red Hat Developer Hub on OpenShift Container Platform.
-
Cluster administrator access or
RBACpermissions for resource inspection. -
Authenticated OpenShift CLI (
oc) (OpenShift Container Platform).
Procedure
Run must-gather:
$ oc adm must-gather --image=registry.access.redhat.com/rhdh/rhdh-must-gather-rhel9:1.10
Output:
./must-gather.local.<timestamp>NoteThe must-gather tool automatically detects and collects data from all RHDH instances in the cluster, regardless of whether they were deployed using the Operator or Helm chart.
For advanced scenarios, you can limit data collection:
-
Skip Helm-based deployments:
-- /usr/bin/gather --without-helm -
Skip Operator-based deployments:
-- /usr/bin/gather --without-operator
-
Skip Helm-based deployments:
Verification
Confirm that the output directory exists:
$ ls must-gather.local.<timestamp>/
The directory contains subdirectories for each deployment method found:
-
operator/- Data from Operator-based deployments -
helm/- Data from Helm-based deployments
-
11.6.2.3. Run must-gather on Kubernetes to collect diagnostic data
Collect diagnostic data from RHDH deployments on supported Kubernetes platforms.
Prerequisites
- You have deployed Red Hat Developer Hub on a supported Kubernetes platform.
-
Cluster administrator access or
RBACpermissions for resource inspection. -
Authenticated CLI:
kubectlandhelm.
Procedure
Install must-gather:
$ helm upgrade --install my-rhdh-must-gather redhat-developer-hub-must-gather \ --repo https://charts.openshift.io \ --namespace rhdh-diagnostics \ --create-namespace
NoteThe must-gather tool automatically detects and collects data from all RHDH instances in the cluster, regardless of whether they were deployed using the Operator or Helm chart.
For advanced scenarios, you can limit data collection using Helm values:
-
Skip Helm-based deployments:
--set gather.withHelm=false -
Skip Operator-based deployments:
--set gather.withOperator=false
-
Skip Helm-based deployments:
Wait for collection:
$ kubectl wait --for=condition=ready pod \ -l app.kubernetes.io/instance=my-rhdh-must-gather,app.kubernetes.io/component=gather \ --timeout=3600s -n rhdh-diagnostics
Extract data:
$ kubectl exec deploy/my-rhdh-must-gather -c data-holder -n rhdh-diagnostics -- \ tar czf - -C /must-gather . > rhdh-must-gather-output.tar.gz
Clean up:
$ helm uninstall my-rhdh-must-gather -n rhdh-diagnostics
Verification
Confirm that the output archive contains diagnostic data:
$ tar -tzf rhdh-must-gather-output.tar.gz
The archive contains subdirectories for each deployment method found:
-
operator/- Data from Operator-based deployments -
helm/- Data from Helm-based deployments
-
11.6.2.4. Collect diagnostic data from air-gapped clusters with a mirrored must-gather image
Mirror the must-gather image to your registry to enable diagnostic data collection from disconnected clusters.
Prerequisites
-
skopeotool installed on the machine with registry access. - Access to an internal container registry.
- For OpenShift Container Platform: Cluster administrator access to update the global pull secret.
- For Kubernetes: Ability to create secrets in target namespaces.
Procedure
Choose your mirroring workflow based on network access:
Partially disconnected:
Your local machine can access both the internet and the internal registry.
Fully disconnected:
Requires a bastion host or approved file transfer method to move images.
Mirror the must-gather image:
For partially disconnected environments:
$ skopeo copy \ docker://registry.access.redhat.com/rhdh/rhdh-must-gather-rhel9:*<version>* \ docker://<internal-registry>/rhdh/rhdh-must-gather:*<version>*
For fully disconnected environments:
On a machine with internet access, pull the must-gather image:
$ skopeo copy \ docker://registry.access.redhat.com/rhdh/rhdh-must-gather-rhel9:*<version>* \ dir:./rhdh-must-gather-<version>
Pull the Helm chart:
$ helm pull redhat-developer-hub-must-gather --repo https://charts.openshift.io
Transfer the image directory and the
redhat-developer-hub-must-gather-<version>.tgzchart file to your bastion host. Push the image to the internal registry:$ skopeo copy \ dir:./rhdh-must-gather-<version> \ docker://<internal-registry>/rhdh/rhdh-must-gather:*<version>*
Replace
<version>with the must-gather version that matches your RHDH deployment and<internal-registry>with your internal registry hostname.Configure image pull authentication:
NoteIf your internal registry requires authentication, you must configure image pull secrets before running must-gather. Without proper credentials, the must-gather pod fails with
ImagePullBackOfferrors.On OpenShift Container Platform:
Add your internal registry credentials to the cluster-wide pull secret. For instructions, see Updating the global cluster pull secret in the Red Hat OpenShift Container Platform documentation.
On Kubernetes:
Create a docker-registry secret:
$ kubectl create secret docker-registry must-gather-pull-secret \ --docker-server=<internal-registry> \ --docker-username=<username> \ --docker-password=<password> \ -n rhdh-diagnostics
Run must-gather using the mirrored image:
On OpenShift Container Platform:
$ oc adm must-gather --image=<internal-registry>/rhdh/rhdh-must-gather:*<version>*
On Kubernetes (partially disconnected):
$ helm upgrade --install my-rhdh-must-gather redhat-developer-hub-must-gather \ --repo https://charts.openshift.io \ --namespace rhdh-diagnostics \ --create-namespace \ --set image.registry=<internal-registry> \ --set image.repository=rhdh/rhdh-must-gather \ --set image.tag=<version> \ --set imagePullSecrets[0].name=must-gather-pull-secret
On Kubernetes (fully disconnected):
$ helm upgrade --install my-rhdh-must-gather /path/to/redhat-developer-hub-must-gather-<version>.tgz \ --repo https://charts.openshift.io \ --namespace rhdh-diagnostics \ --create-namespace \ --set image.registry=<internal-registry> \ --set image.repository=rhdh/rhdh-must-gather \ --set image.tag=<version> \ --set imagePullSecrets[0].name=must-gather-pull-secret
Verification
Verify that the collection starts without
ImagePullBackOfferrors:$ oc get pods -n openshift-must-gather-<random> # On OpenShift $ kubectl get pods -n rhdh-diagnostics # On Kubernetes
Troubleshooting
ImagePullBackOff errors:
Check that registry credentials are configured correctly and that the image path matches your registry structure.
Certificate errors:
If your internal registry uses self-signed certificates, configure certificate trust on the cluster. For OpenShift Container Platform, see Configuring image registry repository mirroring in the Red Hat OpenShift Container Platform documentation.
11.6.3. Collect heap dumps to diagnose memory issues
Collect Node.js heap snapshots when you troubleshoot memory leaks, out-of-memory errors, or when support requests memory analysis.
Prerequisites
- Sufficient storage for heap dump files (50 MB to 500 MB each).
-
For SIGUSR2 method: Node.js 12+ for
--heapsnapshot-signalflag support.
Procedure
Choose the heap dump collection method:
Inspector protocol (default):
- Works out of the box
-
Use unless your deployment sets
--disable-sigusr1inNODE_OPTIONS
SIGUSR2 signal:
-
Requires configuring
NODE_OPTIONSin your deployment first - Use when the inspector protocol is not available
If using SIGUSR2, configure
NODE_OPTIONS:NoteSkip this step if using the inspector protocol (default method).
Operator deployments:
apiVersion: rhdh.redhat.com/v1alpha1 kind: Backstage metadata: name: my-rhdh spec: application: extraEnvs: - name: NODE_OPTIONS value: "--heapsnapshot-signal=SIGUSR2 --diagnostic-dir=/tmp"Apply the change:
$ oc apply -f backstage-cr.yaml
Helm deployments:
upstream: backstage: extraEnvVars: - name: NODE_OPTIONS value: "--heapsnapshot-signal=SIGUSR2 --diagnostic-dir=/tmp"Update the release:
$ helm upgrade my-rhdh redhat-developer-hub/backstage -f values.yaml -n <namespace>
Wait for pods to restart before proceeding.
Increase the liveness probe timeout to prevent pod restarts:
ImportantRHDH stops responding during heap dump collection, and large memory footprints (1GB+) can cause liveness probe failures. Plan collection during maintenance windows or low-traffic periods.
Operator deployments:
Update the Backstage custom resource to patch the deployment:
apiVersion: rhdh.redhat.com/v1alpha1 kind: Backstage metadata: name: my-rhdh spec: deployment: patch: spec: template: spec: containers: - name: backstage-backend livenessProbe: failureThreshold: 180Apply the change:
$ oc apply -f backstage-cr.yaml
Helm deployments:
Update your Helm values:
upstream: backstage: livenessProbe: failureThreshold: 180Apply the change:
$ helm upgrade my-rhdh redhat-developer-hub/backstage -f values.yaml -n <namespace>
Wait for pods to restart before proceeding.
Run must-gather with heap dumps enabled:
On OpenShift Container Platform:
For inspector protocol (default):
$ oc adm must-gather --image=registry.access.redhat.com/rhdh/rhdh-must-gather-rhel9:1.10 -- /usr/bin/gather --with-heap-dumps
For SIGUSR2 method:
$ oc adm must-gather --image=registry.access.redhat.com/rhdh/rhdh-must-gather-rhel9:1.10 -- /usr/bin/gather --with-heap-dumps --heap-dump-method sigusr2
On supported Kubernetes platforms:
For inspector protocol (default):
gather: heapDump: enabled: true method: "inspector"For SIGUSR2 method:
gather: heapDump: enabled: true method: "sigusr2"Collection takes 5-15 minutes depending on pod count and memory size.
Verification
Check for .heapsnapshot files:
$ find must-gather.local.<timestamp> -name "*.heapsnapshot" # On OpenShift $ tar -tzf rhdh-must-gather-output.tar.gz | grep heapsnapshot # On Kubernetes
- If collection starts but times out before completing
You see progress messages but collection eventually times out before finishing. Check the
must-gatherlogs for warnings about liveness probe settings:[WARN] Pod 'xxx' may restart during heap dump collection! [WARN] Current: failureThreshold=3 × periodSeconds=10s = 30s before restart [WARN] Required: at least 900s (HEAP_DUMP_TIMEOUT)
Set your liveness probe timeout longer than the collection time.
For Operator-based deployments, update the Backstage custom resource:
spec: deployment: patch: spec: template: spec: containers: - name: backstage-backend livenessProbe: failureThreshold: 180Apply with
oc apply -f backstage-cr.yaml.For Helm-based deployments, patch the deployment directly:
$ oc patch deployment <deployment-name> -n <namespace> \ -p '{"spec":{"template":{"spec":{"containers":[{"name":"backstage-backend","livenessProbe":{"failureThreshold":180}}]}}}}'Wait for your pods to restart with the new configuration, then run heap dump collection again.
- If collection times out
Large memory footprints (multiple gigabytes) can take 10-15 minutes to snapshot. Increase the heap dump timeout to allow more time for collection.
On OpenShift Container Platform, set the timeout using an environment variable:
$ oc adm must-gather --image=registry.access.redhat.com/rhdh/rhdh-must-gather-rhel9:1.10 \ -- /usr/bin/env HEAP_DUMP_TIMEOUT=1800 /usr/bin/gather --with-heap-dumps
On Kubernetes, set the timeout in your Helm values:
gather: heapDump: enabled: true timeout: "1800"
11.6.4. Diagnostic data types and collection scope
The must-gather tool uses collectors to gather specific types of diagnostic data.
Reduce collection time by:
- Excluding collectors not needed for your deployment
- Filtering to specific namespaces
- Enabling optional collectors only when required
11.6.4.1. Default-enabled collectors
The following collectors run by default. Exclude collectors not needed for your deployment using --without-<collector> flags:
- platform collector
-
Collects cluster version and platform type (OpenShift Container Platform, AKS, EKS, or GKE). Disable with
--without-platform. - helm collector
-
Collects Helm release information. Use for Helm-based deployments only. Disable with
--without-helm. - operator collector
-
Collects Operator logs and custom resources. Use for Operator-based deployments only. Disable with
--without-operator. - orchestrator collector
-
Collects workflow data for the Orchestrator plugin. Use to troubleshoot Orchestrator workflows only. Disable with
--without-orchestrator. - route-ingress collector
-
Collects route definitions (OpenShift Container Platform) and ingress configurations (Kubernetes). Use to troubleshoot external access only. Disable with
--without-routeor--without-ingress. - namespace-inspect collector
-
Collects namespace resources for support teams. Limit to specific namespaces using
--namespaces. Recommended for all collections. Disable with--without-namespace-inspect.
11.6.4.2. Opt-in collectors
The following collectors do not run by default. Enable them only when needed:
- cluster-info collector
Collects cluster-wide state information beyond basic platform metadata. Enable with
--cluster-info.ImportantEnable this collector only when support requests it, as it significantly increases collection time and may impact cluster performance during collection.
- heap-dumps collector
Collects Node.js memory snapshots for diagnosing memory issues. Enable with
--with-heap-dumps.Requirements:
- Liveness probe timeout increased to prevent pod restarts
- Sufficient storage (50 MB to 500 MB per heap dump file)
Use only when:
- Troubleshooting memory leaks
- Support requests memory analysis
- Diagnosing out-of-memory errors
11.6.5. Configuration options for diagnostic collection
Reference tables for must-gather command-line flags, environment variables, and Helm chart values.
11.6.5.1. Command-line flags
Command-line flags are available when running the gather script directly. On OpenShift Container Platform, pass these flags after -- /usr/bin/gather. On Kubernetes, use the equivalent Helm chart values instead.
| Flag | Description | Default | Example |
|---|---|---|---|
|
|
Comma-separated list of namespaces to collect data from. |
All namespaces |
|
|
|
Include cluster-wide state information. Use only when requested by support. |
Not included |
|
|
|
Trigger Node.js heap snapshots and collect heap dump files for memory analysis. |
Not included |
|
|
|
Comma-separated list of specific RHDH instance names to collect heap dumps from. Supports exact match, prefix match, or contains match. Only applies when |
All RHDH instances |
|
|
|
Method to trigger heap dumps. Valid values: |
|
|
|
|
Exclude the Operator collector. Use for Helm-based deployments. |
Operator collector included |
|
|
|
Exclude the Helm collector. Use for Operator-based deployments. |
Helm collector included |
|
|
|
Exclude the Orchestrator collector. Use when not using Orchestrator functionality. |
Orchestrator collector included |
|
|
|
Exclude the platform collector. |
Platform collector included |
|
|
|
Exclude the route collector (OpenShift Container Platform routes). |
Route collector included |
|
|
|
Exclude the ingress collector (Kubernetes ingress resources). |
Ingress collector included |
|
|
|
Exclude the namespace-inspect collector. Not recommended as it aids support navigation. |
Namespace-inspect collector included |
|
11.6.5.2. Environment variables
Environment variables control must-gather operational behavior when running the gather script directly. When using the Helm chart, use the Helm chart values described in the next section instead of environment variables.
| Variable | Description | Default | Helm Chart Equivalent |
|---|---|---|---|
|
|
Logging verbosity level. Valid values: |
|
|
|
|
Timeout for individual kubectl and Helm commands (seconds). |
|
|
|
|
Relative time duration to limit log collection (for example, |
Not set (collects all available logs) |
|
|
|
Absolute RFC3339 timestamp to limit log collection. |
Not set (collects all available logs) |
|
|
|
Timeout in seconds for heap dump generation per pod. |
|
|
11.6.5.3. Helm chart values
When deploying must-gather on Kubernetes platforms using the Helm chart, configure collection options using a values file. The following table shows key Helm values and their equivalent command-line flags or environment variables.
| Helm Value Path | Description | Equivalent Command-line Flag or Environment Variable |
|---|---|---|
|
|
Array of namespaces to collect from. |
|
|
|
Boolean to include cluster-wide state information. Use only when requested by support. |
|
|
|
Boolean to collect heap dumps from Node.js backend pods. |
|
|
|
Array of specific RHDH instance names to collect heap dumps from. |
|
|
|
Method to trigger heap dumps. Valid values: |
|
|
|
Timeout in seconds for heap dump collection. |
|
|
|
Boolean to enable or disable the Operator collector. Set to |
|
|
|
Boolean to enable or disable the Helm collector. Set to |
|
|
|
Boolean to enable or disable the Orchestrator collector. Set to |
|
|
|
Log level for must-gather operations. Valid values: |
|
|
|
Timeout in seconds for individual kubectl or helm commands. |
|
|
|
Relative time duration to limit log collection (for example, |
|
|
|
Absolute RFC3339 timestamp to limit log collection. |
|
Helm boolean values use positive logic (withX: true means include), while command-line flags use negative logic (--without-X means exclude).
11.6.6. Diagnostic data output structure and organization
The must-gather output directory organizes data by collector type, namespace, and resource type.
11.6.6.1. Top-level directory structure
The must-gather output directory contains files and subdirectories organized by collection method and data type. The following table shows the top-level structure:
| Path | Contents |
|---|---|
|
|
Collection metadata including timestamps, must-gather version, collectors that ran, and collection parameters. |
|
|
Data sanitization summary and details. |
|
|
All OpenShift Container Platform routes cluster-wide. |
|
|
All Kubernetes ingresses cluster-wide. |
|
|
Cluster-wide information (only present if you specified |
|
|
Deep namespace inspect data (collected by default). |
|
|
Platform and infrastructure information. |
|
|
Helm deployment data (native releases and standalone deployments). Only present if Helm-deployed RHDH instances are detected. |
|
|
Orchestrator-flavored deployment data (if detected). Only present if Orchestrator components are detected. |
|
|
Operator deployment data (if RHDH operators found). Only present if RHDH operators are detected. |
11.6.6.2. Heap dump file locations
When the tool collects heap dumps with the --with-heap-dumps flag, they appear within deployment-specific directories, not under namespace-inspect/namespaces/. The location depends on the installation method:
Heap dump file paths by deployment type:
-
Helm releases:
helm/releases/ns=<namespace>/<release>/deployment/heap-dumps/… -
Helm standalone:
helm/standalone/ns=<namespace>/<workload>/deployment/heap-dumps/… -
Operator:
operator/backstage-crs/ns=<namespace>/<cr>/deployment/heap-dumps/…
Example:
helm/releases/ns=rhdh-prod/developer-hub/deployment/heap-dumps/pod=backstage-developer-hub-7d8f9c5b-xk2m4/container=backstage-backend/heapdump-20260430-143022.heapsnapshot
Analyze heap dump files using Chrome DevTools, Node.js heap analysis tools, or memory profilers.
11.6.6.3. Common diagnostic data locations
The following table shows where to find frequently needed diagnostic information in the must-gather output:
| Diagnostic Data | Location |
|---|---|
|
Backend pod logs |
|
|
PostgreSQL connection configuration |
|
|
Operator logs |
|
|
Backstage custom resource definition |
|
|
Route or Ingress definitions |
|
|
Helm release values |
|
|
Deployment configurations |
|
|
Service definitions |
|
|
Platform and cluster version |
|
|
Heap dumps for memory analysis |
|
Chapter 12. Integrate
12.1. Integrate
Integrate Red Hat Developer Hub with AI assistants, external tools, and infrastructure platforms to enhance developer productivity and streamline workflows.
12.2. Enable AI assistance for developers
12.2.1. Enable AI assistance for developers
Red Hat Developer Lightspeed for Red Hat Developer Hub (Developer Lightspeed for RHDH) is an AI-powered virtual assistant for Red Hat Developer Hub (RHDH). You can interact with Developer Lightspeed for RHDH to explore RHDH capabilities in detail.
12.2.2. Developer Lightspeed for RHDH architecture
12.2.2.1. Developer Lightspeed for RHDH architecture
Red Hat Developer Lightspeed for Red Hat Developer Hub is enabled by default on Red Hat Developer Hub (RHDH) instances. To provide developers with chat assistance, configure your deployment settings by using either the Operator or the Helm chart.
12.2.2.2. Retrieval augmented generation (RAG) embeddings for grounded AI responses
Use retrieval-augmented generation (RAG) embeddings to ground artificial intelligence (AI) responses in your internal documentation and provide verified citations during user interactions.
The RHDH documentation serves as the primary data source for RAG operations. To provide accurate citations to production documentation during inference, the system uses RAG embeddings stored within a vector database.
The system processes RAG data through the following sequence:
- An initialization container copies the RAG data to a shared volume.
- The Lightspeed Core Service (LCORE) sidecar container mounts the shared volume to access the data.
- The sidecar layer uses the embeddings to attach precise documentation references to the chat responses.
12.2.2.3. Configure the virtual assistant components
Configure Developer Lightspeed for RHDH by updating your Backstage custom resource (CR) to map environment variables, manage configurations, and set access rights.
Prerequisites
- The RHDH Operator is installed on your cluster.
- You have cluster administrator privileges.
Procedure
Create an opaque Kubernetes Secret containing your operational credentials and query safety guardrails before applying the Backstage CR. Refer to the following key definitions for required environment variables:
ImportantTo disable an inference provider or configuration feature, you must leave the corresponding
ENABLE_*variable completely unset. Setting anENABLE_*variable tofalsedoes not disable the component because the underlying system checks only whether the variable is defined.Key Description ENABLE_VLLMEnables the vLLM platform when set to
"true".VLLM_URLSpecifies the target API endpoint URL for vLLM (for example,
https://<api_endpoint>/v1).VLLM_API_KEYStores the authorization token for your vLLM platform.
ENABLE_OPENAIEnables the OpenAI platform when set to
"true".OPENAI_API_KEYStores the authorization secret key for OpenAI.
ENABLE_OLLAMAEnables the Ollama platform when set to
"true".OLLAMA_URLSpecifies the target endpoint URL for Ollama.
ENABLE_VERTEX_AIEnables the Vertex AI platform when set to
"true".VERTEX_AI_PROJECTSpecifies your Google Cloud project ID.
VERTEX_AI_LOCATIONSpecifies your target Google Cloud region.
GOOGLE_APPLICATION_CREDENTIALSSpecifies the file path of your mounted Google Cloud service account credentials JSON file.
ENABLE_VALIDATIONActivates query safety validation guardrails when set to
"true".VALIDATION_PROVIDERDefines the active provider managing the verification routines (for example,
openaiorvllm).VALIDATION_MODEL_NAMESpecifies the exact verification model to use (for example,
gpt-4o-mini).The following code shows an example configuration Secret for vLLM with validation:
apiVersion: v1 kind: Secret metadata: name: lightspeed-auth-secrets type: Opaque stringData: ENABLE_VLLM: "true" VLLM_URL: "https://<api_endpoint>/v1" VLLM_API_KEY: "<api_key>" ENABLE_VALIDATION: "true" VALIDATION_PROVIDER: "vllm" VALIDATION_MODEL_NAME: "llama3.1"
Map your secret inside the
extraEnvssection of the Backstage CR to complete container provisioning:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: lightspeed-rhdh spec: application: extraEnvs: secrets: - name: lightspeed-auth-secrets containers: - lightspeed-coreOptional: To protect settings such as Model Context Protocol (MCP) server additions from being overwritten during reconciliation loops, define a custom ConfigMap mapping in the
extraFilessection of the CR:extraFiles: configMaps: - name: "my-custom-config" mountPath: /app-root key: lightspeed-stack.yaml containers: - lightspeed-coreConfigure access rights by updating the RBAC policy inside your Backstage CR:
To grant non-administrator teams access to the virtual assistant, append permission lines to the
rbac-policies.csvsection, replacing<team>with your target team name:p, role:default/<team>, lightspeed.chat.read, read, allow p, role:default/<team>, lightspeed.chat.create, create, allow
Apply the updated custom resource manifest to your cluster:
$ oc apply -f <backstage_cr_file>.yaml
Verification
- Log in to your console instance.
- Verify that the Lightspeed button appears on the home page.
- Select the Lightspeed button and confirm that the chat window initializes successfully.
12.2.2.4. Configure Developer Lightspeed for RHDH by using the Helm chart
Configure Developer Lightspeed for RHDH by using the Helm chart to manage large language model (LLM) providers, enable validation guardrails, and authorize custom role-based access control (RBAC) policies.
Prerequisites
- You have access to a running RHDH instance deployed with Helm.
- You have operational credentials for your chosen LLM provider.
Procedure
Create a manual Kubernetes Secret to store your provider credentials by adding the required keys to your Secret based on your provider requirements:
ImportantTo disable an inference provider or configuration feature, you must leave the corresponding
ENABLE_*variable completely unset. Setting anENABLE_*variable tofalsedoes not disable the component because the underlying system checks only whether the variable is defined.Key Description ENABLE_VLLMEnables the vLLM platform when set to
"true".VLLM_URLSpecifies the target API endpoint URL for vLLM (for example,
https://<api_endpoint>/v1).VLLM_API_KEYStores the authorization token for your vLLM platform.
ENABLE_OPENAIEnables the OpenAI platform when set to
"true".OPENAI_API_KEYStores the authorization secret key for OpenAI.
ENABLE_OLLAMAEnables the Ollama platform when set to
"true".OLLAMA_URLSpecifies the target endpoint URL for Ollama.
ENABLE_VERTEX_AIEnables the Vertex AI platform when set to
"true".VERTEX_AI_PROJECTSpecifies your Google Cloud project ID.
VERTEX_AI_LOCATIONSpecifies your target Google Cloud region.
GOOGLE_APPLICATION_CREDENTIALSSpecifies the file path of your mounted Google Cloud service account credentials JSON file.
ENABLE_VALIDATIONActivates query safety validation guardrails when set to
"true".VALIDATION_PROVIDERDefines the active provider managing the verification routines (for example,
openaiorvllm).VALIDATION_MODEL_NAMESpecifies the exact verification model to use (for example,
gpt-4o-mini).Note-
By default, the Helm installation creates a temporary Kubernetes Secret containing keys for various LLM providers. On subsequent
helm upgradecycles, the system overwrites this default Secret. Create a manual Kubernetes Secret to persist your credentials. - Vertex AI requires custom architecture mapping and has received limited testing.
TipTo filter and reject off-topic user queries, you can optionally configure query safety validation guardrails within this Secret by defining the
ENABLE_VALIDATION,VALIDATION_PROVIDER, andVALIDATION_MODEL_NAMEkeys.-
By default, the Helm installation creates a temporary Kubernetes Secret containing keys for various LLM providers. On subsequent
Reference your manual secret inside the
values.yamlfile:global: lightspeed: secret: create: false name: "my-custom-secret"Optional: Configuration files such as
lightspeed-stack.yaml,config.yamlandrhdh-profile.pyare managed by the Helm deployment and overwrites changes onHelm upgraderuns. To protect changes to a file, create a custom config map and reference it in thevalues.yamlfile:ImportantOnly modify the
createandnameOverridefields. Keep the default mount paths and file configurations unchanged.global: lightspeed: configMaps: - name: stack create: false nameOverride: "my-custom-stack" mountPath: /app-root/lightspeed-stack.yaml subPath: lightspeed-stack.yaml sourceFile: lightspeed-stack.yaml optional: falseConfigure access rights by updating your RBAC definitions:
To grant non-administrator teams access to the virtual assistant, append permission lines to the
rbac-policies.csvsection, replacing<team>with your target team name:p, role:default/<team>, lightspeed.chat.read, read, allow p, role:default/<team>, lightspeed.chat.create, create, allow
-
Run the
helm upgradecommand to apply your configurations to the cluster.
Verification
- Log in to your console instance.
- Verify that the Lightspeed button appears on the home page.
- Select the Lightspeed button and confirm that the chat window initializes successfully.
12.2.2.5. Disable Developer Lightspeed for RHDH by using the Operator
Disable the Developer Lightspeed for RHDH chat interface and stop associated container processes to remove the service from your Operator-backed deployment.
Prerequisites
- You have access to the cluster where your instance is deployed.
- You have cluster administrator privileges.
Procedure
- Open your Backstage custom resource (CR) YAML file.
In the
specsection, set theenabledflag tofalsefor thelightspeedflavour. This disables the chat interface and prevents the Operator from injecting unconfigured sidecar containers:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: lightspeed-disabled spec: flavours: - name: lightspeed enabled: falseApply the updated custom resource manifest to your cluster:
oc apply -f <backstage_cr_file>.yaml
Verification
- Log in to your console instance.
- Verify that the Lightspeed button no longer appears on the home page.
12.2.2.6. Disable Developer Lightspeed for RHDH by using the Helm chart
Disable the Developer Lightspeed for RHDH chat interface and stop associated container processes to remove the service from your Helm-deployed environment.
Prerequisites
- You have access to the cluster where your instance is deployed.
- You have cluster administrator privileges.
Procedure
-
Open your Helm
values.yamlfile. Update the
global.lightspeed.enabledparameter tofalseto disable the chat interface:global: lightspeed: enabled: false-
Run the
helm upgradecommand to apply the configuration change to your cluster.
Verification
- Log in to your console instance.
- Verify that the Lightspeed button no longer appears on the home page.
12.2.2.7. Customize the system prompt and UI options
12.2.2.7.1. Customize the system prompt and UI options
You can customize Developer Lightspeed for RHDH to align model behavior with your operational goals, enhance developer productivity, and ensure secure data retention.
12.2.2.7.2. Enable user feedback to improve model performance
Enable user feedback collection to allow users to rate chat responses and submit text comments directly within the console interface.
The Lightspeed Core Service (LCORE) stores this data as JSON files inside your cluster. Because Red Hat does not collect or access this data, platform administrators must manage, analyze, and delete these files locally.
Prerequisites
- You have platform administrator privileges.
- You created and referenced a custom config map in your deployment to ensure configuration changes persist during system upgrades or Operator reconciliation loops. For more information, see Provision your custom Red Hat Developer Hub configuration.
Procedure
In your custom configuration file, such as
lightspeed-stack.yaml, modify theuser_data_collectionblock to configure your data preferences:To enable feedback collection, set the
feedback_enabledparameter totrue:user_data_collection: feedback_enabled: true feedback_storage: "/tmp/data/feedback" transcripts_enabled: true transcripts_storage: "/tmp/data/transcripts"
To disable feedback collection, set the
feedback_enabledparameter tofalse:user_data_collection: feedback_enabled: false feedback_storage: "/tmp/data/feedback" transcripts_enabled: true transcripts_storage: "/tmp/data/transcripts"
NoteDo not modify the
feedback_storageortranscripts_storagedata paths when disabling feedback. Altering these path strings prevents the service from locating existing historical logs.
- Apply the updated configuration file changes to your cluster by running your platform’s standard deployment or upgrade sequence.
12.2.2.7.3. Customize AI responses by using system prompts
Configure a custom system prompt to provide environmental context to the large language model (LLM). This custom instruction prefixes user queries, guiding the assistant to generate artificial intelligence (AI) responses tailored to your RHDH instance.
Prerequisites
- You have administrative access to the RHDH host platform filesystem.
Procedure
In your
app-config.yamlfile, add or modify thesystemPromptparameter under thelightspeedsection, specifying your custom instruction string:lightspeed: # ... other lightspeed configurations systemPrompt: "You are a helpful assistant focused on Red Hat Developer Hub development."
- Save the file.
- Restart the RHDH service to apply the updated system prompt configuration.
12.2.2.7.4. Customize chat history storage
Configure chat history storage to choose between non-persistent local logs and a persistent external database for user conversations.
By default, the system stores chat history in a non-persistent local database within the Lightspeed Core Service (LCORE) container. To retain data across system restarts, you must configure a PostgreSQL database connection.
Storing chat history records user prompts and responses. You must assess data privacy and security implications if your user chat history contains private, sensitive, or confidential information. For users that want to have their chat data removed, they must request their platform administrator to perform this action. Red Hat does not collect or access this chat history data.
Prerequisites
- You created and referenced a custom config map in your deployment to ensure configuration changes persist during system upgrades or Operator reconciliation loops. For more information, see Provision your custom Red Hat Developer Hub configuration.
Procedure
In your custom configuration file, such as
lightspeed-stack.yaml, modify theconversation_cacheblock to specify your storage configuration:To enable persistent storage, add your PostgreSQL database credentials and endpoint properties:
conversation_cache: type: "postgres" postgres: host: _<your_database_host>_ port: _<your_database_port>_ db: _<your_database_name>_ user: _<your_user_name>"_ password: _<postgres_password>_To retain the default non-persistent SQLite setup, verify that the parameters match the following paths:
conversation_cache: type: "sqlite" sqlite: db_path: '/tmp/cache.db'
- Restart the LCORE service to apply your new database configuration.
12.2.2.8. Mirror Lightspeed images for air-gapped environments
Mirror the required Developer Lightspeed for RHDH container images and plugins to your local registry to provide chat assistance in an air-gapped environment.
The prepare-restricted-environment.sh script does not automatically parse Developer Lightspeed for RHDH images from the bundle manifest, so mirror these images manually before running the script.
Prerequisites
- You have a target mirror registry accessible to your disconnected cluster.
- You authenticated to the Red Hat Container Registry and your target mirror registry.
-
You have configured image pull authentication for your mirror registry as described in Install Red Hat Developer Hub in an air-gapped environment with the Operator. The
kubeletrequires these credentials to pull all Red Hat Developer Hub container images, including the Developer Lightspeed for RHDH sidecar images.
Procedure
Extract the deployment configurations from the official Operator bundle:
BUNDLE_IMAGE="registry.redhat.io/rhdh/rhdh-operator-bundle:1.10" CONTAINER_ID=$(podman create "${BUNDLE_IMAGE}") podman cp $CONTAINER_ID:/manifests/rhdh-flavour-lightspeed-config_v1_configmap.yaml ./lightspeed-config.yaml podman rm $CONTAINER_IDIdentify the initialization and sidecar container image tags from the extracted configuration file:
LS_RAG_IMAGE=$(yq '.data["deployment.yaml"]' lightspeed-config.yaml | yq '.spec.template.spec.initContainers[] | select(.name == "init-rag-data") | .image') LS_CORE_IMAGE=$(yq '.data["deployment.yaml"]' lightspeed-config.yaml | yq '.spec.template.spec.containers[] | select(.name == "lightspeed-core") | .image')
Mirror the images to your internal registry by running the
skopeo copycommand:skopeo copy docker://${LS_RAG_IMAGE} docker://<mirror_registry>/<ls_rag_repo>@<digest> skopeo copy docker://${LS_CORE_IMAGE} docker://<mirror_registry>/<ls_core_repo>@<digest>
12.2.2.9. Mirror Developer Lightspeed for RHDH images for Helm deployments on OpenShift Container Platform
Mirror the required Developer Lightspeed for RHDH container images to your local registry by using the oc-mirror plugin when deploying the Helm chart on an OpenShift Container Platform cluster.
Prerequisites
- You have a target mirror registry accessible to your disconnected OpenShift Container Platform cluster.
- You authenticated to the Red Hat Container Registry and your target mirror registry.
-
You have configured image pull authentication for your mirror registry as described in Install Red Hat Developer Hub on OpenShift Container Platform in an air-gapped environment with the Helm chart. The
kubeletrequires these credentials to pull all Red Hat Developer Hub container images, including the Developer Lightspeed for RHDH sidecar images.
Procedure
Identify the initialization and sidecar container images from the default values file of the chart:
helm show values redhat-developer-hub --repo https://charts.openshift.io/ --version 1.10.1 > values.default.yaml LS_RAG_IMAGE=$(yq '.global.lightspeed.initContainer.image | .registry + "/" + .repository' values.default.yaml) LS_RAG_DIGEST=$(yq '.global.lightspeed.initContainer.image.tag' values.default.yaml) LS_CORE_IMAGE=$(yq '.global.lightspeed.sidecar.image | .registry + "/" + .repository' values.default.yaml) LS_CORE_DIGEST=$(yq '.global.lightspeed.sidecar.image.tag' values.default.yaml)
Add these images to the
additionalImagessection of yourImageSetConfigurationfile:apiVersion: mirror.openshift.io/v2alpha1 kind: ImageSetConfiguration mirror: additionalImages: - name: ${LS_RAG_IMAGE}:${LS_RAG_DIGEST} - name: ${LS_CORE_IMAGE}:${LS_CORE_DIGEST} helm: repositories: - name: openshift-charts url: https://charts.openshift.io charts: - name: redhat-developer-hub version: "1.10"
12.2.2.10. Mirror Developer Lightspeed for RHDH images for Helm deployments on Kubernetes
Isolate image references, copy them manually to your internal registry, and update your configuration file when deploying the Helm chart on non-OpenShift platforms.
Prerequisites
- You have a target mirror registry accessible to your disconnected cluster.
- You authenticated to the Red Hat Container Registry and your target mirror registry.
-
You have configured image pull authentication for your mirror registry as described in Install Red Hat Developer Hub on a supported Kubernetes platform in an air-gapped environment with the Helm chart. The
kubeletrequires these credentials to pull all Red Hat Developer Hub container images, including the Developer Lightspeed for RHDH sidecar images.
Procedure
Extract the image references from the default values file of the chart:
$ helm show values redhat-developer-hub --repo https://charts.openshift.io/ --version 1.10.1 > values.default.yaml LS_RAG_IMAGE=$(yq '.global.lightspeed.initContainer.image | .registry + "/" + .repository' values.default.yaml) LS_RAG_DIGEST=$(yq '.global.lightspeed.initContainer.image.tag' values.default.yaml) LS_CORE_IMAGE=$(yq '.global.lightspeed.sidecar.image | .registry + "/" + .repository' values.default.yaml) LS_CORE_DIGEST=$(yq '.global.lightspeed.sidecar.image.tag' values.default.yaml)
Mirror the images to your internal mirror registry:
skopeo copy --all docker://${LS_RAG_IMAGE}:${LS_RAG_DIGEST} docker://<mirror_registry_name>/<ls_rag_repo_name>:${LS_RAG_DIGEST} skopeo copy --all docker://${LS_CORE_IMAGE}:${LS_CORE_DIGEST} docker://<mirror_registry_name>/<ls_core_repo_name>:${LS_CORE_DIGEST}Update your custom Helm values file with the mirrored registry locations and plugin references. Mirror the dynamic plugins to the local registry before you add their package paths to the file. For mirroring instructions, see Mirroring Red Hat Developer Hub dynamic plugins in disconnected environments:
global: lightspeed: initContainer: image: registry: "<mirror_registry_name>" repository: <ls_rag_repo_name> tag: "${LS_RAG_DIGEST}" sidecar: image: registry: "<mirror_registry_name>" repository: <ls_core_repo_name> tag: "${LS_CORE_DIGEST}" plugins: - package: "oci://<mirror_registry_name>/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed@<ls_frontend_digest>" disabled: false - package: "oci://<mirror_registry_name>/rhdh/red-hat-developer-hub-backstage-plugin-lightspeed-backend@<ls_backend_digest>" disabled: false
Additional resources
12.2.3. Build a private knowledge base with Lightspeed Notebooks
12.2.3.1. Build a private knowledge base with Lightspeed Notebooks
Use Developer Lightspeed for RHDH Notebooks to research, troubleshoot, and analyze projects by using a large language model (LLM) grounded in your own documentation. Notebooks use Retrieval-Augmented Generation (RAG) to ensure that responses are based strictly on the files you upload.
12.2.3.2. Solve project-specific challenges
Configure Red Hat Developer Hub and Red Hat Developer Lightspeed for Red Hat Developer Hub to provide users with private, document-based AI workspaces.
Prerequisites
- A deployed instance of RHDH.
-
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. - A Lightspeed Stack service is running and accessible to the backend.
- A supported large language model (LLM), such as Granite 7B or higher, is available.
Procedure
Enable the notebook feature and define your model by adding the following configuration to your
app-config.yamlfile:lightspeed: notebooks: enabled: true queryDefaults: model: ${NOTEBOOKS_QUERY_MODEL} # Use the exact model name provider_id: ${NOTEBOOKS_QUERY_PROVIDER_ID}NoteIf the model name is incorrect, an error message appears in the logs and the user interface.
Grant user access through role-based access control (RBAC) policies by defining permissions in your
rbac-policy-csvfile:Add the permission policy:
p, role:default/_<your_team_name>_, lightspeed.notebooks.use, update, allow
Assign the role to specific users:
g, user:default/_<your_user_name>_, role:default/_<your_team_name>_
- Apply the updated configuration and restart the service.
Verification
- Log in to RHDH using an account assigned to the RBAC role defined in the configuration.
- Confirm that the Notebooks tab is visible next to the Chat tab in the primary navigation bar.
- Click the Notebooks tab and ensure the My Notebooks dashboard loads without error messages.
12.2.3.3. Enable data persistence for Developer Lightspeed for RHDH Notebooks
To persist Notebook sessions, documents, and AI history across service restarts, you must configure the Notebooks storage backends to use persistent volumes.
By default, the service uses ephemeral storage in the /tmp directory, which the system clears during a pod restart.
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. - You have authored and provisioned a custom config map for your deployment. For more information, see link:Provision your custom Red Hat Developer Hub configuration.
-
A Persistent Volume Claim (PVC) is provisioned in your cluster and mounted to the LCORE container (for example, at
/var/lib/lightspeed-data).
Procedure
Update your custom config map
llama-stack-configs/config.yamlfile to point thekv_notebooksstorage backend to your persistent mount point:spec: initContainers: - name: init-notebooks-dir # ... complete init container containers: - name: lightspeed-core image: quay.io/lightspeed-core/lightspeed-stack:0.5.1 ports: - containerPort: 8080 volumeMounts: - name: notebooks-storage mountPath: /var/lib/lightspeed-data - name: config # ← Added all ConfigMap mounts mountPath: /app-root/config.yaml subPath: config.yaml - name: lightspeed-config mountPath: /app-root/lightspeed-stack.yaml subPath: lightspeed-stack.yaml - name: profile mountPath: /app-root/rhdh-profile.py subPath: rhdh-profile.py livenessProbe: # ← Added health checks httpGet: path: /readiness port: 8080 readinessProbe: httpGet: path: /readiness port: 8080 volumes: # ← Added all volume definitions - name: notebooks-storage persistentVolumeClaim: claimName: lightspeed-notebooks-pvc - name: config configMap: name: llama-stack-config - name: lightspeed-config configMap: name: lightspeed-core-config - name: profile configMap: name: rhdh-profileUpdate your deployment manifest to include the init container, volume mounts, and volume definitions:
spec: template: spec: initContainers: - name: init-notebooks-storage image: registry.access.redhat.com/ubi9/ubi-minimal command: ["sh", "-c", "mkdir -p /var/lib/lightspeed-data/notebooks && chmod -R 777 /var/lib/lightspeed-data/notebooks"] volumeMounts: - name: lightspeed-notebooks mountPath: /var/lib/lightspeed-data containers: - name: lightspeed-stack image: quay.io/lightspeed-core/lightspeed-stack:0.5.1 ports: - containerPort: 8080 volumeMounts: - name: lightspeed-notebooks mountPath: /var/lib/lightspeed-data - name: config mountPath: /app-root/config.yaml subPath: config.yaml livenessProbe: httpGet: path: /readiness port: 8080 readinessProbe: httpGet: path: /readiness port: 8080 volumes: - name: lightspeed-notebooks persistentVolumeClaim: claimName: lightspeed-notebooks-pvc - name: config configMap: name: llama-stack-config- Apply the updated configuration and restart the service.
Verification
- In Red Hat Developer Hub, create a Notebook and upload a test document.
- Send a message to the virtual assistant and verify that the response is based on the document.
Restart the pod:
$ oc delete pod <pod_name>
- After the pod recovers, refresh the My Notebooks dashboard.
- Verify that the Notebook and the uploaded file are still accessible.
12.2.4. Large language model (LLM) requirements
To plan your Developer Lightspeed for RHDH deployment, you must determine which compatible large language model (LLM) inference provider fits your infrastructure.
Developer Lightspeed for RHDH operates on a Bring Your Own Model (BYOM) architecture. Because the service does not include a native model, you must connect a compatible inference provider during installation.
The underlying LCORE service integrates with platforms that support either the OpenAI API specification or the vLLM inference engine. Developer Lightspeed for RHDH supports the following inference provider configurations:
- OpenAI: Cloud-based inference services.
- vLLM: Enterprise inference servers, which include models hosted on Red Hat OpenShift AI and Red Hat Enterprise Linux AI.
- Ollama: Desktop inference servers.
- Gemini: Services through Vertex AI.
When configuring your deployment, you must account for the following provider behaviors:
- Red Hat OpenShift AI routing: Because the configuration lacks an explicit Red Hat OpenShift AI provider option, you must route these deployments through the vLLM provider settings.
-
vLLM URL syntax: The
vllmprovider type communicates with endpoints that conform to the OpenAI API schema. You must manually append/v1to the configured provider URL because the system does not add it automatically. This configuration also applies to other hosted, OpenAI-compliant inference providers.
12.2.5. OpenAI model integration for your deployment
Use OpenAI models to provide generative artificial intelligence (AI) inference services, such as GPT 5, for your Developer Lightspeed for RHDH deployment.
The system connects directly to the OpenAI API platform to route user prompts and return model insights. To configure this large language model (LLM) provider, you must have an active API key generated from your OpenAI developer account.
Additional resources
12.2.6. Ollama model integration requirements
To integrate the open-source Ollama framework with Developer Lightspeed for RHDH, you must ensure that your network topology allows the Developer Lightspeed for RHDH service to route traffic to the Ollama server endpoint.
The Ollama server operates as a containerized layer, providing a command-line interface (CLI) to download, manage, and execute open-source models such as Llama 3 and Mistral. You can deploy Ollama on both local workstations and cluster environments.
However, a cluster-deployed Developer Lightspeed for RHDH instance cannot access an Ollama server that runs exclusively on a workstation localhost interface. For cluster deployments, the Ollama server must reside on an externally accessible network perimeter or run directly inside the cluster.
The following integration configurations are supported:
- Both Developer Lightspeed for RHDH and Ollama deploy on a local workstation.
- Developer Lightspeed for RHDH deploys locally and connects to an externally accessible cluster Ollama server.
- Both Developer Lightspeed for RHDH and Ollama deploy inside the cluster infrastructure.
Additional resources
12.2.7. vLLM model integration for high-throughput inference
Use the open-source vLLM high-throughput serving framework to optimize memory utilization and manage high volumes of concurrent requests for your Developer Lightspeed for RHDH deployment.
The vLLM framework operates as an enterprise inference server that optimizes memory allocation to maximize the processing efficiency of large language models (LLMs). Integrating vLLM ensures that your environment maintains high performance and responsiveness under heavy concurrent user traffic.
Additional resources
12.2.8. Vertex AI integration for Gemini models
To use Gemini models with Developer Lightspeed for RHDH, you can configure Google Cloud Vertex AI to act as your managed large language model (LLM) inference provider.
The underlying LCORE service connects to Vertex AI to access hosted Gemini models. This integration provides Developer Lightspeed for RHDH with enterprise-grade language processing and chat assistance capabilities without requiring you to maintain a local inference server.
Additional resources
12.2.9. Manage user data security
Review data routing and privacy practices to evaluate how Developer Lightspeed for RHDH handles chat messages and operational information transmitted to large language model (LLM) providers.
Developer Lightspeed for RHDH sends your chat messages directly to your configured large language model (LLM) provider. Because these messages can contain sensitive operational data regarding your cluster, users, or business environment, ensure that your provider compliance policies align with your organizational security standards.
Developer Lightspeed for RHDH has limited capabilities to filter or redact the information you submit during user interactions. To mitigate data exposure risks, do not enter proprietary or confidential information into Developer Lightspeed for RHDH. To encourage user compliance, Developer Lightspeed for RHDH displays a mandatory warning at the start of each sessions, reminding users to omit personal or sensitive details.
12.2.10. User feedback collection
Review how Developer Lightspeed for RHDH collects and isolates user feedback data within your cluster to manage local storage requirements and data privacy standards.
Developer Lightspeed for RHDH saves user feedback submissions, including numerical ratings and text commentary, locally within the pod filesystem. Because Red Hat does not collect, access, or transmit this data, local platform administrators must manage and monitor these storage directories.
12.2.11. Bring Your Own Model integration
Review Bring Your Own Model (BYOM) requirements to select and integrate an OpenAI API-compatible inference service with Lightspeed Core Service.
Developer Lightspeed for RHDH relies on a BYOM architecture that let you connect the Lightspeed Core Service (LCORE) layer to any OpenAI API-compatible inference platforms. To establish connection compatibility, your chosen inference service must satisfy the following technical criteria:
- The service must conform to the OpenAI API specification for chat completions.
- The host environment must match the specified infrastructure configuration and installation instructions.
Various commercial and open-source inference services support the OpenAI API specification. Because operational costs, performance metrics, and data security controls vary by provider, you must evaluate and test prospective platforms locally to select the service that best meets your organizational requirements.
Additional resources
12.2.12. Your compliance and data-sharing responsibility
Review compliance requirements and data-sharing responsibilities to ensure that user interactions with Developer Lightspeed for RHDH align with your organization’s data privacy policies.
All data that users submit through prompts and responses within Developer Lightspeed for RHDH is transmitted directly to your configured large language model (LLM) inference service. Platform administrators must ensure that these external data transfers comply with corporate security standards, governance frameworks, and local data protection policies.
12.2.13. Configure Model Context Protocol tools to enhance AI interactions with portal data
12.2.13.1. Configure Model Context Protocol tools to enhance AI interactions with portal data
Leverage the Model Context Protocol (MCP) server to integrate Red Hat Developer Hub with AI clients through a standardized method for accessing RHDH information and workflows using defined MCP tools.
12.2.13.2. Connect AI applications to external systems using MCP
Model Context Protocol (MCP) connects AI applications to external systems, enabling Developer Hub MCP tools through the mcp-actions-backend plugin.
This section describes Developer Preview features in the Model Context Protocol plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
Model Context Protocol (MCP) connects AI models and applications (MCP clients) to external systems (MCP servers) to access information and workflows. MCP servers define the tools that MCP clients can interact with. Red Hat Developer Hub (RHDH) supports MCP tools through the mcp-actions-backend plugin available in Backstage 1.40 or later.
You must verify that your model supports tool calling before you enable Model Context Protocol (MCP) features. Using an incompatible model results in error messages.
12.2.13.3. Install MCP server plugins
To run MCP tools within RHDH, you must add the MCP server plugin to your configuration. This installation enables the backend infrastructure required to manage MCP actions.
Prerequisites
- Your RHDH instance is installed and running.
Procedure
In your dynamic plugins ConfigMap (for example,
dynamic-plugins-rhdh.yaml), add the updated MCP server plugin:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-plugin-mcp-actions-backend:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Verification
- Confirm the plugins are active by checking the RHDH logs for "loaded" status messages, or by verifying that the corresponding MCP tools appear in your product tool registry.
12.2.13.4. Install the MCP tool plugins
Install individual extras plugins to expose specific capabilities for the Software Catalog, TechDocs, and Scaffolder features.
The previous MCP plugins (software-catalog-mcp-tool and techdocs-mcp-tool) are deprecated and no longer updated. You must use the new extras versions listed in the following procedure to receive updates and new features.
Prerequisites
- Your RHDH instance is installed and running.
Procedure
Install any of the following MCP tools that you want to use:
Software Catalog MCP extras:
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-software-catalog-mcp-extras:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
TechDocs MCP extras:
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-techdocs-mcp-extras:<tag> disabled: false
where:
<tag>Enter your RHDH version of Backstage and the plugin version, in the format
bs_<backstage-version>__<plugin-version>(note the double underscore delimiter). To find these versions, complete the following steps:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Scaffolder MCP extras:
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scaffolder-mcp-extras:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Verification
- Confirm the plugins are active by checking the RHDH logs for "loaded" status messages, or by verifying that the corresponding MCP tools appear in your product tool registry.
12.2.13.5. Configure MCP tokens and endpoints
12.2.13.5.1. Configure MCP tokens and endpoints
When using third-party MCP integrations, you can store your personal access tokens securely and manage credentials in Red Hat Developer Lightspeed for Red Hat Developer Hub so that the AI acts on your behalf.
12.2.13.5.2. Configure MCP tokens and endpoints to authorize client access
Configure Model Context Protocol (MCP) server endpoints, database backends, and authentication tokens to securely authorize client applications to interact with your developer portal.
This configuration is a prerequisite for MCP clients to use the defined MCP tools and access the exposed capabilities of RHDH.
Prerequisites
Procedure
In your Red Hat Developer Hub
app-config.yamlfile, configure a static token for authentication against the MCP server endpoint. MCP clients (such asCursor,Continue, orLightspeed Core) use these tokens to authenticate against the Backstage MCP server. For example:backend: auth: externalAccess: - type: static options: token: ${MCP_TOKEN} subject: mcp-clientswhere:
${MCP_TOKEN}Set the token value that you generate manually and share with your MCP clients.
NoteTokens must be long and complex strings without whitespace to prevent brute-force guessing.
- To generate a sample token, use the following command:
$ node -p `require("crypto").randomBytes(24).toString("base64")`
Register the MCP tools that you install as a plugin source in your
app-config.yamlfile:To use the installed
extrasplugins, you must register them as plugin sources:backend: actions: pluginSources: - software-catalog-mcp-extras - techdocs-mcp-extras - scaffolder-mcp-extrasTo fetch entities or manage components, you must register the catalog plugin source. If your workflow requires scaffolding tools, you must also register the scaffolder plugin source. These plugins are optional and required only when using these specific tools.
backend: actions: pluginSources: - catalog - scaffolderIf you are using OpenAI models with the RHDH MCP server, add the following configuration to your
app-config.yamlfile to disable namespaced toolnames:mcpActions: namespacedToolNames: false
# Full
app-config.yamlfile example with MCP configuration app: title: AI Dev Developer Hub baseUrl: "${RHDH_BASE_URL}" auth: environment: development session: secret: "${BACKEND_SECRET}" providers: guest: dangerouslyAllowOutsideDevelopment: true backend: actions: pluginSources: - software-catalog-mcp-extras - techdocs-mcp-extras - scaffolder-mcp-extras - catalog - scaffolder auth: externalAccess: - type: static options: token: ${MCP_TOKEN} subject: mcp-clients keys: - secret: "${BACKEND_SECRET}" baseUrl: "${RHDH_BASE_URL}" cors: origin: "${RHDH_BASE_URL}" signInPage: oidc
12.2.13.5.3. Configure MCP clients to access the RHDH server
Configure Model Context Protocol (MCP) client applications with server URLs and authentication to enable interaction with the RHDH server.
You must configure an MCP client before it can interact with the MCP server. For a list of supported clients and their specific configurations, see Example Clients.
Prerequisites
You have one of the following endpoints for the server URL, where
<my_developer_hub_domain>is the hostname of your RHDH instance.-
Streamable:
https://<my_developer_hub_domain>/api/mcp-actions/v1 SSE (Legacy):
`https://<my_developer_hub_domain>/api/mcp-actions/v1/sseNoteSome clients do not yet support the Streamable endpoint. Use the SSE (Legacy) endpoint if your client requires it.
-
Streamable:
-
You have set the
MCP_TOKENenvironment variable in your MCP server configuration as the bearer token for authentication.
Procedure
Configure Developer Lightspeed for RHDH as a client. For more details, see {developer-lightspeed-link}[Red Hat Developer Lightspeed for Red Hat Developer Hub].
In the
lightspeed-stack.yamlconfiguration, add the followingmcp_serversconfiguration:mcp_servers: - name: mcp::backstage provider_id: model-context-protocol url: https://<my_developer_hub_domain>/api/mcp-actions/v1 authorization_headers: Authorization: "client"model-context-protocol-
Enter the tool runtime provider defined in the llama-stack
run.yamlconfiguration for LCORE.
Optional: To use a custom Llama Stack configuration, add the following code to the
run.yamlLlama Stack configuration file.providers: tool_runtime: - provider_id: model-context-protocol provider_type: remote::model-context-protocol config: {}To authorize requests to the MCP endpoint using
<MCP_TOKEN>, add one or more servers to themcpServerslist in the Developer Lightspeed for RHDHapp-config.yamlfile, to make POST requests to LCORE:lightspeed: mcpServers: - name: mcp::backstage token: ${MCP_TOKEN} - name: _<mcp_server_name>_ token: ${MCP_TOKEN_2}where:
name- Enter the server name. This must match the name configured in the LCORE.
token- Optional: Enter the static token used to authorize requests. You can also configure the token through the MCP Server Settings in the Developer Lightspeed for RHDH user interface. The setting remains disabled until you configure the token.
Optional: Query the LCORE
/v1/streaming_queryendpoint directly by providing theMCP_TOKENin the header:curl -X POST \ -H `Content-Type: application/json` \ -H `MCP-HEADERS: {"mcp::backstage": {"Authorization": "Bearer <MCP_TOKEN>"}}` \ -d `{"query": "Can you give me all catalog templates of type 'service', "model": "gpt-4o-mini", "provider": "openai"}` \ _<url>_/v1/streaming_querywhere:
<url>-
Enter the LCORE endpoint. Use
localhostor the service namepass:c,a,q:[<RHDH_servicename>.my-rhdh-project.svc.cluster.local:8080]if you are inside the Backstage container.
Configure Cursor as a client.
From your Desktop app, navigate to Cursor Settings, select MCP Tools > New MCP Server and add the following configuration:
{ "mcpServers": { "backstage-actions": { "url": "https://<my_developer_hub_domain>/api/mcp-actions/v1", "headers": { "Authorization": "Bearer <mcp_token>" } } } }where:
<mcp_token>- Enter the previously configured static token
<my_developer_hub_domain>- Enter the hostname of your RHDH instance
Configure Continue as a client.
In your agent yaml configuration file, add the following configuration:
mcpServers: - name: backstage-actions type: sse url: https://<my_developer_hub_domain>/api/mcp-actions/v1/sse requestOptions: headers: Authorization: "Bearer <mcp_token>"where:
<mcp_token>- Enter the previously configured static token
<my_developer_hub_domain>- Enter the hostname of your RHDH instance
12.2.13.5.4. Enable encryption and database storage for tokens
To protect sensitive credentials and persist user preferences, you must configure encryption and database settings in the app-config.yaml file.
Configuring encryption prevents the system from storing Model Context Protocol (MCP) tokens as plain text in the database.
Prerequisites
- You have administrator access to the RHDH environment.
-
Your backend secet is available in the
BACKEND_SECRETenvironment variable.
Procedure
To enable encryption for MCP server tokens, add the following snippet to the
backendsection of yourapp-config.yamlfile:backend: auth: keys: - secret: ${BACKEND_SECRET}To store MCP server user preferences, configure the database connection. Use the configuration example that matches your environment:
Local development (In-memory):
backend: database: client: better-sqlite3 connection: ':memory:'Local path storage:
backend: database: client: better-sqlite3 connection: directory: './sqlite-data'Deployed PostgreSQL database:
backend: database: client: pg connection: host: localhost port: 5432 user: ${POSTGRES_USER} password: ${POSTGRES_PASSWORD}
Verification
-
Restart the RHDH instance and ensure no errors appear in the logs related to the
backend-authordatabaseplugins.
12.2.13.5.5. Toggle MCP tools in the chat interface
Use the Red Hat Developer Lightspeed for Red Hat Developer Hub chat interface options to securely configure your personal tokens, toggle specific Model Context Protocol (MCP) services, and directly control the data context made available to the AI assistant.
You can use the MCP settings panel in the Developer Lightspeed for RHDH chat interface to review server status and enable or disable specific tools for your session.
Prerequisites
- An administrator has configured encryption and database storage for the backend.
- You have a valid Personal Access Token for the MCP servers you want to enable.
Procedure
- In the Red Hat Developer Lightspeed for Red Hat Developer Hub chat box, click the Chatbot options menu icon in the header.
Select MCP settings.

In the MCP settings panel, perform any of the following actions to configure your session:
- Review server status: View whether available MCP servers are enabled or disabled.
- View available tools: View the count of specific tools available for each server under Status.
Configure personal tokens:
- To add or update a token, click the Edit icon, enter your Personal Access Token in the field, and click Save. The system validates the token automatically.
To remove or replace a token, click the Edit icon and select Forget Token.

Enable or disable servers: Use the toggles to select which servers provide tools for your chat session.
NoteYou must configure a token before you can enable a server that requires authentication.
Verification
- Submit a query in the chat that requires an MCP tool, such as requesting catalog resources or server information.
- If you enabled a server, verify that the response contains data from that specific MCP tool.
- If you disabled a server, verify that Developer Lightspeed for RHDH uses standard documentation or general knowledge instead of the MCP tool to provide the response.
12.2.13.6. Enable Software Catalog MCP tools
12.2.13.6.1. Enable Software Catalog MCP tools
Install the Model Context Protocol (MCP) server and its associated tool plugins to expose Red Hat Developer Hub portal capabilities, such as the Software Catalog and TechDocs, to your external AI assistant.
12.2.13.6.2. Enable Software Catalog MCP tools to allow the AI to query component metadata
Enable and use the Software Catalog MCP tools so that the AI assistant can seamlessly query internal software component metadata, relations, and ownership information on your behalf.
Use Software Catalog MCP tools to manage and retrieve RHDH entities such as Components, Systems, Resources, APIs, Locations, Users, and Groups.
Software Catalog tool reference:
The software-catalog-mcp-extras plugin provides tools to interact with the software catalog. By default, these tools return data in a JSON array format.
The following table lists the available tools in the software-catalog-mcp-tool plugin:
| Tool | Description | Parameters |
|---|---|---|
|
|
Lists RHDH entities such as components, APIs, and resources. |
|
|
|
Registers a new entity in the software catalog using a |
|
|
|
Removes an existing entity from the software catalog. |
|
|
|
Retrieves metadata for a specific software template. |
|
12.2.13.6.3. Fetch entities using fetch-catalog-entities
List Developer Hub entities including components, APIs, and resources using the fetch-catalog-entities tool.
The fetch-catalog-entities tool lists RHDH entities, including components, APIs, and resources.
Common query examples: * "Fetch all ai-model resources in the Backstage catalog" * "Fetch the API definition for the beneficiary-management-api API" * "Construct a curl command based on the API definition for the “insert beneficiary” endpoint in the beneficiary-management-api"
The following table lists the parameters for the fetch-catalog-entities tool:
| Parameter | Description | Example |
|---|---|---|
|
|
Filters by entity kind. |
|
|
|
Filters by entity type. [NOTE]: You must use the |
|
|
|
Specifies a specific entity name. |
|
|
|
Filters entities by their owner. |
|
|
|
Filters entities by their lifecycle. |
|
|
|
Filters entities by their tags. |
|
|
|
Retrieves the full Backstage entity object instead of a shortened output when set to |
|
12.2.13.6.4. Register entities using catalog-register-tool
Add new entities to the Software Catalog using the catalog-register-tool.
Use the catalog-register-tool to add new entities to your Software Catalog.
Table 12.1. catalog-register-tool parameters
| Parameter | Description |
|---|---|
|
|
The URL to the |
12.2.13.6.5. Unregister entities using catalog-unregister-tool
Remove existing entities from the Software Catalog using the catalog-unregister-tool.
Use the catalog-unregister-tool to remove an existing entity from the Software Catalog.
The following table lists the parameters for the catalog-unregister-tool:
| Parameter | Description |
|---|---|
|
|
A valid catalog location URL or a UUID. |
12.2.13.6.6. Retrieve Software Template metadata
Retrieve metadata for specific Software Templates using the software-template-metadata-tool.
Use the software-template-metadata-tool to retrieve metadata for a specific Software Template.
The following table lists the parameters for the software-template-metadata-tool:
| Parameter | Description |
|---|---|
|
|
The reference identifier for the Software Template. |
12.2.13.7. Enable TechDocs MCP tools
12.2.13.7.1. Enable TechDocs MCP tools
Install the Model Context Protocol (MCP) server and its associated tool plugins to expose Red Hat Developer Hub portal capabilities, such as the Software Catalog and TechDocs, to your external AI assistant.
12.2.13.7.2. Enable TechDocs MCP tools to allow the AI to read and analyze internal documentation
Enable and use TechDocs MCP tools to allow the AI assistant to search, read, and analyze your internal technical documentation to resolve queries with accurate portal data.
The TechDocs MCP tool enables MCP clients to search and retrieve documentation from RHDH for use as context in AI applications.
The following table lists the TechDocs tools and parameters:
| Tool | Description | Parameters |
|---|---|---|
|
|
Lists all entities with registered TechDocs. Includes metadata such as |
|
|
|
Calculates the percentage of entities with TechDocs configured to identify documentation gaps. |
|
|
|
Retrieves the content of a specific TechDocs resource. |
|
12.2.13.7.3. Retrieve TechDocs URLs and metadata using fetch-techdocs
List all Backstage entities with TechDocs including URLs, metadata, timestamps, and build information using the fetch-techdocs tool.
The fetch-techdocs TechDocs MCP tool lists all Backstage entities with TechDocs. By default, the tool returns results in a JSON array format. Each entry includes entity details and TechDocs metadata, like last update timestamp and build information.
By default, each entry in the JSON array is an entity with the following fields: name, title, tags, description, owner, lifecycle, namespace, kind, techDocsUrl, matadataUrl, and metadata.
The following examples show common queries:
- “Fetch all techdocs from the Backstage server”
- “Fetch all techdocs of the default namespace”
- “Fetch all techdocs created by user:john.doe”
Table 12.2. fetch-techdocs TechDocs MCP tool.
| Name | Description | Example |
|---|---|---|
|
|
Filters entities by their type. |
"Component" |
|
|
Filter entities by their namespace. |
"default" |
|
|
Filters entities by owner. |
"user:john.doe" |
|
|
Filters entities by their lifecycle. |
"development" |
|
|
Filters entities by their tags. |
["genai, "ibm", "llm", "granite", "conversational", "task-text-generation"] |
12.2.13.7.4. Measure documentation gaps using analyze-techdocs-coverage
Calculate documentation coverage percentage and identify gaps using the analyze-techdocs-coverage tool with entity attribute filters.
The analyze-techdocs-coverage TechDocs MCP tool calculates the percentage of entities that have TechDocs configured. Use this tool to identify documentation gaps and improve overall documentation coverage.
You can filter results by the following entity attributes: * type * namespace * owner * lifecycle * tags By default, analyze-techdocs-coverage returns a JSON entity that includes the totalEntities, entitiesWithDocs, and coveragePercentage fields.
The following examples show common queries:
- “What is the coverage of techdocs in the backstage server”
- “What is the coverage of techdocs in the default namespace”
The following table lists the parameters for the analyze-techdocs-coverage TechDocs MCP tool:
| Name | Description | Example |
|---|---|---|
|
|
Filters entities by their type. |
"Component" |
|
|
Filter entities by their namespace. |
"default" |
|
|
Filters entities by owner. |
"user:john.doe" |
|
|
Filters entities by their lifecycle. |
"development" |
|
|
Filters entities by their tags. |
["genai, "ibm", "llm", "granite", "conversational", "task-text-generation"] |
12.2.13.7.5. Find a specific TechDoc using retrieve-techdocs-content
Retrieve TechDocs content for specific Software Catalog entities using the retrieve-techdocs-content tool with entityRef, name, title, and content fields.
The retrieve-techdocs-content TechDocs MCP tool retrieves the content of a TechDocs resource, enabling AI clients to access documentation content for specific Software Catalog entities. By default, the tool returns a JSON entity with the following fields: entityRef, name, title, kind, namespace, content, path, contentType, lastModified, and metadata.
The following examples show common queries:
- “Fetch techdoc with reference component:default/my-service”
- “Fetch page about.html from techdoc with reference component:default/my-service”
The following table describes the parameters for the retrieve-techdocs-content TechDocs MCP tool.
| Name | Description | Example |
|---|---|---|
|
|
Specifies the entity to retrieve using the |
"component:default/my-service" |
|
|
Specifies the path to a specific documentation page. Defaults to |
"index.html" |
12.2.13.8. Enable Scaffolder MCP tools
12.2.13.8.1. Enable Scaffolder MCP tools
Use the Scaffolder Model Context Protocol (MCP) (scaffolder-mcp-extras) tools to query available actions, validate template dry-runs, and retrieve task logs during Software Template development in RHDH.
12.2.13.8.2. Automate software resource creation
With Software Template validation, you can verify YAML configuration and execution logic in a sandboxed environment. This preliminary testing ensures that your templates function as intended before you deploy them to a production environment.
The validation process involves the following key components:
- User interaction: You must provide the template YAML content, required input values, and any additional files.
-
Agent invocation: The AI agent maps these inputs to the
templateYAML,values, andfilesparameters to call the dry-run tool. -
Outcome processing: The AI agent interprets the
validstatus and execution logs to provide a plain-language summary or troubleshooting steps if validation fails.
12.2.13.8.3. Scaffolder dry-run tool reference
Use this tool to perform a sandboxed dry-run execution of a Scaffolder template.
The following table describes the input fields:
| Input parameter | Description | Example |
|---|---|---|
|
|
Full YAML content of the template. |
|
|
|
Key-value map of required input values. |
|
|
|
Additional files including path and content. |
|
The following table describes the output fields:
| Output field | Description | Example |
|---|---|---|
|
|
Boolean indicating if the template passed validation. |
|
|
|
Summary of the dry-run result. |
|
|
|
List of error messages if |
|
|
|
List of execution log objects. | |
|
|
Log message text from the dry run. |
|
|
|
ID of the step associated with the log. |
|
|
|
Step status, such as |
|
|
|
Template output produced by the dry run. |
|
|
|
List of execution step objects. | |
|
|
ID of the step. |
|
|
|
Display name of the step. |
|
|
|
Action identifier used by the step. |
|
12.2.13.8.4. Software Template execution with Scaffolder MCP tools
Automate resource creation, such as repositories or components, by executing Software Templates through the AI agent.
By using Scaffolder MCP tools, the AI agent interacts directly with your existing software templates to streamline the development lifecycle.
The execution process relies on three core components:
-
User interaction: You must identify a reference for the target template (for example,
template:default/create-node) and provide the necessary inputvaluesandsecrets. -
Agent invocation: The AI agent maps the data to the
templateRef,values, andsecretsparameters to execute the template. -
Outcome processing: The AI agent confirms the execution and provides the
taskIdto the user for progress tracking.
12.2.13.8.5. Scaffolder execution tool reference
Run a Software Template to create repositories, register components, or provision infrastructure.
The following table describes the inputs fields:
| Input parameter | Description | Example |
|---|---|---|
|
|
Entity reference of the target template. |
|
|
|
Key-value map of required input values. |
|
|
|
Optional: Secrets required for execution. |
|
The following table describes the output fields:
|
Output field |
Description |
|
|
ID of the created task used for log tracking. |
12.2.13.8.6. Scaffolder task monitoring with MCP tools
Scaffolder task monitoring provides visibility into the lifecycle of automated resource creation. By using MCP tools, you can track the progress of templates and retrieve execution results for workflows initiated by an AI agent.
Monitoring capabilities include the following features:
- User interaction: You must ask for a status update on your tasks or a list of recent activities.
-
Agent invocation: The AI agent calls the task list tool. To restrict results to only include your own tasks, the agent must set the
ownedparameter totrue. -
Outcome processing: The AI agent filters and summarizes the
tasks[]list, reporting statuses such asprocessing,completed, orfailed.
12.2.13.8.7. Scaffolder tasks list tool reference
Use the Scaffolder tasks list tool to retrieve and filter a list of Scaffolder tasks.
The following table describes the input fields:
| Input parameter | Description | Example |
|---|---|---|
|
|
If |
|
|
|
Maximum number of tasks to return per request. |
|
|
|
Number of tasks to skip for pagination. |
|
The following table describes the output fields:
| Output field | Description | Example |
|---|---|---|
|
|
A list of Scaffolder tasks including ID, timestamps, and status. Statuses include: |
|
12.2.13.8.8. Automate Software Templates
Use this tool to list all installed Scaffolder actions and their associated metadata. This tool requires no input parameters. The following table describes the output fields.
| Output field | Description |
|---|---|
|
|
List containing action IDs and descriptions. |
|
|
Action identifier (for example, |
|
|
Summary of the action’s function. |
|
|
JSON Schema for input parameters. |
|
|
JSON Schema for output values. |
|
|
Usage examples provided by the action. |
12.2.13.8.9. Get Scaffolder task logs
Retrieve log events for a task to monitor execution progress or diagnose template failures.
The following table describes the input parameters:
| Input parameter | Description | Example |
|---|---|---|
|
|
Unique identifier for a task. |
|
|
|
Optional: Return only events after this event ID. |
|
The following table describes the output parameters:
| Output parameter | Description | Example |
|---|---|---|
|
|
The log output for the specified task ID. Each log entry includes the message, |
|
12.2.14. Accelerate AI model discovery by integrating the OpenShift AI Connector
12.2.14.1. Accelerate AI model discovery by integrating the OpenShift AI Connector
Integrate AI models and model servers from Red Hat OpenShift AI directly into the Red Hat Developer Hub (RHDH) Catalog to provide a unified hub for discovering and consuming AI components.
12.2.14.2. How AI assets map to the Red Hat Developer Hub Catalog
This section describes Developer Preview features in the OpenShift AI Connector for Red Hat Developer Hub plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
The OpenShift AI Connector for Red Hat Developer Hub (OpenShift AI Connector for RHDH) discovers AI assets managed within Red Hat OpenShift AI. The connector automatically converts AI models and model servers into Backstage entities to provide a unified view for developer teams.
For more information on model registry components, see Overview of model registries and model catalog.
12.2.14.3. Configure AI asset mapping
12.2.14.3.1. Configure AI asset mapping
The OpenShift AI Connector for Red Hat Developer Hub (OpenShift AI Connector for RHDH) discovers AI assets managed within Red Hat OpenShift AI. The connector automatically converts AI models and model servers into Backstage entities to provide a unified view for developer teams.
12.2.14.3.2. Model-to-Entity mapping
The following table maps RHOAI components to Backstage entity kinds.
| RHOAI Artifact | RHDH/Backstage Entity Kind | RHDH/Backstage Entity Type | Purpose |
|---|---|---|---|
|
Model Server (InferenceService) |
Component |
|
Represents a running, accessible AI model endpoint. See Configuring your model-serving platform. |
|
AI Model (Model Registry Version) |
Resource |
|
Represents the specific AI model artifact, for example, |
|
Model Server API Details |
API |
|
Provides the OpenAPI/Swagger specification for the REST endpoint of the model. See Red Hat OpenShifT AI: API Tiers |
|
Model Cards |
TechDocs |
N/A |
Associates model cards from the RHOAI model catalog with the Resource entities. See Registering a model from the model catalog. |
Once the OpenShift AI Connector for RHDH is installed and connected with RHOAI, the transfer of information commences automatically.
12.2.14.3.3. Data mapping specifications
Review the key data that the connector automatically propagates from RHOAI.
InferenceServices (Component type model-server):
- URL of the OpenShift Route (if exposed).
- URL of the Kubernetes Service.
- Authentication requirement status.
Model registry (Resource type
ai-model):- Model description, asset URIs, and author or owner information.
Model catalog:
- Links to the Model Card (as RHDH TechDocs).
- Model license URL.
12.2.14.3.4. Enrich AI model metadata for enhanced Red Hat Developer Hub experience
Enrich the RHDH experience by adding custom properties to your RHOAI model metadata, so that the OpenShift AI Connector for Red Hat Developer Hub populates additional fields in the catalog entities.
For more details, see Editing model version metadata in a model registry.
| Property Key | Entity Field Populated | Description |
|---|---|---|
|
|
API Definition Tab |
The OpenAPI / Swagger JSON specification for the model REST API. |
|
|
API Type |
Correlates to supported RHDH/Backstage API types (defaults to |
|
|
TechDocs |
URL pointing to a Git repository that follows RHDH TechDocs conventions for the Model Card. Use this setting only if the Model Card to TechDocs mapping is inactive. |
|
|
Links |
The home page URL for the model. |
|
|
Owner |
Overrides the default OpenShift user as the entity owner. |
|
|
Lifecycle |
Expresses the lifecycle concept of RHDH/Backstage. |
|
|
Links |
A URL that points to usage documentation. |
|
|
Links |
A URL to the license file of the model. |
|
|
Annotations |
A key piece of metadata is the name of the model used when communicating with the model server’s REST API. OpenShift AI Connector for Red Hat Developer Hub stores this name in the |
12.2.14.4. Set up OpenShift AI Connector for Red Hat Developer Hub with Red Hat OpenShift AI
To install the OpenShift AI Connector for Red Hat Developer Hub, you must manually update your RHDH-related Kubernetes resources.
This section describes Developer Preview features in the OpenShift AI Connector for Red Hat Developer Hub plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
Prerequisites
To import model cards from the model catalog into TechDocs, you must use RHOAI 2.25.
NoteIf you upgraded to RHOAI 2.25 from an earlier version, you must manually enable the model catalog dashboard and model registry before you can import model cards.
- If you used the model catalog in earlier versions of RHOAI, TechDocs propagation does not work for any models you registered into the model registry while at those earlier versions; only models registered into model registry from a RHOAI 2.25 model catalog have their model cards transferred to RHDH as TechDocs.
- For the rest of the features, version 2.20 or later suffices. Enabling model registry and its associated dashboard allows for a user experience that more directly allows for customizing AI Model metadata. For best overall experience, RHOAI 2.25 is recommended.
For more details, see Enabling the model registry component.
Procedure
Configure RHOAI-related RBAC and credentials.
A Kubernetes
ServiceAccountand aservice-account-tokenSecret are required for the connector to retrieve data from RHOAI. The following resources must be created, replacing namespace names (ai-rhdhfor RHDH,rhoai-model-registriesfor RHOAI) as needed:ServiceAccount(rhdh-rhoai-connector). For example:apiVersion: v1 kind: ServiceAccount metadata: name: rhdh-rhoai-connector namespace: ai-rhdh
ClusterRoleandClusterRoleBinding(rhdh-rhoai-connector) to allow access to OpenShift Container Platform resources such asroutes,services, andinferenceservices. For example:# Example for `ClusterRole` apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: rhdh-rhoai-connector annotations: argocd.argoproj.io/sync-wave: "0" rules: - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - get - apiGroups: - route.openshift.io resources: - routes verbs: - get - list - watch - apiGroups: [""] resources: - serviceaccounts - services verbs: - get - list - watch - apiGroups: ["serving.kserve.io"] resources: ["inferenceservices"] verbs: ["get", "list", "watch"]# Example for `ClusterRoleBinding` apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: rhdh-rhoai-connector roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: rhdh-rhoai-connector subjects: - kind: ServiceAccount name: rhdh-rhoai-connector namespace: ai-rhdhRoleandRoleBindingto allow ConfigMap updates within the RHDH namespace (ai-rhdh). For example:# Example for `Role` and `Rolebinding` in the {product-very-short} namespace (`ai-rhdh`) apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: rhdh-rhoai-connector namespace: ai-rhdh rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: rhdh-rhoai-connector namespace: ai-rhdh roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: rhdh-rhoai-connector subjects: - kind: ServiceAccount name: rhdh-rhoai-connector namespace: ai-rhdhRoleBindingin the RHOAI namespace (rhoai-model-registries) to grant the RHDHServiceAccountread permissions to the model registry data (binding toregistry-user-modelregistry-public).# Example for `RoleBinding` in the {rhoai-short} namespace (rhoai-model-registries) apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: # if using ODH then change rhoai to odh in the name and namespace here name: rhdh-rhoai-dashboard-permissions # namespace: odh-model-registries namespace: rhoai-model-registries roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: registry-user-modelregistry-public subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:serviceaccounts:ai-rhdhSecret (
rhdh-rhoai-connector-token) of typekubernetes.io/service-account-tokenthat goes along with therhdh-rhoai-connectorServiceAccount.apiVersion: v1 kind: Secret metadata: name: rhdh-rhoai-connector-token namespace: ai-rhdh annotations: kubernetes.io/service-account.name: rhdh-rhoai-connector type: kubernetes.io/service-account-token
Update your RHDH dynamic plugin configuration. The RHDH Pod requires two dynamic plugins.
In your RHDH dynamic plugins ConfigMap, add the following code:
plugins: - disabled: false package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog:<tag> - disabled: false package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
-
Add the
Connectorsidecar containers to the RHDH Pod. - If RHDH was installed by using the Operator, modify your RHDH custom resource (CR) instance.
If RHDH was installed by using the Helm charts, modify the Deployment specification.
The system relies on three sidecar containers (OpenShift AI Connector for Red Hat Developer Hub) running alongside the
backstage-backendcontainer. Add these sidecar containers to your configuration referencing therhdh-rhoai-connector-tokenSecret:-
location: Provides the REST API for RHDH plugins to fetch model metadata. -
storage-rest: Maintains a cache of AI Model metadata in a ConfigMap calledbac-import-model. rhoai-normalizer: Acts as a Kubernetes controller and RHOAI client, normalizing RHOAI metadata for the connector. The following code block is an example:spec: template: spec: containers: - env: - name: NORMALIZER_FORMAT value: JsonArrayFormat - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace envFrom: - secretRef: name: rhdh-rhoai-connector-token image: quay.io/redhat-ai-dev/model-catalog-location-service@sha256:c4471e07be6e0dbe821613053e6264a552cacda7f8604dbf306e6ac9e81e8ab9 imagePullPolicy: Always name: location ports: - containerPort: 9090 name: location protocol: TCP volumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root workingDir: /opt/app-root/src - env: - name: NORMALIZER_FORMAT value: JsonArrayFormat - name: STORAGE_TYPE value: ConfigMap - name: BRIDGE_URL value: http://localhost:9090 - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace envFrom: - secretRef: name: rhdh-rhoai-connector-token image: quay.io/redhat-ai-dev/model-catalog-storage-rest@sha256:609f6866c7913a87c51912260803c219e564fa7dc90c2ff735ff6dfc5797bc3b imagePullPolicy: Always name: storage-rest volumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root workingDir: /opt/app-root/src - env: - name: NORMALIZER_FORMAT value: JsonArrayFormat - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace envFrom: - secretRef: name: rhdh-rhoai-connector-token image: quay.io/redhat-ai-dev/model-catalog-rhoai-normalizer@sha256:9f19742450a3a9c6d9c01d8341a20db7eb5a52a39348f488ae06b6aa49754a26 imagePullPolicy: Always name: rhoai-normalizer volumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root workingDir: /opt/app-root/src args: - '--metrics-address=:8081'Enable
Connectorin your RHDHapp-config.yamlfile. In yourBackstage `app-config.extra.yamlfile, configureEntity Providerunder thecatalog.providerssection:providers: modelCatalog: development: baseUrl: http://localhost:9090where:
modelCatalog- Specifies the name of the provider.
development-
Defines future connector capability beyond a single
baseUrl. baseUrl- For Developer Preview, this value is the only one supported. Future releases might support external routes.
12.2.14.5. Populate AI model catalog metadata
12.2.14.5.1. Populate AI model catalog metadata
Enrich the RHDH experience by adding custom properties to your RHOAI model metadata, so that the OpenShift AI Connector for Red Hat Developer Hub populates additional fields in the catalog entities.
12.2.14.5.2. Set up OpenShift AI Connector for Red Hat Developer Hub with Red Hat OpenShift AI
To install the OpenShift AI Connector for Red Hat Developer Hub, you must manually update your RHDH-related Kubernetes resources.
This section describes Developer Preview features in the OpenShift AI Connector for Red Hat Developer Hub plugin. Developer Preview features are not supported by Red Hat in any way and are not functionally complete or production-ready. Do not use Developer Preview features for production or business-critical workloads. Developer Preview features provide early access to functionality in advance of possible inclusion in a Red Hat product offering. Customers can use these features to test functionality and provide feedback during the development process. Developer Preview features might not have any documentation, are subject to change or removal at any time, and have received limited testing. Red Hat might provide ways to submit feedback on Developer Preview features without an associated SLA.
For more information about the support scope of Red Hat Developer Preview features, see Developer Preview Support Scope.
Prerequisites
To import model cards from the model catalog into TechDocs, you must use RHOAI 2.25.
NoteIf you upgraded to RHOAI 2.25 from an earlier version, you must manually enable the model catalog dashboard and model registry before you can import model cards.
- If you used the model catalog in earlier versions of RHOAI, TechDocs propagation does not work for any models you registered into the model registry while at those earlier versions; only models registered into model registry from a RHOAI 2.25 model catalog have their model cards transferred to RHDH as TechDocs.
- For the rest of the features, version 2.20 or later suffices. Enabling model registry and its associated dashboard allows for a user experience that more directly allows for customizing AI Model metadata. For best overall experience, RHOAI 2.25 is recommended.
For more details, see Enabling the model registry component.
Procedure
Configure RHOAI-related RBAC and credentials.
A Kubernetes
ServiceAccountand aservice-account-tokenSecret are required for the connector to retrieve data from RHOAI. The following resources must be created, replacing namespace names (ai-rhdhfor RHDH,rhoai-model-registriesfor RHOAI) as needed:ServiceAccount(rhdh-rhoai-connector). For example:apiVersion: v1 kind: ServiceAccount metadata: name: rhdh-rhoai-connector namespace: ai-rhdh
ClusterRoleandClusterRoleBinding(rhdh-rhoai-connector) to allow access to OpenShift Container Platform resources such asroutes,services, andinferenceservices. For example:# Example for `ClusterRole` apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: rhdh-rhoai-connector annotations: argocd.argoproj.io/sync-wave: "0" rules: - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - get - apiGroups: - route.openshift.io resources: - routes verbs: - get - list - watch - apiGroups: [""] resources: - serviceaccounts - services verbs: - get - list - watch - apiGroups: ["serving.kserve.io"] resources: ["inferenceservices"] verbs: ["get", "list", "watch"]# Example for `ClusterRoleBinding` apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: rhdh-rhoai-connector roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: rhdh-rhoai-connector subjects: - kind: ServiceAccount name: rhdh-rhoai-connector namespace: ai-rhdhRoleandRoleBindingto allow ConfigMap updates within the RHDH namespace (ai-rhdh). For example:# Example for `Role` and `Rolebinding` in the {product-very-short} namespace (`ai-rhdh`) apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: rhdh-rhoai-connector namespace: ai-rhdh rules: - apiGroups: [""] resources: ["configmaps"] verbs: ["get", "list", "watch", "create", "update", "patch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: rhdh-rhoai-connector namespace: ai-rhdh roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: rhdh-rhoai-connector subjects: - kind: ServiceAccount name: rhdh-rhoai-connector namespace: ai-rhdhRoleBindingin the RHOAI namespace (rhoai-model-registries) to grant the RHDHServiceAccountread permissions to the model registry data (binding toregistry-user-modelregistry-public).# Example for `RoleBinding` in the {rhoai-short} namespace (rhoai-model-registries) apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: # if using ODH then change rhoai to odh in the name and namespace here name: rhdh-rhoai-dashboard-permissions # namespace: odh-model-registries namespace: rhoai-model-registries roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: registry-user-modelregistry-public subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:serviceaccounts:ai-rhdhSecret (
rhdh-rhoai-connector-token) of typekubernetes.io/service-account-tokenthat goes along with therhdh-rhoai-connectorServiceAccount.apiVersion: v1 kind: Secret metadata: name: rhdh-rhoai-connector-token namespace: ai-rhdh annotations: kubernetes.io/service-account.name: rhdh-rhoai-connector type: kubernetes.io/service-account-token
Update your RHDH dynamic plugin configuration. The RHDH Pod requires two dynamic plugins.
In your RHDH dynamic plugins ConfigMap, add the following code:
plugins: - disabled: false package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog:<tag> - disabled: false package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
-
Add the
Connectorsidecar containers to the RHDH Pod. - If RHDH was installed by using the Operator, modify your RHDH custom resource (CR) instance.
If RHDH was installed by using the Helm charts, modify the Deployment specification.
The system relies on three sidecar containers (OpenShift AI Connector for Red Hat Developer Hub) running alongside the
backstage-backendcontainer. Add these sidecar containers to your configuration referencing therhdh-rhoai-connector-tokenSecret:-
location: Provides the REST API for RHDH plugins to fetch model metadata. -
storage-rest: Maintains a cache of AI Model metadata in a ConfigMap calledbac-import-model. rhoai-normalizer: Acts as a Kubernetes controller and RHOAI client, normalizing RHOAI metadata for the connector. The following code block is an example:spec: template: spec: containers: - env: - name: NORMALIZER_FORMAT value: JsonArrayFormat - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace envFrom: - secretRef: name: rhdh-rhoai-connector-token image: quay.io/redhat-ai-dev/model-catalog-location-service@sha256:c4471e07be6e0dbe821613053e6264a552cacda7f8604dbf306e6ac9e81e8ab9 imagePullPolicy: Always name: location ports: - containerPort: 9090 name: location protocol: TCP volumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root workingDir: /opt/app-root/src - env: - name: NORMALIZER_FORMAT value: JsonArrayFormat - name: STORAGE_TYPE value: ConfigMap - name: BRIDGE_URL value: http://localhost:9090 - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace envFrom: - secretRef: name: rhdh-rhoai-connector-token image: quay.io/redhat-ai-dev/model-catalog-storage-rest@sha256:609f6866c7913a87c51912260803c219e564fa7dc90c2ff735ff6dfc5797bc3b imagePullPolicy: Always name: storage-rest volumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root workingDir: /opt/app-root/src - env: - name: NORMALIZER_FORMAT value: JsonArrayFormat - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace envFrom: - secretRef: name: rhdh-rhoai-connector-token image: quay.io/redhat-ai-dev/model-catalog-rhoai-normalizer@sha256:9f19742450a3a9c6d9c01d8341a20db7eb5a52a39348f488ae06b6aa49754a26 imagePullPolicy: Always name: rhoai-normalizer volumeMounts: - mountPath: /opt/app-root/src/dynamic-plugins-root name: dynamic-plugins-root workingDir: /opt/app-root/src args: - '--metrics-address=:8081'Enable
Connectorin your RHDHapp-config.yamlfile. In yourBackstage `app-config.extra.yamlfile, configureEntity Providerunder thecatalog.providerssection:providers: modelCatalog: development: baseUrl: http://localhost:9090where:
modelCatalog- Specifies the name of the provider.
development-
Defines future connector capability beyond a single
baseUrl. baseUrl- For Developer Preview, this value is the only one supported. Future releases might support external routes.
12.2.14.5.3. Populate the API Definition tab in RHDH API entities
Because RHOAI does not expose the OpenAPI specification by default, the AI platform engineer can take the following steps to provide this information:
Prerequisites
- You have set up the OpenShift AI Connector for Red Hat Developer Hub with Red Hat OpenShift AI. For more information, see Set up OpenShift AI Connector for Red Hat Developer Hub with Red Hat OpenShift AI.
- You have a running AI model server with an accessible endpoint.
Procedure
Retrieve OpenAPI JSON: Use a tool such as
curlto fetch the specification directly from the running endpoint of the AI model server. The following command provides the precise endpoint (/openapi.json) and shows how to include aBearertoken if the model requires authentication for access.$ curl -k -H "Authorization: Bearer $MODEL_API_KEY" https://$MODEL_ROOT_URL_INCLUDING_PORT/openapi.json | jq > open-api.json
Set Property in RHOAI.
In the RHOAI dashboard, go to Model Registry and select the appropriate Model Version.
NoteRed Hat recommends using Model Version instead of Registered Model to maintain stability if the API changes between versions.
-
In the Properties section, set a key/value pair where the key is
API Specand the value is the entire JSON content from theopen-api.jsonfile.
- Propagation: The OpenShift AI Connector for Red Hat Developer Hub periodically polls the RHOAI Model Registry, propagates this JSON, and renders the interactive API documentation in the Definition tab of the RHDH API entity.
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
Integrate CI/CD and infrastructure tools with Red Hat Developer Hub to visualize deployment pipelines, track build artifacts, and monitor Kubernetes workloads.
12.3.2. Track deployment history and rollouts with Argo CD
12.3.2.1. Track deployment history and rollouts with Argo CD
The Argo CD plugin provides a visual overview of the application's status, deployment details, commit message, author of the commit, container image promoted to environment and deployment history.
12.3.2.2. Enable the Argo CD plugin
The Argo CD plugin provides a visual overview of the application's status, deployment details, commit message, author of the commit, container image promoted to environment and deployment history.
Procedure
Add Argo CD instance information to your
app-config.yamlconfigmap as shown in the following example:argocd: appLocatorMethods: - type: 'config' instances: - name: argoInstance1 url: https://argoInstance1.com username: ${ARGOCD_USERNAME} password: ${ARGOCD_PASSWORD} - name: argoInstance2 url: https://argoInstance2.com username: ${ARGOCD_USERNAME} password: ${ARGOCD_PASSWORD}NoteAvoid using a trailing slash in the
url, as it might cause unexpected behavior.Add the following annotation to the entity's
catalog-info.yamlfile to identify the Argo CD applications.annotations: ... # The label that Argo CD uses to fetch all the applications. The format to be used is label.key=label.value. For example, rht-gitops.com/janus-argocd=quarkus-app. argocd/app-selector: '${ARGOCD_LABEL_SELECTOR}'(Optional) Add the following annotation to the entity's
catalog-info.yamlfile to switch between Argo CD instances as shown in the following example:annotations: ... # The Argo CD instance name used in `app-config.yaml`. argocd/instance-name: '${ARGOCD_INSTANCE}'NoteIf you do not set this annotation, the Argo CD plugin defaults to the first Argo CD instance configured in
app-config.yaml.To enable the Argo CD plugin, set the
disabledproperty tofalsein yourdynamic-plugins.yamlfile as follows:ImportantArgo CD contains multiple plugin options you can choose from for your Argo CD configuration:
Community Argo CD:
-
@backstage-community/plugin-argocd -
@backstage-community/plugin-argocd-backend
-
Roadie Argo CD:
-
@roadiehq/backstage-plugin-argo-cd -
@roadiehq/backstage-plugin-argo-cd-backend
-
Community and Roadie plugins are comparable in functionality but have different features. For example, both versions feature scaffolder actions, however, their implementation is different: the Community version contains scaffolder actions by default, the Roadie version requires an additional plugin.
The recommended combination is to use
@backstage-community/plugin-argocdtogether with@backstage-community/plugin-argocd-backend.However, you can also combine
@roadiehq/backstage-plugin-argo-cdtogether with@roadiehq/backstage-plugin-argo-cd-backend.Mixing Community and Roadie plugins is not recommended.
plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-backstage-plugin-argo-cd-backend:<tag> disabled: false - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-argocd:<tag> disabled: false
where:
<tag>Enter your RHDH version of Backstage and the plugin version, in the format
bs_<backstage-version>__<plugin-version>(note the double underscore delimiter). To find these versions, complete the following steps:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
12.3.2.3. Enable Argo CD Rollouts
Enable advanced deployment strategies such as blue-green and canary deployments by integrating Argo CD Rollouts with the Red Hat Developer Hub Kubernetes plugin.
The optional Argo CD Rollouts feature enhances Kubernetes by providing advanced deployment strategies, such as blue-green and canary deployments, for your applications. When integrated into the backstage Kubernetes plugin, it allows developers and operations teams to visualize and manage Argo CD Rollouts seamlessly within the Developer Hub interface.
Prerequisites
The Developer Hub Kubernetes plugin (
@backstage/plugin-kubernetes) is installed and configured.- To install and configure Kubernetes plugin in Developer Hub, see Installation and Configuration guide.
-
You have access to the Kubernetes cluster with the necessary permissions to create and manage custom resources and
ClusterRoles. -
The Kubernetes cluster has the
argoproj.iogroup resources (for example, Rollouts and Analysis Runs) installed.
Procedure
In the
app-config.yamlfile in your Developer Hub instance, add the followingcustomResourcescomponent under thekubernetesconfiguration to enable Argo Rollouts and Analysis Runs:kubernetes: ... customResources: - group: 'argoproj.io' apiVersion: 'v1alpha1' plural: 'Rollouts' - group: 'argoproj.io' apiVersion: 'v1alpha1' plural: 'analysisruns'Grant
ClusterRolepermissions for custom resources.Note-
If the Developer Hub Kubernetes plugin is already configured, the
ClusterRolepermissions for Rollouts and AnalysisRuns might already be granted. -
Use the prepared manifest to give read-only
ClusterRoleaccess to both the Kubernetes and ArgoCD plugins.
-
If the
ClusterRolepermission is not granted, use the following YAML manifest to create theClusterRole:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: - apiGroups: - argoproj.io resources: - rollouts - analysisruns verbs: - get - listApply the manifest to the cluster using
kubectl:$ kubectl apply -f <your_cluster_role_file>.yaml
-
Ensure the
ServiceAccountaccessing the cluster has thisClusterRoleassigned.
-
If the Developer Hub Kubernetes plugin is already configured, the
Add annotations to
catalog-info.yamlto identify Kubernetes resources for Backstage.For identifying resources by entity ID:
annotations: ... backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
(Optional) For identifying resources by namespace:
annotations: ... backstage.io/kubernetes-namespace: <RESOURCE_NAMESPACE>
For using custom label selectors, which override resource identification by entity ID or namespace:
annotations: ... backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
NoteEnsure you specify the labels declared in
backstage.io/kubernetes-label-selectoron your Kubernetes resources. This annotation overrides entity-based or namespace-based identification annotations, such asbackstage.io/kubernetes-idandbackstage.io/kubernetes-namespace.
Add label to Kubernetes resources to enable Developer Hub to find the appropriate Kubernetes resources.
Developer Hub Kubernetes plugin label: Add this label to map resources to specific Developer Hub entities.
labels: ... backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
GitOps application mapping: Add this label to map Argo CD Rollouts to a specific GitOps application
labels: ... app.kubernetes.io/instance: <GITOPS_APPLICATION_NAME>
NoteIf using the label selector annotation (
backstage.io/kubernetes-label-selector), ensure the specified labels are present on the resources. The label selector will override other annotations such askubernetes-idorkubernetes-namespace.
Verification
- Push the updated configuration to your GitOps repository to trigger a rollout.
- Open Red Hat Developer Hub interface and navigate to the entity you configured.
- Select the CD tab and then select the GitOps application. The side panel opens.
In the Resources table of the side panel, verify that the following resources are displayed:
- Rollouts
- Analysis Runs (optional)
Expand a rollout resource and review the following details:
- The Revisions row displays traffic distribution details for different rollout versions.
- The Analysis Runs row displays the status of analysis tasks that evaluate rollout success.
12.3.2.4. Use the Argo CD plugin
You can use the Argo CD plugin to visualize the Continuous Delivery (CD) workflows in OpenShift GitOps. This plugin provides a visual overview of the application’s status, deployment details, commit message, author of the commit, container image promoted to environment and deployment history.
Prerequisites
- You have link:enabled the Argo CD plugin in RHDH.
Procedure
- Select the Catalog tab and choose the component that you want to use.
Select the CD tab to view insights into deployments managed by Argo CD.

Select an appropriate card to view the deployment details (for example, commit message, author name, and deployment history).

-
Click the link icon (
) to open the deployment details in Argo CD.
-
Click the link icon (
Select the Overview tab and navigate to the Deployment summary section to review the summary of your application’s deployment across namespaces. Additionally, select an appropriate Argo CD app to open the deployment details in Argo CD, or select a commit ID from the Revision column to review the changes in GitLab or GitHub.

12.3.3. Track build artifacts using the JFrog plugin
12.3.3.1. Track build artifacts using the JFrog plugin
Enable the JFrog Artifactory plugin to track and view build artifacts stored in your JFrog Artifactory instance.
12.3.3.2. Enable the JFrog Artifactory plugin
To enable the JFrog Artifactory plugin, set the disabled property to false.
Procedure
To enable the JFrog Artifactory plugin, set the
disabledproperty tofalsein yourdynamic-plugins.yamlfile as follows:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-jfrog-artifactory:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
12.3.3.3. Configure the JFrog Artifactory plugin
Configure proxy settings and annotations to display container images stored in your JFrog Artifactory repository.
Procedure
Set the proxy to the required JFrog Artifactory server in the app-config.yaml file as follows:
proxy: endpoints: '/jfrog-artifactory/api': target: http://<hostname>:8082 # or https://<customer>.jfrog.io headers: # Authorization: 'Bearer <YOUR TOKEN>' # Change to "false" in case of using a self-hosted Artifactory instance with a self-signed certificate secure: trueAdd the following annotation to the entity’s
catalog-info.yamlfile to enable the JFrog Artifactory plugin features in RHDH components:metadata: annotations: 'jfrog-artifactory/image-name': '<IMAGE-NAME>'
12.3.3.4. Use the JFrog Artifactory plugin
The JFrog Artifactory plugin displays information about your container images within the JFrog Artifactory registry.
Prerequisites
- Your Developer Hub application is installed and running.
- You have enabled the JFrog Artifactory plugin.
Procedure
- Open your Developer Hub application and select a component from the Catalog page.
Go to the Image Registry tab.
The Image Registry tab contains a list of container images within your JFrog Artifactory repository and related information, such as Version, Repositories, Manifest, Modified, and Size.

12.3.4. Manage identity data by integrating Keycloak
12.3.4.1. Manage identity data by integrating Keycloak
Configure schedule frequency, query parameters, and authentication methods for synchronizing Keycloak users and groups.
12.3.4.2. Enable the Keycloak plugin
Enable the Keycloak plugin to synchronize users and groups from your Red Hat Build of Keycloak realm into Red Hat Developer Hub.
Prerequisites
To enable the Keycloak plugin, you must set the following environment variables:
-
KEYCLOAK_BASE_URL -
KEYCLOAK_LOGIN_REALM -
KEYCLOAK_REALM -
KEYCLOAK_CLIENT_ID -
KEYCLOAK_CLIENT_SECRET
-
Procedure
The Keycloak plugin is pre-loaded in Developer Hub with basic configuration properties. To enable it, set the
disabledproperty tofalsein yourdynamic-plugins.yamlfile as follows:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-catalog-backend-module-keycloak:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
12.3.4.3. Configure the Keycloak plugin
Configure schedule frequency, query parameters, and authentication methods for synchronizing Keycloak users and groups.
Procedure
To configure the Keycloak plugin, add the following in your
app-config.yamlfile:scheduleConfigure the schedule frequency, timeout, and initial delay. The fields support cron, ISO duration, "human duration" as used in code.
catalog: providers: keycloakOrg: default: schedule: frequency: { minutes: 1 } timeout: { minutes: 1 } initialDelay: { seconds: 15 }userQuerySizeandgroupQuerySizeOptionally, configure the Keycloak query parameters to define the number of users and groups to query at a time. Default values are 100 for both fields.
catalog: providers: keycloakOrg: default: userQuerySize: 100 groupQuerySize: 100- Authentication
Communication between Developer Hub and Keycloak is enabled by using the Keycloak API. Username and password, or client credentials are supported authentication methods.
The following table describes the parameters that you can configure to enable the plugin under
catalog.providers.keycloakOrg.<ENVIRONMENT_NAME>object in theapp-config.yamlfile:Name Description Default Value Required baseUrlLocation of the Keycloak server, such as
https://localhost:8443/auth.""
Yes
realmRealm to synchronize
masterNo
loginRealmRealm used to authenticate
masterNo
usernameUsername to authenticate
""
Yes if using password based authentication
passwordPassword to authenticate
""
Yes if using password based authentication
clientIdClient ID to authenticate
""
Yes if using client credentials based authentication
clientSecretClient Secret to authenticate
""
Yes if using client credentials based authentication
userQuerySizeNumber of users to query at a time
100No
groupQuerySizeNumber of groups to query at a time
100No
When using client credentials
-
Set the access type to
confidential. - Enable service accounts.
-
Add the following roles from the
realm-managementclient role:
-
Set the access type to
-
query-groups -
query-users -
view-users Optionally, if you have self-signed or corporate certificate issues, you can set the following environment variable before starting Developer Hub:
NODE_TLS_REJECT_UNAUTHORIZED=0
WarningSetting the environment variable is not recommended.
12.3.4.4. Keycloak plugin metrics
Monitor Keycloak fetch operations and diagnose issues by using OpenTelemetry metrics with Prometheus or Grafana.
The Keycloak backend plugin supports OpenTelemetry metrics that you can use to monitor fetch operations and diagnose potential issues.
12.3.4.4.1. Available Counters
Keycloak metrics:
| Metric Name | Description |
|---|---|
|
|
Counts fetch task failures where no data was returned due to an error. |
|
|
Counts partial data batch failures. Even if some batches fail, the plugin continues fetching others. |
12.3.4.4.2. Labels
All counters include the taskInstanceId label, which uniquely identifies each scheduled fetch task. You can use this label to trace failures back to individual task executions.
Users can enter queries in the Prometheus UI or Grafana to explore and manipulate metric data.
In the following examples, a Prometheus Query Language (PromQL) expression returns the number of backend failures.
To get the number of backend failures associated with a taskInstanceId:
backend_keycloak_fetch_data_batch_failure_count_total{taskInstanceId="df040f82-2e80-44bd-83b0-06a984ca05ba"} 1To get the number of backend failures during the last hour:
sum(backend_keycloak_fetch_data_batch_failure_count_total) - sum(backend_keycloak_fetch_data_batch_failure_count_total offset 1h)
PromQL supports arithmetic operations, comparison operators, logical/set operations, aggregation, and various functions. Users can combine these features to analyze time-series data effectively.
Additionally, the results can be visualized using Grafana.
12.3.4.4.3. Export metrics
You can export metrics by using any OpenTelemetry-compatible backend, such as Prometheus.
Additional resources
12.3.4.5. Use Keycloak
The Keycloak backend plugin, which integrates Keycloak into Developer Hub, has the following capabilities:
- Synchronization of Keycloak users in a realm.
- Synchronization of Keycloak groups and their users in a realm.
After configuring the plugin successfully, the plugin imports the users and groups each time when started.
If you set up a schedule, users and groups will also be imported.
Procedure
- In Red Hat Developer Hub, go to the Catalog page.
- Select User from the entity type filter to display the list of imported users.
- Browse the list of users displayed on the page.
- Select a user to view detailed information imported from Keycloak.
- To view groups, select Group from the entity type filter.
- Browse the list of groups shown on the page.
- From the list of groups, select a group to view the information imported from Keycloak.
12.3.5. View build artifacts using Nexus Repository Manager
12.3.5.1. View build artifacts using Nexus Repository Manager
Configure the Nexus Repository Manager plugin to display artifact information from your Nexus Repository Manager instance.
12.3.5.2. Enable the Nexus Repository Manager plugin
To enable the Nexus Repository Manager plugin, set the disabled property to false.
Procedure
To enable the Nexus Repository Manager plugin, set the
disabledproperty tofalsein yourdynamic-plugins.yamlfile as follows:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-nexus-repository-manager:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
12.3.5.3. Configure the Nexus Repository Manager plugin
Configure the Nexus Repository Manager plugin to display artifact information from your Nexus Repository Manager instance.
Procedure
Set the proxy to the required Nexus Repository Manager server in the
app-config.yamlfile as follows:proxy: '/nexus-repository-manager': target: 'https://<NEXUS_REPOSITORY_MANAGER_URL>' headers: X-Requested-With: 'XMLHttpRequest' # Uncomment the following line to access a private Nexus Repository Manager using a token # Authorization: 'Bearer <YOUR TOKEN>' changeOrigin: true # Change to "false" in case of using self hosted Nexus Repository Manager instance with a self-signed certificate secure: trueOptional: Change the base URL of Nexus Repository Manager proxy as follows:
nexusRepositoryManager: # default path is `/nexus-repository-manager` proxyPath: /custom-pathOptional: Enable the following experimental annotations:
nexusRepositoryManager: experimentalAnnotations: trueAnnotate your entity using the following annotations:
metadata: annotations: # insert the chosen annotations here # example nexus-repository-manager/docker.image-name: `<ORGANIZATION>/<REPOSITORY>`,
12.3.5.4. Use the Nexus Repository Manager plugin
For components in the Red Hat Developer Hub catalog, you can view build artifacts from the Nexus Repository Manager.
Prerequisites
- Your Developer Hub application is installed and running.
- You have installed the Nexus Repository Manager plugin.
Procedure
- Open your Developer Hub application and select a component from the Catalog page.
Go to the BUILD ARTIFACTS tab.
The BUILD ARTIFACTS tab contains a list of build artifacts and related information, such as VERSION, REPOSITORY, REPOSITORY TYPE, MANIFEST, MODIFIED, and SIZE.

12.3.6. Monitor continuous integration pipelines with Tekton
The Tekton plugin enables you to monitor CI/CD pipeline results across your Kubernetes or OpenShift clusters. It provides a high-level overview of all associated tasks, allowing you to track the real-time status of your application pipelines.
Prerequisites
-
You have installed and configured the
@backstage/plugin-kubernetesand@backstage/plugin-kubernetes-backenddynamic plugins. -
You have configured the Kubernetes plugin to connect to the cluster using a
ServiceAccount. The
ClusterRolemust be granted for custom resources (PipelineRuns and TaskRuns) to theServiceAccountaccessing the cluster.NoteIf you have the RHDH Kubernetes plugin configured, then the
ClusterRoleis already granted.-
To view the pod logs, you have granted permissions for
pods/log. You can use the following code to grant the
ClusterRolefor custom resources and pod logs:kubernetes: ... customResources: - group: 'tekton.dev' apiVersion: 'v1' plural: 'pipelineruns' - group: 'tekton.dev' apiVersion: 'v1' ... apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: - apiGroups: - "" resources: - pods/log verbs: - get - list - watch ... - apiGroups: - tekton.dev resources: - pipelineruns - taskruns verbs: - get - listYou can use the prepared manifest for a read-only
ClusterRole, which provides access for both Kubernetes plugin and Tekton plugin.Add the following annotation to the entity’s
catalog-info.yamlfile to identify whether an entity contains the Kubernetes resources:annotations: ... backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
You can also add the
backstage.io/kubernetes-namespaceannotation to identify the Kubernetes resources using the defined namespace.annotations: ... backstage.io/kubernetes-namespace: <RESOURCE_NS>
Add the following annotation to the
catalog-info.yamlfile of the entity to enable the Tekton related features in RHDH. The value of the annotation identifies the name of the RHDH entity:annotations: ... janus-idp.io/tekton : <BACKSTAGE_ENTITY_NAME>
Add a custom label selector, which RHDH uses to find the Kubernetes resources. The label selector takes precedence over the ID annotations.
annotations: ... backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
Add the following label to the resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:
labels: ... backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
NoteWhen you use the label selector, the mentioned labels must be present on the resource.
Procedure
To enable the Tekton plugin, set the
disabledproperty tofalsein yourdynamic-plugins.yamlfile as follows:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-tekton:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
12.3.7. Use the Tekton plugin
You can use the Tekton plugin to visualize the results of CI/CD pipeline runs on your Kubernetes or OpenShift clusters. The plugin allows users to visually see high level status of all associated tasks in the pipeline for their applications.
You can use the Tekton front-end plugin to view PipelineRun resources.
Prerequisites
- You have installed the Red Hat Developer Hub (RHDH).
- You have installed the Tekton plugin. For the installation process, see Installing and viewing plugins in Red Hat Developer Hub.
Procedure
- Open your RHDH application and select a component from the Catalog page.
Go to the CI tab.
The CI tab displays the list of PipelineRun resources associated with a Kubernetes cluster. The list contains pipeline run details, such as NAME, VULNERABILITIES, STATUS, TASK STATUS, STARTED, and DURATION.

Click the expand row button besides PipelineRun name in the list to view the PipelineRun visualization. The pipeline run resource includes tasks to complete. When you hover the mouse pointer on a task card, you can view the steps to complete that particular task.

12.3.8. Visualize Kubernetes workloads and pod health with Topology
12.3.8.1. Visualize Kubernetes workloads and pod health with Topology
Visualize Kubernetes workloads like Deployments, Pods, and Virtual Machines by enabling the Topology plugin.
12.3.8.2. Install the Topology plugin
Visualize Kubernetes workloads like Deployments, Pods, and Virtual Machines by enabling the Topology plugin.
The Topology plugin enables you to visualize the workloads such as Deployment, Job, Daemonset, Statefulset, CronJob, Pods and Virtual Machines powering any service on your Kubernetes cluster.
Prerequisites
- You have installed and configured the @backstage/plugin-kubernetes-backend dynamic plugins.
- You have configured the Kubernetes plugin to connect to the cluster using a ServiceAccount.
The
ClusterRolemust be granted to ServiceAccount accessing the cluster.NoteIf you have the Developer Hub Kubernetes plugin configured, then the
ClusterRoleis already granted.
Procedure
The Topology plugin is pre-loaded in Developer Hub with basic configuration properties. To enable it, set the disabled property to false as follows:
plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-topology:__<tag>__ disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
12.3.8.3. Configure the plugin
Grant read access to routes resource in ClusterRole to view OpenShift routes in the Topology plugin.
Procedure
To view OpenShift routes, grant read access to the
routesresource in theClusterRole:apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: ... - apiGroups: - route.openshift.io resources: - routes verbs: - get - listAlso add the following in
kubernetes.customResourcesproperty in yourapp-config.yamlfile:kubernetes: ... customResources: - group: 'route.openshift.io' apiVersion: 'v1' plural: 'routes'
12.3.8.3.1. View pod logs
Grant ClusterRole permissions to pods and pods/log resources to view pod logs in the Topology plugin.
Procedure
To view pod logs, you must grant the following permission to the
ClusterRole:apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: ... - apiGroups: - '' resources: - pods - pods/log verbs: - get - list - watch
12.3.8.3.2. View Tekton PipelineRuns
Grant ClusterRole access to Tekton resources to view PipelineRuns status in the Topology plugin.
Procedure
To view the Tekton
PipelineRuns, grant read access to thepipelines,pipelineruns, andtaskrunsresources in theClusterRole:... apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: ... - apiGroups: - tekton.dev resources: - pipelines - pipelineruns - taskruns verbs: - get - listTo view the Tekton
PipelineRunslist in the side panel and the latestPipelineRunsstatus in the Topology node decorator, add the following code to thekubernetes.customResourcesproperty in yourapp-config.yamlfile:kubernetes: ... customResources: - group: 'tekton.dev' apiVersion: 'v1' plural: 'pipelines' - group: 'tekton.dev' apiVersion: 'v1' plural: 'pipelineruns' - group: 'tekton.dev' apiVersion: 'v1' plural: 'taskruns'
12.3.8.3.3. View virtual machines
Grant ClusterRole access to VirtualMachines resources to view virtual machine nodes in the Topology plugin.
Prerequisites
- The OpenShift Virtualization operator is installed and configured on a Kubernetes cluster.
Procedure
Grant read access to the
VirtualMachinesresource in theClusterRole:... apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: ... - apiGroups: - kubevirt.io resources: - virtualmachines - virtualmachineinstances verbs: - get - listTo view the virtual machine nodes on the topology plugin, add the following code to the
kubernetes.customResourcesproperty in theapp-config.yamlfile:kubernetes: ... customResources: - group: 'kubevirt.io' apiVersion: 'v1' plural: 'virtualmachines' - group: 'kubevirt.io' apiVersion: 'v1' plural: 'virtualmachineinstances'
12.3.8.3.4. Enable the source code editor
Enable the source code editor to allow developers to open source code directly from RHDH.
Procedure
Grant read access to the CheClusters resource in the
ClusterRole:... apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: backstage-read-only rules: ... - apiGroups: - org.eclipse.che resources: - checlusters verbs: - get - listAdd the following configuration to the
kubernetes.customResourcesproperty in yourapp-config.yamlfile:kubernetes: ... customResources: - group: 'org.eclipse.che' apiVersion: 'v2' plural: 'checlusters'
12.3.8.4. Manage labels and annotations
Add annotations to workload resources to enable navigation to the Git repository of the associated application using the source code editor.
Procedure
Add the following annotations to workload resources, such as Deployments, to navigate to the Git repository of the associated application using the source code editor:
annotations: app.openshift.io/vcs-uri: <GIT_REPO_URL>
Optional: Add the following annotation to navigate to a specific branch:
annotations: app.openshift.io/vcs-ref: <GIT_REPO_BRANCH>
Optional: Add the
app.openshift.io/edit-linkannotation with the edit URL that you want to access using the decorator.NoteIf Red Hat OpenShift Dev Spaces is installed and configured and Git URL annotations are also added to the workload YAML file, then clicking on the edit code decorator redirects you to the Red Hat OpenShift Dev Spaces instance.
NoteWhen you deploy your application using the OCP Git import flows, you do not need to add the labels as import flows do that. Otherwise, you need to add the labels manually to the workload YAML file.
12.3.8.4.1. Add entity annotations and labels for the Kubernetes plugin
Add annotations and labels to enable RHDH to detect that an entity has Kubernetes components.
Procedure
Add the following annotation to the
catalog-info.yamlfile of the entity:annotations: backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
Add the following label to the resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:
labels: backstage.io/kubernetes-id: <BACKSTAGE_ENTITY_NAME>
NoteWhen using the label selector, the mentioned labels must be present on the resource.
12.3.8.4.2. Namespace annotation
Identify Kubernetes resources by namespace using the backstage.io/kubernetes-namespace annotation.
Procedure
To identify the Kubernetes resources using the defined namespace, add the
backstage.io/kubernetes-namespaceannotation:annotations: backstage.io/kubernetes-namespace: <RESOURCE_NS>
The Red Hat OpenShift Dev Spaces instance is not accessible using the source code editor if the
backstage.io/kubernetes-namespaceannotation is added to thecatalog-info.yamlfile.To retrieve the instance URL, you require the CheCluster custom resource (CR). As the CheCluster CR is created in the openshift-devspaces namespace, the instance URL is not retrieved if the namespace annotation value is not openshift-devspaces.
12.3.8.4.3. Add a label selector query annotation
Add a custom label selector annotation so that RHDH uses your custom labels to find Kubernetes resources.
Procedure
Add the
backstage.io/kubernetes-label-selectorannotation to thecatalog-info.yamlfile of the entity. The label selector takes precedence over the ID annotations:annotations: backstage.io/kubernetes-label-selector: 'app=my-app,component=front-end'
Optional: If you have many entities while Red Hat Dev Spaces is configured and want multmanyities to support the edit code decorator that redirects to the Red Hat Dev Spaces instance, add the
backstage.io/kubernetes-label-selectorannotation to thecatalog-info.yamlfile for each entity:annotations: backstage.io/kubernetes-label-selector: 'component in (<BACKSTAGE_ENTITY_NAME>,che)'
If you are using the previous label selector, add the following labels to your resources so that the Kubernetes plugin gets the Kubernetes resources from the requested entity:
labels: component: che # add this label to your che cluster instance labels: component: <BACKSTAGE_ENTITY_NAME> # add this label to the other resources associated with your entity
You can also write your own custom query for the label selector with unique labels to differentiate your entities. However, you need to ensure that you add those labels to the resources associated with your entities including your
CheClusterinstance.
12.3.8.4.4. Display a runtime icon in the topology node
Add a label to workload resources to display a runtime icon in the topology nodes.
Procedure
Add the following label to workload resources, such as Deployments:
labels: app.openshift.io/runtime: <RUNTIME_NAME>
Alternatively, you can include the following label to display the runtime icon:
labels: app.kubernetes.io/name: <RUNTIME_NAME>
Supported values of
<RUNTIME_NAME>includedjango,dotnet,drupal,go-gopher,golang,grails,jboss,jruby,js,nginx,nodejs,openjdk,perl,phalcon,php,python,quarkus,rails,redis,rh-spring-boot,rust,java,rh-openjdk,ruby,spring, andspring-boot. Other values result in icons not being rendered for the node.
12.3.8.4.5. Group applications in the topology view
Add a label to workload resources to display them in a visual group in the topology view.
Procedure
Add the following label to workload resources, such as deployments or pods, to display them in a visual group:
labels: app.kubernetes.io/part-of: <GROUP_NAME>
12.3.8.4.6. Node connector
Display visual connectors between workload resources like deployments and pods using annotations.
Procedure
To display the workload resources such as deployments or pods with a visual connector, add the following annotation:
annotations: app.openshift.io/connects-to: '[{"apiVersion": <RESOURCE_APIVERSION>,"kind": <RESOURCE_KIND>,"name": <RESOURCE_NAME>}]'
12.3.8.5. Use the Topology plugin
You can use the Topology plugin to view the workloads such as deployments or pods as nodes on the Kubernetes cluster.
Prerequisites
- Your Red Hat Developer Hub instance is installed and running.
- You have installed the Topology plugin.
- You have enabled the users to use the Topology plugin.
Procedure
- Open your RHDH application and select a component from the Catalog page.
Go to the TOPOLOGY tab and you can view the workloads such as deployments or pods as nodes.

Select a node and a pop-up appears on the right side that contains two tabs: Details and Resources.
The Details and Resources tabs contain the associated information and resources for the node.

Click the Open URL button on the top of a node.

Click the Open URL button to access the associated Ingresses and run your application in a new tab.
12.3.8.6. Enable users to use the Topology plugin
The Topology plugin is defining additional permissions. When Authorization in Red Hat Developer Hub is enabled, to enable users to use the Topology plugin, grant them:
-
The
kubernetes.clusters.readandkubernetes.resources.read,readpermissions to view the Topology panel. -
The
kubernetes.proxyusepermission to view the pod logs. -
The
catalog-entityreadpermission to view the Red Hat Developer Hub software catalog items.
Prerequisites
Procedure
Add the following permission policies to your
rbac-policy.csvfile to create atopology-viewerrole that has access to the Topology plugin features, and add the role to the users requiring this authorization:g, user:default/<YOUR_USERNAME>, role:default/topology-viewer p, role:default/topology-viewer, kubernetes.clusters.read, read, allow p, role:default/topology-viewer, kubernetes.resources.read, read, allow p, role:default/topology-viewer, kubernetes.proxy, use, allow p, role:default/topology-viewer, catalog-entity, read, allow
kubernetes.clusters.readandkubernetes.resources.read, read, allow- Grants the user the ability to see the Topology panel.
kubernetes.proxy, use, allow- Grants the user the ability to view the pod logs.
catalog-entity, read, allow- Grants the user the ability to see the catalog item.
12.3.9. Configure the GitHub Events Module plugin
Configure GitHub webhooks to trigger real-time updates for GitHub Discovery and organizational data.
Learn how to configure Events Module for use with the RHDH GitHub Discovery feature and GitHub organization data.
Prerequisites
-
You have added your GitHub integration credentials in the
app-config.yamlfile. -
You have defined the
schedule.frequencyin theapp-config.yamlfile as longer time period, such as 24 hours. - For GitHub Discovery only: You have enabled GitHub Discovery.
- For GitHub Organizational Data only: You have enabled Github Authentication with user ingestion.
Procedure
Add the GitHub Events Module to your
dynamic-plugins.yamlconfiguration file as follows:data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: oci://registry.access.redhat.com/rhdh/backstage-plugin-events-backend-module-github:<tag> disabled: false
where:
<tag>-
Enter your RHDH version and the plugin version, in the format
<rhdh-version>--<plugin-version>. To find these versions, complete the following steps:
Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.10, use the format
1.10--<plugin-version>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
To create HTTP endpoints to receive events for the
github, add the following to yourapp-config.yamlfile:events: http: topics: - github modules: github: webhookSecret: ${GITHUB_WEBHOOK_SECRET}ImportantSecure your workflow by adding a webhook secret token to validate webhook deliveries.
Create a GitHub webhook with the following specifications:
- For GitHub Discovery Events: push, repository
- For GitHub Organizational Data Events: organization, team and membership
- Content Type: application/json
Payload URL:
https://<my_developer_hub_domain>/api/events/http/githubNotePayload URL is the URL exposed after configuring the HTTP endpoint.
Verification
Check the log for an entry that confirms that http endpoint was set up successfully to receive events from the GitHub webhook.
- Example of a log of successfully set up http endpoint
{"level":"\u001b[32minfo\u001b[39m","message":"Registered /api/events/http/github to receive events","plugin":"events","service":"backstage","timestamp":"2025-11-03 02:19:12"}
For GitHub Discovery only:
Trigger a GitHub push event by adding, modifying or deleting the
catalog-info.yamlfile in the repository where you set up your webhook. A record of this event should appear in the pod logs of your RHDH instance.- Example of a log with changes to
catalog-info.yamlfile {"level":"\u001b[32minfo\u001b[39m","message":"Processed Github push event: added 0 - removed 0 - modified 1","plugin":"catalog","service":"backstage","span_id":"47534b96c4afc654","target":"github-provider:providerId","timestamp":"2025-06-15 21:33:14","trace_flags":"01","trace_id":"ecc782deb86aed2027da0ae6b1999e5c"}
- Example of a log with changes to
For GitHub Organizational Data only:
- Newly added users and teams appear in the RHDH catalog.
12.4. Extend software templates with Kubernetes custom actions
12.4.1. Kubernetes custom actions in Red Hat Developer Hub
You can create and manage Kubernetes resources by using custom scaffolder actions in Red Hat Developer Hub templates. The Kubernetes custom actions plugin is preinstalled in a disabled state.
12.4.2. Enable Kubernetes custom actions plugin in Red Hat Developer Hub
Enable the preinstalled Kubernetes custom actions plugin by updating the dynamic plugins configuration.
In Red Hat Developer Hub, the Kubernetes custom actions are provided as a preinstalled plugin, which is disabled by default. You can enable the Kubernetes custom actions plugin by updating the disabled key value in your dynamic-plugins.yaml file.
Procedure
Add a
packagewith the Kubernetes custom action plugin name and update thedisabledfield in yourdynamic-plugins.yamlfile to enable the plugin. For example:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-scaffolder-backend-module-kubernetes:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
NoteThe default configuration for a plugin is extracted from the
dynamic-plugins.default.yamlfile, however, you can use apluginConfigentry to override the default configuration.
12.4.3. Use Kubernetes custom actions plugin in Red Hat Developer Hub
Add Kubernetes actions to your custom templates to create namespaces and manage cluster resources.
In Red Hat Developer Hub, the Kubernetes custom actions enable you to run template actions for Kubernetes.
Procedure
To use a Kubernetes custom action in your custom template, add the following Kubernetes actions to your template:
action: kubernetes:create-namespace id: create-kubernetes-namespace name: Create kubernetes namespace input: namespace: my-rhdh-project clusterRef: bar token: TOKEN skipTLSVerify: false caData: Zm9v labels: app.io/type=ns; app.io/managed-by=org;
Additional resources
12.4.4. Create a template using Kubernetes custom actions in Red Hat Developer Hub
Define a Template object with Kubernetes actions to automate namespace creation and resource management.
Procedure
To create a template, define a
Templateobject as a YAML file.The
Templateobject describes the template and its metadata. It also contains required input variables and a list of actions that are executed by the scaffolding service.apiVersion: scaffolder.backstage.io/v1beta3 kind: Template metadata: name: create-kubernetes-namespace title: Create a kubernetes namespace description: Create a kubernetes namespace spec: type: service parameters: - title: Information required: [namespace, token] properties: namespace: title: Namespace name type: string description: Name of the namespace to be created clusterRef: title: Cluster reference type: string description: Cluster resource entity reference from the catalog ui:field: EntityPicker ui:options: catalogFilter: kind: Resource url: title: Url type: string description: Url of the kubernetes API, will be used if clusterRef is not provided token: title: Token type: string ui:field: Secret description: Bearer token to authenticate with skipTLSVerify: title: Skip TLS verification type: boolean description: Skip TLS certificate verification, not recommended to use in production environment, default to false caData: title: CA data type: string ui:field: Secret description: Certificate Authority base64 encoded certificate labels: title: Labels type: string description: Labels to be applied to the namespace ui:widget: textarea ui:options: rows: 3 ui:help: 'Hint: Separate multiple labels with a semicolon!' ui:placeholder: 'kubernetes.io/type=namespace; app.io/managed-by=org' steps: - id: create-kubernetes-namespace name: Create kubernetes namespace action: kubernetes:create-namespace input: namespace: ${ parameters.namespace } clusterRef: ${ parameters.clusterRef } url: ${ parameters.url } token: ${ secrets.token } skipTLSVerify: ${ parameters.skipTLSVerify } caData: ${ secrets.caData } labels: ${ parameters.labels }
12.4.5. Supported Kubernetes custom actions in Red Hat Developer Hub
Access parameter specifications and requirements for the kubernetes:create-namespace scaffolder action.
In Red Hat Developer Hub, you can use custom Kubernetes actions in Scaffolder templates.
- Action:
kubernetes:create-namespace - Creates a namespace for the Kubernetes cluster in the Developer Hub.
| Parameter name | Type | Requirement | Description | Example |
|---|---|---|---|---|
|
|
|
Required |
Name of the Kubernetes namespace |
|
|
|
|
Required only if |
Cluster resource entity reference from the catalog |
|
|
|
|
Required only if |
API url of the Kubernetes cluster |
|
|
|
|
Required |
Kubernetes API bearer token used for authentication | |
|
|
|
Optional |
If true, certificate verification is skipped |
false |
|
|
|
Optional |
Base64 encoded certificate data | |
|
|
|
Optional |
Labels applied to the namespace |
app.io/type=ns; app.io/managed-by=org; |
12.5. Integrate ServiceNow for incident management and scaffolder actions
12.5.1. ServiceNow custom actions in Red Hat Developer Hub
Integrate ServiceNow with Red Hat Developer Hub to manage ServiceNow records by using Scaffolder actions and view ServiceNow data on entity pages.
In Red Hat Developer Hub, you can use ServiceNow custom actions to fetch and register resources within the catalog.
The custom actions in Developer Hub help you automate the management of records. By using the custom actions, you can:
- Create, update, or delete a record
- Retrieve information about a single record or many records
The ServiceNow custom actions plugin is community-sourced.
12.5.2. ServiceNow entity linking methods
To view and manage ServiceNow incidents directly in Red Hat Developer Hub (RHDH), you must link an entity to your ServiceNow records. Linking ensures that incident data is accurately synchronized and visible within the relevant component or system.
Red Hat Developer Hub provides two methods for linking these entities. You can choose the method that best fits your organization’s security requirements and your ability to modify the ServiceNow schema.
12.5.2.1. Direct mapping (Backstage Entity ID column)
The default method requires adding a custom column named backstage_entity_id to your ServiceNow incident table. You then manually or programmatically assign the specific RHDH entity reference (for example, component:default/my-service) to this column in ServiceNow.
Advantages:
- Highly secure and precise
- Ensures data is only exposed to the intended entity
Limitations:
- Requires a schema change in ServiceNow
- Requires manual data entry for each incident
12.5.2.2. Flexible mapping (Custom column mapping)
The flexible mapping approach is an opt-in feature that allows you to use any existing column in your ServiceNow incident table to link to RHDH entities. Instead of creating a new column, you configure the ServiceNow plugin to look at an existing field (such as short_description, cmdb_ci, or a custom organizational ID) to match the entity.
Advantages:
- Does not require ServiceNow schema changes
- Faster to implement for organizations with strict ServiceNow governance
Limitations:
- Requires careful configuration to ensure that the search criteria in the chosen column are unique enough to prevent displaying unrelated incidents
12.5.2.3. Comparison of linking methods
| Feature | Direct mapping | Flexible mapping |
|---|---|---|
|
ServiceNow schema change |
Required |
Not required |
|
Security level |
High (strict matching) |
Medium (dependent on column data) |
|
Configuration complexity |
Low (plugin side) |
Medium (requires YAML mapping) |
|
Ideal use case |
New ServiceNow instances or high-security environments |
Existing ServiceNow instances where schema changes are restricted |
12.5.3. Enable ServiceNow custom actions plugin in Red Hat Developer Hub
To use ServiceNow custom actions, you must first activate the plugin.
Prerequisites
- Red Hat Developer Hub is installed and running.
- You have created a project in the Developer Hub.
Procedure
Add a
packagewith plugin name and update thedisabledfield in yourdynamic-plugins.yamlfile as follows:plugins: - package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-scaffolder-backend-module-servicenow:<tag> disabled: falsewhere:
<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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
NoteThe default configuration for a plugin is extracted from the
dynamic-plugins.default.yamlfile, however, you can use apluginConfigentry to override the default configuration.Set the following variables in your
app-config.yamlfile to access the custom actions:servicenow: # The base url of the ServiceNow instance. baseUrl: ${SERVICENOW_BASE_URL} # The username to use for authentication. username: ${SERVICENOW_USERNAME} # The password to use for authentication. password: ${SERVICENOW_PASSWORD}
12.5.4. Configure the ServiceNow plugin in the ConfigMap
Update the Red Hat Developer Hub ConfigMap to enable the ServiceNow backend, frontend, and Scaffolder actions. This configuration defines the connection parameters and UI components required to integrate ServiceNow with your software catalog.
Prerequisites
-
You have provisioned a custom configuration by following the steps in Provisioning and using your custom Developer Hub configuration, including the section on authoring a custom
dynamic-plugins.yamlfile. - You have administrator access to an Red Hat OpenShift Container Platform cluster.
- Red Hat Developer Hub is installed on the cluster.
Procedure
-
Open your
Red Hat Developer HubConfigMap for editing. Add the ServiceNow backend and frontend plugin packages to the
dynamic-plugins.yamlsection, including the connection and UI configuration:kind: ConfigMap apiVersion: v1 metadata: name: rhdh-plugin-config data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: # ----------------------------------------------------------------- # ... Your pre-existing custom dynamic plugins would be listed here # ----------------------------------------------------------------- # ServiceNow Backend Plugin - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-servicenow-backend:<tag>' disabled: false pluginConfig: servicenow: instanceUrl: ${SERVICENOW_BASE_URL} basicAuth: username: ${SERVICENOW_USERNAME} password: ${SERVICENOW_PASSWORD} # ServiceNow Scaffolder Module / Actions - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-scaffolder-backend-module-servicenow:<tag>' disabled: false pluginConfig: servicenow: baseUrl: ${SERVICENOW_BASE_URL} username: ${SERVICENOW_USERNAME} password: ${SERVICENOW_PASSWORD} # ServiceNow Frontend Plugin - package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-servicenow:<tag>' disabled: falsewhere:
<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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
- Save the changes to the ConfigMap.
-
Wait for the RHDH Operator to redeploy the pods. The plugins are available once the pods are in a
Runningstate.
12.5.5. Link ServiceNow tickets to catalog entities
The ServiceNow integration in Red Hat Developer Hub uses software catalog annotations to associate entities with ServiceNow records. By defining these identifiers, the ServiceNow plugin can retrieve and display relevant tickets and incidents directly within the component dashboard.
Prerequisites
- The ServiceNow plugin is installed and configured in your Red Hat Developer Hub instance.
- You have the unique identifier (such as a Service ID or Category) for the ServiceNow resource you want to link.
Procedure
-
Open the
catalog-info.yamlfile of the component you want to link to ServiceNow. Add the
servicenow.com/service-idannotation to themetadata.annotationssection.apiVersion: backstage.io/v1alpha1 kind: Component metadata: name: example-component annotations: servicenow.com/service-id: <your-service-id>servicenow.com/<field-name>-
Annotation pattern for linking to ServiceNow records. Replace
<field-name>with any ServiceNow table column name (such asservice-id,category,company). Theservicenow.com/prefix enables the ServiceNow tab. You can add multiple annotations to filter by different fields.
Optional: If your organization uses different categories to filter tickets, you can also add the category annotation:
metadata: annotations: servicenow.com/category: "software"- metadata.annotations.servicenow.com/category
- Specifies the ServiceNow category used to filter the displayed incidents.
-
Save the changes to
catalog-info.yamland commit them to your repository. - If the changes do not appear automatically, manually refresh the entity in the Red Hat Developer Hub catalog.
Verification
- Log in to your Red Hat Developer Hub and navigate to the Catalog.
- Select the component you updated.
- Select the ServiceNow tab.
- Confirm that the tab displays ServiceNow tickets or incidents associated with the provided ID.
12.5.6. Use ServiceNow scaffolder actions in software templates
Add ServiceNow actions to your software templates to automate the creation, retrieval, and modification of ServiceNow records during the software scaffolding process.
Prerequisites
- You have configured the ServiceNow instance parameters in the Red Hat Developer HubConfigMap or app-config.yaml file.
- You have the required permissions to edit Software Templates in the source repository.
- You have registered the Software Template in the Red Hat Developer Hub catalog.
Procedure
- Open your software template YAML file.
-
In the
spec.stepssection, add the ServiceNow action that corresponds to your goal. Define the
tableNameand therequestBodycontaining the fields to populate or modify. The following example demonstrates how to use theservicenow:now:table:createRecordaction to generate an incident ticket:steps: - id: create-incident name: Create ServiceNow Incident action: servicenow:now:table:createRecord input: tableName: incident requestBody: short_description: "Printer is offline" description: "The office printer is not accessible via the network" severity: "3"Optional: To perform other operations, use the appropriate action ID and parameters:
Goal Action ID Key Input Parameters Delete a record
servicenow:now:table:deleteRecordtableName,sysIdModify a record
servicenow:now:table:modifyRecordtableName,sysId,requestBodyRetrieve a record
servicenow:now:table:retrieveRecordtableName,sysIdUpdate a record
servicenow:now:table:updateRecordtableName,sysId,requestBodyTipTo view the full schema and all available ServiceNow actions for your specific installation, navigate to Create > Installed Actions in the Red Hat Developer Hub interface.
12.5.7. ServiceNow configuration parameters
The ServiceNow integration requires specific parameters in your configuration files to establish a connection between Red Hat Developer Hub and your ServiceNow instances. Use these parameters to define authentication methods, instance URLs, and UI layouts.
12.5.7.1. ServiceNow backend and frontend configuration
Define the following parameters in the app-config.yaml file or the dynamic-plugins.yaml section of the Red Hat Developer Hub ConfigMap to enable the backend and frontend plugins.
| Parameter | Description | Requirement |
|---|---|---|
|
|
The base URL of your ServiceNow instance. For example, |
Required |
|
|
The service account username for Basic authentication. |
Optional |
|
|
The service account password for Basic authentication. |
Optional |
|
|
The OAuth 2.0 grant type. Supports |
Optional |
|
|
The client ID for OAuth authentication. |
Optional |
|
|
The client secret for OAuth authentication. |
Optional |
12.5.7.2. ServiceNow scaffolder configuration
The ServiceNow Scaffolder module requires a separate configuration block. Note that this module uses baseUrl instead of instanceUrl.
| Parameter | Description | Requirement |
|---|---|---|
|
|
The base URL of your ServiceNow instance. |
Required |
|
|
The service account username. |
Required for Basic authentication |
|
|
The service account password. |
Required for Basic authentication |
12.5.7.3. Authentication examples
The following examples demonstrate how to structure different authentication methods in your configuration.
12.5.7.4. Basic authentication example
servicenow:
baseUrl: ${SERVICENOW_PROD_URL}
username: ${SERVICENOW_USER}
password: ${SERVICENOW_PASS}12.5.7.5. OAuth with Client Credentials
servicenow:
instanceUrl: ${SERVICENOW_INSTANCE_URL}
oauth:
grantType: client_credentials
clientId: ${SERVICENOW_CLIENT_ID}
clientSecret: ${SERVICENOW_CLIENT_SECRET}12.5.7.6. OAuth with Password Grant
servicenow:
instanceUrl: ${SERVICENOW_INSTANCE_URL}
oauth:
grantType: password
clientId: ${SERVICENOW_CLIENT_ID}
clientSecret: ${SERVICENOW_CLIENT_SECRET}
username: ${SERVICENOW_USER}
password: ${SERVICENOW_PASS}12.5.7.7. Frontend UI configuration
The frontend plugin configuration defines how ServiceNow data appears on component entity pages.
dynamicPlugins:
frontend:
backstage-community.plugin-servicenow:
entityTabs:
- path: /servicenow
title: ServiceNow
mountPoint: entity.page.servicenow
mountPoints:
- mountPoint: entity.page.servicenow/cards
importName: ServicenowPage
config:
layout:
gridColumn: 1 / -1
height: 75vh12.5.8. Supported ServiceNow custom actions in Red Hat Developer Hub
The ServiceNow custom actions enable you to manage records in the Red Hat Developer Hub.
The custom actions support the following HTTP methods for API requests:
-
GET: Retrieves specified information from a specified resource endpoint -
POST: Creates or updates a resource -
PUT: Modify a resource -
PATCH: Updates a resource DELETE: Deletes a resource- [GET] servicenow:now:table:retrieveRecord
Retrieves information of a specified record from a table in the Developer Hub.
The following table describes the input parameters:
Name Type Requirement Description tableNamestringRequired
Name of the table to retrieve the record from
sysIdstringRequired
Unique identifier of the record to retrieve
sysparmDisplayValueenum("true", "false", "all")Optional
Returns field display values such as
true, actual values asfalse, or both. The default value isfalse.sysparmExcludeReferenceLinkbooleanOptional
Set as
trueto exclude Table API links for reference fields. The default value isfalse.sysparmFieldsstring[]Optional
Array of fields to return in the response
sysparmViewstringOptional
Renders the response according to the specified UI view. You can override this parameter using
sysparm_fields.sysparmQueryNoDomainbooleanOptional
Set as
trueto access data across domains if authorized. The default value isfalse.The following table describes the output parameters:
Name Type Description resultRecord<PropertyKey, unknown>The response body of the request
- [GET]
servicenow:now:table:retrieveRecords Retrieves information about multiple records from a table in the Developer Hub.
The following table describes the input parameters:
Name Type Requirement Description tableNamestringRequired
Name of the table to retrieve the records from
sysparamQuerystringOptional
Encoded query string used to filter the results
sysparmDisplayValueenum("true", "false", "all")Optional
Returns field display values such as
true, actual values asfalse, or both. The default value isfalse.sysparmExcludeReferenceLinkbooleanOptional
Set as
trueto exclude Table API links for reference fields. The default value isfalse.sysparmSuppressPaginationHeaderbooleanOptional
Set as
trueto suppress pagination header. The default value isfalse.sysparmFieldsstring[]Optional
Array of fields to return in the response
sysparmLimitintOptional
Maximum number of results returned per page. The default value is
10,000.sysparmViewstringOptional
Renders the response according to the specified UI view. You can override this parameter using
sysparm_fields.sysparmQueryCategorystringOptional
Name of the query category to use for queries
sysparmQueryNoDomainbooleanOptional
Set as
trueto access data across domains if authorized. The default value isfalse.sysparmNoCountbooleanOptional
Does not run a select count(*) on the table. The default value is
false.The following table describes the output parameters:
Name Type Description resultRecord<PropertyKey, unknown>The response body of the request
- [POST]
servicenow:now:table:createRecord Creates a record in a table in the Developer Hub.
The following table describes the input parameters:
Name Type Requirement Description tableNamestringRequired
Name of the table to save the record in
requestBodyRecord<PropertyKey, unknown>Optional
Field name and associated value for each parameter to define in the specified record
sysparmDisplayValueenum("true", "false", "all")Optional
Returns field display values such as
true, actual values asfalse, or both. The default value isfalse.sysparmExcludeReferenceLinkbooleanOptional
Set as
trueto exclude Table API links for reference fields. The default value isfalse.sysparmFieldsstring[]Optional
Array of fields to return in the response
sysparmInputDisplayValuebooleanOptional
Set field values using their display value such as
trueor actual value asfalse. The default value isfalse.sysparmSuppressAutoSysFieldbooleanOptional
Set as
trueto suppress auto-generation of system fields. The default value isfalse.sysparmViewstringOptional
Renders the response according to the specified UI view. You can override this parameter using
sysparm_fields.The following table describes the output parameters:
Name Type Description resultRecord<PropertyKey, unknown>The response body of the request
- [PUT]
servicenow:now:table:modifyRecord Modifies a record in a table in the Developer Hub.
The following table describes the input parameters:
Name Type Requirement Description tableNamestringRequired
Name of the table to change the record from
sysIdstringRequired
Unique identifier of the record to change
requestBodyRecord<PropertyKey, unknown>Optional
Field name and associated value for each parameter to define in the specified record
sysparmDisplayValueenum("true", "false", "all")Optional
Returns field display values such as
true, actual values asfalse, or both. The default value isfalse.sysparmExcludeReferenceLinkbooleanOptional
Set as
trueto exclude Table API links for reference fields. The default value isfalse.sysparmFieldsstring[]Optional
Array of fields to return in the response
sysparmInputDisplayValuebooleanOptional
Set field values using their display value such as
trueor actual value asfalse. The default value isfalse.sysparmSuppressAutoSysFieldbooleanOptional
Set as
trueto suppress auto-generation of system fields. The default value isfalse.sysparmViewstringOptional
Renders the response according to the specified UI view. You can override this parameter using
sysparm_fields.sysparmQueryNoDomainbooleanOptional
Set as
trueto access data across domains if authorized. The default value isfalse.The following table describes the output parameters:
Name Type Description resultRecord<PropertyKey, unknown>The response body of the request
- [PATCH]
servicenow:now:table:updateRecord Updates a record in a table in the Developer Hub.
The following table describes the input parameters:
Name Type Requirement Description tableNamestringRequired
Name of the table to update the record in
sysIdstringRequired
Unique identifier of the record to update
requestBodyRecord<PropertyKey, unknown>Optional
Field name and associated value for each parameter to define in the specified record
sysparmDisplayValueenum("true", "false", "all")Optional
Returns field display values such as
true, actual values asfalse, or both. The default value isfalse.sysparmExcludeReferenceLinkbooleanOptional
Set as
trueto exclude Table API links for reference fields. The default value isfalse.sysparmFieldsstring[]Optional
Array of fields to return in the response
sysparmInputDisplayValuebooleanOptional
Set field values using their display value such as
trueor actual value asfalse. The default value isfalse.sysparmSuppressAutoSysFieldbooleanOptional
Set as
trueto suppress auto-generation of system fields. The default value isfalse.sysparmViewstringOptional
Renders the response according to the specified UI view. You can override this parameter using
sysparm_fields.sysparmQueryNoDomainbooleanOptional
Set as
trueto access data across domains if authorized. The default value isfalse.The following table describes the output parameters:
Name Type Description resultRecord<PropertyKey, unknown>The response body of the request
- [DELETE]
servicenow:now:table:deleteRecord Deletes a record from a table in the Developer Hub.
The following table describes the input parameters:
Name Type Requirement Description tableNamestringRequired
Name of the table to delete the record from
sysIdstringRequired
Unique identifier of the record to delete
sysparmQueryNoDomainbooleanOptional
Set as
trueto access data across domains if authorized. The default value isfalse.
12.6. Enable Ansible plugins for automation workflows
12.6.1. Enable Ansible plugins for automation workflows
Use the Ansible plugins for Red Hat Developer Hub to integrate Ansible Automation Platform capabilities into your developer portal.
12.6.2. Installing Ansible plugins for Red Hat Developer Hub
Access Ansible-specific portal experience with curated learning paths, push-button content creation, and integrated development tools.
Ansible plugins for Red Hat Developer Hub deliver an Ansible-specific portal experience with curated learning paths, push-button content creation, integrated development tools, and other opinionated resources.
Additional resources
12.6.3. Using Ansible plug-ins for Red Hat Developer Hub
Ansible plug-ins for Red Hat Developer Hub deliver an Ansible-specific portal experience with curated learning paths, push-button content creation, integrated development tools, and other opinionated resources.
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.
Chapter 13. Optimize
13.1. Optimize
Scale your Red Hat Developer Hub deployment for production workloads by configuring high availability, implementing database and cache redundancy, and optimizing plugin startup performance. Optimization tasks ensure your platform maintains reliable service as traffic and usage grow.
13.2. Scale system performance for growing traffic
13.2.1. Scale system performance for growing traffic
Prepare your Red Hat Developer Hub deployment to handle increasing user demand by planning high availability architecture, configuring redundant backend replicas, and caching dynamic plugins to reduce startup time.
13.2.2. Plan production scaling using high availability architecture
Achieving high availability in Red Hat Developer Hub requires implementing redundancy and failover for both the backend service and its data dependencies. This is accomplished through horizontal scaling, database replication, and shared caching to ensure continuous operation during component failures.
13.2.2.1. Deploy multiple stateless instances
Achieving high availability in Red Hat Developer Hub requires implementing redundancy and failover for both the backend service and its data dependencies. This is accomplished through horizontal scaling, database replication, and shared caching to ensure continuous operation during component failures.
13.2.2.1.1. Deploy multiple stateless instances
RHDH backend uses a stateless design to support horizontal scaling. PostgreSQL stores persistent data and the database manages sessions, allowing multiple backend instances to serve any request simultaneously. To improve performance, you can configure an optional logical cache by using Redis.
To maintain backend availability, observe the following architectural requirements:
- Deploy multiple backend instances
- Run at least two backend instances for basic HA.
- Configure a load balancer
- Use platform-provided load balancing, such as OpenShift Routes, Kubernetes Ingress, or cloud provider load balancers.
- Enable health checks
- Configure the load balancer to probe backend health and remove failed instances from rotation.
- Disable session affinity (sticky sessions)
- Database-backed sessions allow any instance to serve any request.
13.2.2.1.2. Implement database HA
RHDH operations rely on PostgreSQL for persistence. A database outage renders the deployment non-functional until the database is restored. For production deployments, you must configure PostgreSQL with high availability (primary-replica replication) to minimize downtime.
If you use catalog providers exclusively, the database acts as an indexed cache. You do not require disaster recovery backups because you can repopulate catalog data from external sources of truth, such as Git repositories, CI/CD platforms, and monitoring tools.
13.2.2.1.3. Implement cache HA
Configuring Redis as a shared logical cache improves production performance by sharing cached data across multiple backend instances. A shared cache makes sure that all instances access the same processed data, such as rendered TechDocs.
If the logical cache fails, the platform remains functional, but you might experience the following symptoms:
- Slower response times due to cache misses.
- Increased database load because the backend must fetch data from PostgreSQL.
- No impact on authentication or core functionality.
For maximum performance stability in production, configure Redis with high availability using Redis Sentinel for small deployments or Redis Cluster for larger deployments.
13.2.3. Configure high availability to maintain performance
Configure high availability to ensure continuous service accessibility by eliminating single points of failure through redundancy and failover mechanisms.
Red Hat Developer Hub supports HA deployments on the following platforms:
- Red Hat OpenShift Container Platform
- Azure Kubernetes Service
- Elastic Kubernetes Service
- Google Kubernetes Engine
The HA deployments enable more resilient and reliable service availability across supported environments.
In a single instance deployment, a failure makes the entire service unavailable. Software crashes, hardware issues, or other disruptions can interrupt development workflows and access to key resources.
With HA enabled, you can scale the number of backend replicas to introduce redundancy. This setup ensures that if one pod or component fails, others continue to serve requests without disruption. The built-in load balancer manages ingress traffic and distributes the load across the available pods. Meanwhile, the RHDH backend manages concurrent requests and resolves resource-level conflicts effectively.
As an administrator, you can configure high availability by adjusting replica values in your configuration file:
-
If you installed using the Operator, configure the replica values in your
Backstagecustom resource. - If you used the Helm chart, set the replica values in the Helm configuration.
13.2.3.1. Configure with the Operator
Configure high availability for Operator deployments by setting the replicas field to a value greater than 1 in the custom resource.
Procedure
In your
Backstagecustom resource (CR), setreplicasto a value greater than1.For example, to configure two replicas (one backup instance):
apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: <your_yaml_file> spec: deployment: patch: spec: replicas: 2
13.2.3.2. Configure with the Helm chart
Configure high availability for Helm deployments by setting the replicas value to greater than 1 in the Helm configuration file.
Procedure
In your Helm chart configuration file, set
replicasto a value greater than1.For example, to configure two replicas (one backup instance):
upstream: backstage: replicas: 2
13.2.4. Configure the dynamic plugins cache
The dynamic plugins cache reduces platform boot time by storing already-installed plugins and skipping redundant downloads when the configuration does not change.
When you enable dynamic plugins cache:
-
The system calculates a checksum of each plugin’s YAML configuration (excluding
pluginConfig). -
The system stores the checksum in a file named
dynamic-plugin-config.hashwithin the plugin’s directory. - During boot, if a plugin’s package reference matches the earlier installation and the checksum does not change, the system skips the download.
- The system automatically removes plugins that you disabled since the earlier boot.
To enable the dynamic plugins cache in RHDH, the plugins directory dynamic-plugins-root must be a persistent volume.
13.2.4.1. Create PVC with Operator
Create a persistent volume claim for the dynamic plugin cache in Operator deployments by replacing the default dynamic-plugins-root volume.
Prerequisites
- You have installed Red Hat Developer Hub on OpenShift Container Platform using the Red Hat Developer Hub Operator.
-
You have installed the OpenShift CLI (
oc).
Procedure
Create the persistent volume definition and save it to a file, such as
pvc.yaml. For example:kind: PersistentVolumeClaim apiVersion: v1 metadata: name: dynamic-plugins-root spec: accessModes: - ReadWriteOnce resources: requests: storage: 5GiNoteThis example uses
ReadWriteOnceas the access mode which prevents many replicas from sharing the PVC across different nodes. To run many replicas on different nodes, depending on your storage driver, you must use an access mode such asReadWriteMany.To apply this PVC to your cluster, run the following command:
$ oc apply -f pvc.yaml
Replace the default
dynamic-plugins-rootvolume with a PVC nameddynamic-plugins-root. For example: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-rootNoteTo avoid adding a new volume, you must use the
$patch: replacedirective.
13.2.4.2. Create PVC with Helm Chart
Create a persistent volume claim for the dynamic plugin cache in Helm deployments to persist the cache across pod restarts.
Prerequisites
- You have installed Red Hat Developer Hub using the Helm chart.
-
You have installed the OpenShift CLI (
oc).
Procedure
Create the persistent volume definition. For example:
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: dynamic-plugins-root spec: accessModes: - ReadWriteOnce resources: requests: storage: 5GiNoteThis example uses
ReadWriteOnceas the access mode which prevents many replicas from sharing the PVC across different nodes. To run many replicas on different nodes, depending on your storage driver, you must use an access mode such asReadWriteMany.To apply this PVC to your cluster, run the following command:
$ oc apply -f pvc.yaml
Configure the Helm chart to use the PVC. For example:
upstream: backstage: extraVolumes: - name: dynamic-plugins-root persistentVolumeClaim: claimName: dynamic-plugins-root - name: dynamic-plugins configMap: defaultMode: 420 name: '{{ printf "%s-dynamic-plugins" .Release.Name }}' optional: true - name: dynamic-plugins-npmrc secret: defaultMode: 420 optional: true secretName: '{{ printf "%s-dynamic-plugins-npmrc" .Release.Name }}' - name: dynamic-plugins-registry-auth secret: defaultMode: 416 optional: true secretName: '{{ printf "%s-dynamic-plugins-registry-auth" .Release.Name }}' - name: npmcacache emptyDir: {} - name: temp emptyDir: {}NoteWhen you configure the Helm chart to use the PVC, you must also include the
extraVolumessection defined in the default Helm chart values.
13.2.4.3. Resolve plugin configuration errors
Troubleshoot and resolve configuration errors that prevent dynamic plugins from loading or operating correctly.
Procedure
- TO DO: Update procedure steps
13.2.5. Enable the plugin assets cache
Use a Redis cache store to improve Developer Hub performance and reliability by caching plugin assets.
Prerequisites
- You have installed Red Hat Developer Hub.
-
You have an active Redis server. For more information on setting up an external Redis server, see the
official Redis documentation.
Procedure
Enable the Developer Hub cache by defining Redis as the cache store type and entering your Redis server connection URL in your
app-config.yamlfile.app-config.yamlfile fragmentbackend: cache: store: redis connection: redis://user:pass@cache.example.com:6379Enable the cache for TechDocs by adding the
techdocs.cache.ttlsetting in yourapp-config.yamlfile. This setting specifies how long, in milliseconds, a statically built asset should stay in the cache.app-config.yamlfile fragmenttechdocs: cache: ttl: 3600000TipOptionally, enable the cache for unsupported plugins that support this feature. See the documentation for each plugin for details.
Chapter 14. Extend
14.1. Extend
Add new capabilities to Red Hat Developer Hub by installing, configuring, and developing dynamic plugins without rebuilding or restarting the core platform. Dynamic plugins enable teams to tailor the developer portal to specific organizational workflows while maintaining upgrade compatibility.
14.2. Manage the plugin ecosystem to add functionality without downtime
14.2.1. Manage the plugin ecosystem to add functionality without downtime
Discover, install, and manage dynamic plugins to extend Red Hat Developer Hub with new capabilities. Dynamic plugins load at runtime from a configured root directory, enabling platform teams to add functionality without rebuilding the application or scheduling downtime.
14.2.2. Install dynamic plugins
14.2.2.1. Install dynamic plugins
Install dynamic plugins by using the Operator or Helm chart to add preinstalled or external capabilities to Red Hat Developer Hub. The backend plugin manager scans a configured root directory for dynamic plugin packages and loads them at startup.
14.2.2.2. Dynamic Plugins
Red Hat Developer Hub implements a dynamic plugin system. You can install, configure, and load plugins at runtime without changing or rebuilding the application. You only need a restart. You can load these plugins from NPM, tarballs, or OCI compliant container images.
With dynamic plugins, instead of modifying the Backstage application itself, you create a dynamic-plugins.yaml file to specify the plugins that Red Hat Developer Hub will install and enable at startup. For example, the following configuration loads a plugin named plugin-name, which is stored in a Quay.io container image at quay.io/account-name/image-name:
dynamic-plugins.yaml fragment
plugins:
- package: oci://quay.io/account-name/image-name:tag
disabled: false
pluginConfig: {}
14.2.2.3. Install with Operator
14.2.2.3.1. Install with Operator
Configure the Red Hat Developer Hub Operator custom resource to install dynamic plugins with dependency management and resource specifications. The Operator automates plugin lifecycle operations during deployments.
14.2.2.3.2. Install dynamic plugins with the Red Hat Developer Hub Operator
You can store the configuration for dynamic plugins in a ConfigMap object that your Backstage custom resource (CR) can reference.
Dynamic plugins might require you to configure certain Kubernetes resources. The documentation refers to these resources as plugin dependencies. For more information, see Dynamic plugins dependency management.
In Red Hat Developer Hub (RHDH), you can automatically create these resources when you apply the Backstage CR to the cluster.
If the pluginConfig field references environment variables, you must define the variables in your <my_product_secrets> secret.
Procedure
- From the OpenShift Container Platform web console, select the ConfigMaps tab.
- Click Create ConfigMap.
From the Create ConfigMap page, select the YAML view option in Configure via and edit the file, if needed.
The following example shows a
ConfigMapobject using the GitHub dynamic plugin: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-catalog-backend-module-github-dynamic' disabled: false pluginConfig: catalog: providers: github: organization: "${GITHUB_ORG}" schedule: frequency: { minutes: 1 } timeout: { minutes: 1 } initialDelay: { seconds: 100 }- Click Create.
- Go to the Topology view.
Click the overflow menu for the Red Hat Developer Hub instance that you want to use and select Edit Backstage to load the YAML view of the Red Hat Developer Hub instance.

Add the
dynamicPluginsConfigMapNamefield to yourBackstageCR. For example:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: my-rhdh spec: application: dynamicPluginsConfigMapName: dynamic-plugins-rhdh- Click Save.
- Navigate back to the Topology view and wait for the Red Hat Developer Hub pod to start.
- Click the Open URL icon to start using the Red Hat Developer Hub platform with the new configuration changes.
Verification
Ensure that the system loads the dynamic plugins configuration, by appending
/api/dynamic-plugins-info/loaded-pluginsto your Red Hat Developer Hub root URL and checking the list of plugins:The following example shows a list of plugins:
[ { "name": "backstage-plugin-catalog-backend-module-github-dynamic", "version": "0.5.2", "platform": "node", "role": "backend-plugin-module" }, { "name": "backstage-plugin-techdocs", "version": "1.10.0", "role": "frontend-plugin", "platform": "web" }, { "name": "backstage-plugin-techdocs-backend-dynamic", "version": "1.9.5", "platform": "node", "role": "backend-plugin" }, ]
14.2.2.4. Dynamic plugin dependency requirements and resource specifications
Dynamic plugins configured for the Backstage custom resource (CR) might require Kubernetes resources called plugin dependencies, which RHDH creates automatically when you apply the CR.
14.2.2.4.1. Cluster level plugin dependencies configuration
You can configure plugin dependencies by including the required Kubernetes resources in the /config/profile/{PROFILE}/plugin-deps directory. You must add the required resources as Kubernetes manifests in YAML format in the plugin-deps directory.
Example showing how to add example-dep1.yaml and example-dep2.yaml as plugin dependencies:
config/
profile/
rhdh/
kustomization.yaml
plugin-deps/
example-dep1.yaml
example-dep2.yaml- If a resource manifest does not specify a namespace, the Operator creates it in the namespace of the Backstage CR.
- Resources can contain {{backstage-name}} and {{backstage-ns}} placeholders. The Operator replaces the {{backstage-name}} placeholder with the name of the Backstage CR, and replaces the {{backstage-ns}} placeholder with the namespace of the Backstage CR.
The kustomization.yaml file must contain the following lines:
configMapGenerator:
- files:
- plugin-deps/example-dep1.yaml
- plugin-deps/example-dep2.yaml
name: plugin-deps14.2.2.4.2. Plugin dependencies infrastructure
To install infrastructural resources that plugin dependencies require, for example, other Operators or custom resources (CR), you can include these in the /config/profile/{PROFILE}/plugin-infra directory.
To create these infrastructural resources (along with the Operator deployment), use the make plugin-infra command.
On a production cluster, use this command with caution as it might reconfigure cluster-scoped resources.
14.2.2.4.3. Plugin configuration
You must reference the plugin dependencies in the dependencies field of the plugin configuration when you apply the Backstage CR.
The Operator creates the resources that the files in the plugin-deps directory describe.
You can reference plugin dependencies in the dynamic-plugins ConfigMap that can either be part of the default profile configuration for all Backstage custom resources or part of the ConfigMap referenced in the Backstage CR. In Red Hat Developer Hub, you can include plugin dependencies in the dynamic plugin configuration.
Each dependencies.ref value can either match the full file name or serve as a prefix for the file name. The Operator creates the resources that the files in the plugin-deps directory describe that start with the specified ref value or exactly match it
Example showing how to add example-dep plugin dependency:
apiVersion: v1
kind: ConfigMap
metadata:
name: default-dynamic-plugins
data:
dynamic-plugins.yaml: |
includes:
- dynamic-plugins.default.yaml
plugins:
- disabled: false
package: "path-or-url-to-example-plugin"
dependencies:
- ref: example-dep14.2.2.5. Install with Helm Chart
14.2.2.5.1. Install with Helm Chart
Configure the Helm chart values file to install dynamic plugins during Red Hat Developer Hub deployment. The Helm chart approach provides fine-grained control over plugin packages and their initialization parameters.
14.2.2.5.2. Installing dynamic plugins using the Helm chart
You can deploy a Developer Hub instance by using a Helm chart, which is a flexible installation method. With the Helm chart, you can load dynamic plugins into your Developer Hub instance without having to recompile your code or rebuild the container.
To install dynamic plugins in Developer Hub using Helm, add the following global.dynamic parameters in your Helm chart:
plugins: the dynamic plugins list intended for installation. By default, the list is empty. You can populate the plugins list with the following fields:-
package: a package specification for the dynamic plugin package that you want to install. You can use a package for either a local or an external dynamic plugin installation. For a local installation, use a path to the local folder containing the dynamic plugin. For an external installation, use a package specification from a public NPM repository. -
integrity(required for external packages): an integrity checksum in the form of<alg>-<digest>specific to the package. Supported algorithms includesha256,sha384andsha512. -
pluginConfig: an optional plugin-specificapp-config.yamlYAML fragment. See plugin configuration for more information. -
disabled: disables the dynamic plugin if set totrue. Default:false. -
forceDownload: Set the value totrueto force a reinstall of the plugin, bypassing the cache. The default value isfalse. pullPolicy: Similar to theforceDownloadparameter and is consistent with other image container platforms. You can use one of the following values for this key:-
Always: This value compares the image digest in the remote registry and downloads the artifact if it has changed, even if you downloaded the plugin before. IfNotPresent: This value downloads the artifact if it is not already present in the dynamic-plugins-root folder, without checking image digests.NoteThe
pullPolicysetting is also applied to the NPM downloading method, althoughAlwayswill download the remote artifact without a digest check. The existingforceDownloadoption remains functional, however, thepullPolicyoption takes precedence. TheforceDownloadoption might be deprecated in a future Developer Hub release.
-
-
-
includes: a list of YAML files using the same syntax.
The system merges the plugins list in the includes file with the plugins list in the main Helm values. If both plugins lists mention a plugin package, the plugins fields in the main Helm values override the plugins fields in the includes file. The default configuration has the dynamic-plugins.default.yaml file, which has all of the dynamic plugins preinstalled in Developer Hub, whether enabled or disabled by default.
14.2.2.5.3. Example configurations
The following examples show how to configure the Helm chart for specific types of dynamic plugin installations.
Configuring a local plugin and an external plugin when the external plugin requires a specific configuration:
global:
dynamic:
plugins:
- package: <alocal package-spec used by npm pack>
- package: <external package-spec used by npm pack>
integrity: sha512-<some hash>
pluginConfig: ...Disabling a plugin from an included file:
global:
dynamic:
includes:
- dynamic-plugins.default.yaml
plugins:
- package: <some imported plugins listed in dynamic-plugins.default.yaml>
disabled: trueEnabling a plugin from an included file:
global:
dynamic:
includes:
- dynamic-plugins.default.yaml
plugins:
- package: <some imported plugin listed in dynamic-plugins.default.yaml>
disabled: falseEnabling a plugin that an included file disables:
global:
dynamic:
includes:
- dynamic-plugins.default.yaml
plugins:
- package: <some disabled plugin listed in dynamic-plugins.default.yaml>
disabled: false # overrides disabled: true from the included file14.2.2.6. Install in an air-gapped environment using the Helm chart
You can install external plugins in an air-gapped environment by setting up a custom NPM registry.
You can configure the NPM registry URL and authentication information for dynamic plugin packages by using a Helm chart. For dynamic plugin packages obtained through npm pack, you can use a .npmrc file.
Using the Helm chart, add the .npmrc file to the NPM registry by creating a secret. For example:
apiVersion: v1
kind: Secret
metadata:
name: <release_name>-dynamic-plugins-npmrc
type: Opaque
stringData:
.npmrc: |
registry=<registry_link>
//<registry_link>:_authToken=<auth_token>
...
Replace <release_name> with your Helm release name. This name is a unique identifier for each chart installation in the Kubernetes cluster.
14.2.2.7. Install in an air-gapped environment using the Operator
To install external dynamic plugins in an air-gapped environment, configure a custom NPM registry by mounting a secret into the Developer Hub Operator.
Prerequisites
- An OpenShift Container Platform administrator has installed the Red Hat Developer Hub Operator.
- You have set up a custom NPM registry that is accessible from within your cluster and contains the required dynamic plugin packages.
Procedure
Create a secret containing your
.npmrcconfiguration that points to your internal NPM registry:apiVersion: v1 kind: Secret metadata: name: dynamic-plugins-npmrc type: Opaque stringData: .npmrc: | registry=https://<your_internal_registry> //<your_internal_registry>:_authToken=<your_auth_token>Apply the secret to your namespace:
$ oc apply -f dynamic-plugins-npmrc.yaml -n my-rhdh-project
Add the secret to the
spec.application.extraFiles.secretsfield in yourBackstagecustom resource, targeting theinstall-dynamic-pluginsinit container:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: my-rhdh spec: application: extraFiles: secrets: - name: dynamic-plugins-npmrc mountPath: /opt/app-root/src/.npmrc.dynamic-plugins containers: - install-dynamic-pluginsThe
install-dynamic-pluginsinit container reads the.npmrcfile from/opt/app-root/src/.npmrc.dynamic-plugins/.npmrcto resolve plugin packages from your internal registry.Apply the updated custom resource:
$ oc apply -f my-rhdh.yaml -n my-rhdh-project
Verification
Verify that the init container used your custom registry by checking the init container logs:
$ oc logs -c install-dynamic-plugins deploy/backstage-my-rhdh
14.2.2.8. Mirror dynamic plugins in disconnected environments
14.2.2.8.1. Mirror dynamic plugins in disconnected environments
Mirror dynamic plugin OCI artifacts to a local registry for deployments in restricted or air-gapped environments. Red Hat Developer Hub distributes plugins as Open Container Initiative (OCI) artifacts that must be accessible from within the cluster network.
14.2.2.8.2. Mirror to a partially disconnected environment
Use this procedure to mirror plugins from a catalog index to a partially disconnected environment.
Procedure
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Mirror the plugin catalog index and all referenced plugin OCI artifacts to your target registry by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-registry <target_registry>where:
<target_registry>Enter the URL of the target mirror registry, such as,
registry.example.com.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
14.2.2.8.3. Mirror to a fully disconnected environment
This two-phase process exports plugins to disk from a connected host, transfers them to a restricted network, then imports them to your internal registry.
Procedure
Download the plugin mirroring script by running the following command:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Export the plugin catalog index and all referenced plugin OCI artifacts to disk by running the following command:
$ bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 \ --to-dir <my_plugin_mirror_dir>where:
<my_plugin_mirror_dir>Enter the absolute path to a directory where you want to export the plugin artifacts, for example,
/home/user/rhdh-plugins-mirror.NoteThe script can take several minutes to complete. It mirrors the catalog index image and all plugin OCI artifacts that the index references.
-
Transfer the directory specified by the
--to-diroption to your disconnected environment. From a machine in your disconnected environment that has access to the target mirror registry, import the plugin artifacts by running the following command:
$ bash mirror-plugins.sh \ --from-dir <my_plugin_mirror_dir> \ --to-registry <target_registry>
where:
<my_plugin_mirror_dir>- Enter the path to the directory containing the exported plugin artifacts.
<target_registry>-
Enter the URL of the target mirror registry, for example,
registry.example.com.
14.2.2.8.4. Mirror specific plugins
Use this procedure to mirror specific plugins by specifying their OCI URLs directly.
Procedure
Download the mirroring script:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
To mirror individual plugins by specifying their OCI URLs directly, run the mirroring script by using the
bashcommand with the appropriate set of options:For example:
bash mirror-plugins.sh \ --plugins oci://quay.io/rhdh-plugin-catalog/backstage-community-plugin-quay:<tag> \ oci://quay.io/rhdh-plugin-catalog/backstage-community-plugin-github-actions:<tag> \ --to-registry <my.registry.example.com>where:
<tag>-
Enter your RHDH version and the plugin version, in the format
<rhdh-version>--<plugin-version>. To find these versions, complete the following steps:
Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.10, use the format
1.10--<plugin-version>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
where:
--to-registry <my.registry.example.com>- Enter the URL for the target mirror registry where you want to mirror the catalog index.
14.2.2.8.5. Mirror plugins from a file
Use this procedure to mirror plugins from a file containing a list of plugin URLs.
Procedure
Create a text file listing the plugins to mirror (one per line), as follows:
Example
plugins.txtfile:oci://quay.io/rhdh-plugin-catalog/backstage-community-plugin-quay:<tag> oci://quay.io/rhdh-plugin-catalog/backstage-community-plugin-github-actions:<tag> oci://quay.io/rhdh-plugin-catalog/backstage-community-plugin-azure-devops:<tag>
where:
<tag>-
Enter your RHDH version and the plugin version, in the format
<rhdh-version>--<plugin-version>. To find these versions, complete the following steps:
Locate the plugin version in the Dynamic Plugins Reference guide. For example, for RHDH 1.10, use the format
1.10--<plugin-version>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Download the mirroring script:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
Run the mirroring script by using the
bashcommand with the appropriate set of options:For example:
bash mirror-plugins.sh \ --plugin-list plugins.txt \ --to-registry <my.registry.example.com>where:
--plugin-list plugins.txt- A text file listing the plugins to mirror.
--to-registry <my.registry.example.com>- Enter the URL for the target mirror registry where you want to mirror the catalog index.
14.2.2.8.6. Combine plugin sources
You can combine any of the plugin sources (for example, catalog index, plugin list file, and direct URLs) in a single mirroring operation. The script automatically deduplicates plugins if the same plugin is present in many sources.
Procedure
Download the mirroring script:
$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/.rhdh/scripts/mirror-plugins.sh
To combine many plugin sources, run the mirroring script by using the
bashcommand with the appropriate set of options:For example:
bash mirror-plugins.sh \ --plugin-index oci://registry.access.redhat.com/rhdh/plugin-catalog-index:1.9 \ --plugin-list custom-plugins.txt \ --plugins 'oci://registry.internal.example.com/custom/my-plugin:1.0' \ --to-registry registry.example.comwhere:
--plugin-list custom-plugins.txt- A text file listing the plugins to mirror.
--to-registry <my.registry.example.com>- Enter the URL for the target mirror registry where you want to mirror the catalog index.
14.2.2.9. Example of installing a custom plugin in Red Hat Developer Hub
This example demonstrates how to package and install dynamic plugins by using the Backstage Entity Feedback community plugin that is not included in Red Hat Developer Hub pre-installed dynamic plugins.
Limitations:
You need to ensure that you build your custom plugin with a compatible version of Backstage. In Developer Hub, click Settings. Your custom plugin must be compatible with the Backstage Version (or the closest earlier version) that the Metadata section of Red Hat Developer Hub displays.
For example, if you view the history of the
backstage.jsonfile for the Entity Feedback plugin, the1fc87decommit is the closest earlier version to Backstage version of 1.39.1.
Prerequisites
- Your local environment meets the following requirements:
- Node.js: Version 22.x
- Yarn: Version 4.x
- git CLI
- jq CLI: Command-line JSON processor
- OpenShift CLI (oc): The client for interacting with your OpenShift cluster.
- Container runtime: You need either podman or docker to package the plugin into an OCI image and to log in to registries.
- Container registry access: Access to an OCI-compliant container registry, such as the internal OpenShift registry or a public registry such as Quay.io.
Procedure
Clone the source code for the Entity Feedback plugin, as follows:
$ git clone https://github.com/backstage/community-plugins.git $ cd community-plugins
Prepare your environment to build the plugin by enabling Yarn for your Node.js installation, as follows:
$ corepack enable yarn
Install the dependencies, compile the code, and build the plugins, as follows:
$ cd workspaces/entity-feedback $ yarn install $ yarn tsc $ yarn build:all
NoteAfter this step, with upstream Backstage, you publish the built plugins to a NPM or NPM-compatible registry. In this example, as you are building this plugin to support dynamic loading by Red Hat Developer Hub, you can skip the
npm publishstep that publishes the plugin to a NPM registry. Instead, you can package the plugin for dynamic loading and publish it as a container image onQuay.ioor your preferred container registry.Prepare the Entity Feedback front-end plugin by using the Red Hat Developer Hub CLI. The following command uses the plugin files in the
distfolder that theyarn build:allcommand generated, and creates a newdist-scalprumfolder that has the necessary configuration and source files to enable dynamic loading:$ cd plugins/entity-feedback $ npx @red-hat-developer-hub/cli@latest plugin export
When this command packages a front-end plugin, it uses a default Scalprum configuration if one is not found. The Scalprum configuration specifies the plugin entry point and exports, and then builds a
dist-scalprumfolder that has the dynamic plugin. The following example shows the default Scalprum configuration. However, you can add ascalprumkey to thepackage.jsonfile used by your plugin to set custom values, if necessary:{ "name": "backstage-community.plugin-entity-feedback", "exposedModules": { "PluginRoot": "./src/index.ts" } }Red Hat Developer Hub uses the following
plugin-manifest.jsonfile to load the plugin. This file is in thedist-dynamic/dist-scalprumfolder:{ "name": "backstage-community.plugin-entity-feedback", "version": "0.6.0", "extensions": [], "registrationMethod": "callback", "baseURL": "auto", "loadScripts": [ "backstage-community.plugin-entity-feedback.fd691533c03cb52c30ac.js" ], "buildHash": "fd691533c03cb52c30acbb5a80197c9d" }Package the plugin into a container image and publish it to Quay.io or your preferred container registry:
$ export QUAY_USER=replace-with-your-username $ export PLUGIN_NAME=entity-feedback-plugin $ export VERSION=$(cat package.json | jq .version -r) $ npx @red-hat-developer-hub/cli@latest plugin package \ --tag quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION $ podman login quay.io $ podman push quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION
Repeat the same steps for the backend plugin. Backend plugins do not require Scalprum, and the export generates a
dist-dynamicfolder instead of adist-scalprumfolder:$ cd ../entity-feedback-backend/ $ npx @red-hat-developer-hub/cli@latest plugin export $ export QUAY_USER=replace-with-your-username $ export PLUGIN_NAME=entity-feedback-plugin-backend $ export VERSION=$(cat package.json | jq .version -r) $ npx @red-hat-developer-hub/cli@latest plugin package \ --tag quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION $ podman push quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION
Those commands publish two container images to your container registry.
The following image shows the container images published to Quay.io:

14.2.3. Install plugins using custom certificates to secure private registry connections
14.2.3.1. Install plugins using custom certificates to secure private registry connections
Install OCI plugins from internal registries served over HTTPS with corporate CA certificates. Custom certificate configuration ensures Red Hat Developer Hub trusts your private registry connections during plugin installation.
14.2.3.2. Install from secure container registries
Use this procedure to install plugins from OCI registries by configuring per-registry TLS certificates.
Procedure
Create a ConfigMap from the CA certificate in the namespace where you are deploying your RHDH instance:
oc create configmap registry-ca-crt --from-file=ca.crt
Mount the CA certificate ConfigMap into your RHDH configuration:
For a Helm chart installation, update your Helm chart configuration file, as follows:
upstream: backstage: extraVolumes: # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the volumes defined in the default Helm Chart # before adding the new one # ... - name: registry-ca-crt configMap: name: registry-ca-crt initContainers: - name: install-dynamic-plugins # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the other fields defined in the default Helm Chart # ... volumeMounts: # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the volume mounts defined in the default Helm Chart # before adding the new one # ... - name: registry-ca-crt # Hostname and port must match your target registry mountPath: '/etc/containers/certs.d/reg.example.com:5000'For Operator-based installations, update your Backstage Custom Resource (CR), as follows:
spec: application: extraFiles: configMaps: - name: registry-ca-crt # Hostname and port must match your target registry mountPath: '/etc/containers/certs.d/reg.example.com:5000' containers: - install-dynamic-plugins
14.2.3.3. Install using trusted certificate authorities
Use this procedure to install plugins from OCI registries by mounting a CA bundle.
Procedure
Create a ConfigMap from the CA bundle in the namespace where you are deploying your RHDH instance:
oc create configmap registry-ca-bundle --from-file=ca-bundle.crt
Mount the CA bundle ConfigMap into your RHDH configuration
For a Helm chart installation, update your Helm chart configuration file, as follows:
upstream: backstage: extraVolumes: # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the volumes defined in the default Helm Chart # before adding the new one # ... - name: registry-ca-bundle configMap: name: registry-ca-bundle initContainers: - name: install-dynamic-plugins # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the other fields defined in the default Helm Chart # ... volumeMounts: # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the volume mounts defined in the default Helm Chart # before adding the new one # ... - name: registry-ca-bundle mountPath: /etc/pki/tls/certs/For Operator-based installations, update your Backstage Custom Resource (CR), as follows:
spec: application: extraFiles: configMaps: - name: registry-ca-bundle mountPath: /etc/pki/tls/certs/ containers: # Note: Set to "*" instead if you want to mount it in all containers - install-dynamic-plugins
14.2.3.4. Install with cluster-wide trust bundles
Use this procedure to install plugins from OCI registries in an OpenShift environment by using cluster-wide trusted CA bundles.
Prerequisites
- Your cluster administrator must add the trusted corporate CA bundle to the cluster-wide configuration. For more information, see Security and compliance in the OpenShift Container Platform documentation.
Procedure
Create an empty ConfigMap in the namespace where you are deploying your RHDH instance. You must add the
config.openshift.io/inject-trusted-cabundlelabel to your ConfigMap, as follows:apiVersion: v1 kind: ConfigMap metadata: name: trusted-ca labels: config.openshift.io/inject-trusted-cabundle: "true"Wait for the cluster to inject the trusted CA bundle into the ConfigMap. You can verify with the following command:
oc get cm trusted-ca
You should see a block of certificates under the
ca-bundle.crtkey.Mount the ConfigMap into the
/etc/pki/ca-trust/extracted/pempath of the RHDH init container.For a Helm chart installation, update your Helm chart configuration file, as follows:
upstream: backstage: extraVolumes: # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the volumes defined in the default Helm Chart # before adding the new one # ... - name: trusted-ca configMap: name: trusted-ca initContainers: - name: install-dynamic-plugins # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the other fields defined in the default Helm Chart # ... volumeMounts: # IMPORTANT: Due to a Helm limitation with arrays, you must also # include all the volume mounts defined in the default Helm Chart # before adding the new one # ... - name: trusted-ca mountPath: /etc/pki/ca-trust/extracted/pemFor Operator-based installations, update your Backstage Custom Resource (CR), as follows:
spec: application: extraFiles: configMaps: - name: trusted-ca mountPath: /etc/pki/ca-trust/extracted/pem containers: # Note: Set to "*" instead if you want to mount it in all containers - install-dynamic-plugins
14.2.4. Enable pre-loaded container plugins
The RHDH container image preinstalls a set of dynamic plugins to enhance functionality. However, due to mandatory configuration requirements, the image disables most of the plugins.
You can enable and configure the plugins in the RHDH container image. This includes how to manage the default configuration, set necessary environment variables, and ensure the proper functionality of the plugins within your application.
Since RHDH 1.10, the latest version of the dynamic-plugins.default.yaml file exists in the plugin catalog index container image.
To retrieve the latest version of the dynamic-plugins.default.yaml file, run the following commands in your terminal:
$ unpack () {
if [[ ! $1 ]]; then
echo "Usage: unpack reg/org/container:tagorsha [file(s)-to-unpack-pattern]"
echo "Example: unpack quay.io/rhdh/plugin-catalog-index:1.10 dynamic-plugins.default.yaml"
else
local FILES=""
if [[ $2 ]]; then FILES="$2"; fi
local IMAGE="$1"
local DIR="${IMAGE//:/_}"
DIR="/tmp/${DIR//\//-}"
rm -fr "$DIR"; mkdir -p "$DIR"; container_id=$(podman create "${IMAGE}")
podman export $container_id -o /tmp/image.tar && tar xf /tmp/image.tar -C "${DIR}/" $FILES; podman rm $container_id; rm -f /tmp/image.tar
echo "Unpacked $IMAGE into $DIR"
cd $DIR;
if [[ $FILES ]]; then ls -la $FILES; else tree -d -L 3 -I "usr|root|buildinfo"; fi
fi
}
$ unpack registry.access.redhat.com/rhdh/plugin-catalog-index:1.10 dynamic-plugins.default.yaml
# For a pre-GA CI container:
$ unpack quay.io/rhdh/plugin-catalog-index:1.10 dynamic-plugins.default.yaml
Alternatively, you can use an oci:// plugin reference, and the special {{inherit}} tag will fetch the latest compatible plugin, including its default configuration, for your current RHDH version.
Prerequisites
-
You have deployed the RHDH application, and have access to the logs of the
install-dynamic-pluginsinit container. - You have the necessary permissions to change plugin configurations and access the application environment.
- You have identified and set the required environment variables referenced by the plugin’s default configuration. You must define these environment variables in the Helm Chart or Operator configuration.
Procedure
-
Start your RHDH application and access the logs of the
install-dynamic-pluginsinit container within the RHDH pod. - Identify the Red Hat supported plugins that the system disables by default.
-
If you need to provide additional configuration for the plugin, other than enabling it, copy the package configuration from the
dynamic-plugins.default.yamlfile you extracted above. For plugins which require no configuration, you can simply reference the plugin and set it todisabled:falseas in the example below. -
To use the latest compatible plugin version, use the special tag
{{inherit}}; this will also load the default configuration, which you can then override. Open the plugin configuration file (Custom Resource or ConfigMap) and locate the plugin entry you want to enable.
The location of the plugin configuration file varies based on the deployment method. For more details, see Installing and viewing plugins in Red Hat Developer Hub.
Change the
disabledfield tofalseand add the package name as follows:plugins: - package: oci://registry.access.redhat.com/rhdh/backstage-community-plugin-analytics-provider-segment:{{inherit}} disabled: false+
ImportantWhen you use the
{{inherit}}tag, z-stream updates automatically update the plugin to the latest version from the base configuration. If a plugin update causes issues, you can pin the plugin to a specific version. For more information, see Roll back a dynamic plugin to a previous version.or using the deprecated wrapper syntax:
plugins: - package: './dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment' disabled: falseFor more information about how to configure dynamic plugins in Developer Hub, see Configuring dynamic plugins.
Verification
- Restart the RHDH application and verify that the plugin is successfully activated and configured.
- Verify the application logs for confirmation and ensure the plugin is functioning as expected.
14.2.5. Browse and manage available plugins using the Extensions UI
14.2.5.1. Browse and manage available plugins using the Extensions UI
Browse, install, and manage available plugins through the Extensions interface in Red Hat Developer Hub. The Extensions feature provides a centralized UI to discover plugins that extend platform functionality and streamline development workflows.
14.2.5.2. Manage plugins
14.2.5.2.1. Manage plugins
Control access to plugin administration, configure persistent storage, and manage the plugin lifecycle through the Extensions UI. Role-based access control restricts who can install, enable, or disable plugins on the platform.
14.2.5.2.2. Control plugin administration access
You can add Extensions permissions by creating or updating and existing RBAC role. For more information about using RBAC to manage role-based controls, see Managing role-based access controls (RBAC) using the Red Hat Developer Hub Web UI.
Prerequisites
-
If RBAC is enabled, you have a role with the following permissions:
policy.entity.create,policy.entity.update,policy.entity.read,catalog.entity.read.
Procedure
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.
- Click Create to create a role.
- Enter the user name and description (optional) of role in the given fields and click Next.
- In Add users and groups, select the user name, and click Next.
- In Add permission policies, select Extensions from the plugins dropdown.
- Expand Extensions, select both the Create and Read permissions for the Extensions plugin and click Next.
Click Create to create the role.

Verification
After you refresh the RHDH application, when you select a plugin, the Actions drop-down is active. When you click the Actions drop-down, you can edit the plugin configuration, and enable or disable the plugin.
Additional resources
14.2.5.2.3. Configure persistent storage for plugin installations
This feature is supported in development environments only. In a production environment, the interface prevents plugin installation and is not supported.
When you install a plugin using Extensions UI, the system saves the configuration to a persistent volume, preserving it across application restarts.
You must create a persistent volume claim (PVC) to ensure that the cache persists when you restart the RHDH application. For more information about using the dynamic plugins cache, see Using the dynamic plugins cache.
Prerequisites
- You have created a persistent volume claim (PVC) for the dynamic plugins cache with the name dynamic-plugins-root.
- You have installed Red Hat Developer Hub using the Helm chart or the Operator.
-
You have installed the OpenShift CLI (
oc).
Procedure
Create the extensions configuration file and save it as
dynamic-plugins.extensions.yaml. For example:includes: - dynamic-plugins.default.yaml plugins: - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-extensions disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-marketplace: translationResources: - importName: marketplaceTranslations ref: marketplaceTranslationRef module: Alpha appIcons: - name: pluginsIcon importName: PluginsIcon dynamicRoutes: - path: /extensions importName: DynamicMarketplacePluginRouter menuItem: icon: pluginsIcon text: Extensions textKey: menuItem.extensions menuItems: extensions: parent: default.admin - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-extensions-backend-dynamic disabled: false pluginConfig: extensions: installation: enabled: true saveToSingleFile: file: /opt/app-root/src/dynamic-plugins-root/dynamic-plugins.extensions.yamlwhere:
translationResources- Sets the extension point for localization.
Copy the file to your cluster by running the following commands:
oc get pods -n <your_namespace> oc cp ./dynamic-plugins.extensions.yaml <your_namespace>/<pod_name>:/opt/app-root/src/dynamic-plugins-root/dynamic-plugins.extensions.yaml
Update your RHDH application to use this file:
For operator-based installations:
Update your Backstage CR to update the
NODE_ENVenvironment variable todevelopment, as follows:apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: developer-hub namespace: rhdh spec: application: dynamicPluginsConfigMapName: dynamic-plugins-rhdh extraEnvs: envs: - name: NODE_ENV value: "development" secrets: - name: secrets-rhdh extraFiles: mountPath: /opt/app-root/src route: enabled: true database: enableLocalDb: trueUpdate your
dynamic-plugins-rhdhconfig map to include your extensions configuration file, as follows:kind: ConfigMap apiVersion: v1 metadata: name: dynamic-plugins-rhdh namespace: rhdh data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml - /dynamic-plugins-root/dynamic-plugins.extensions.yaml plugins: []
For Helm chart installations:
Upgrade the Helm release to include your extensions configuration file and update the
NODE_ENVenvironment variable todevelopment:global: auth: backend: enabled: true clusterRouterBase: apps.<clusterName>.com dynamic: includes: - dynamic-plugins.default.yaml - /dynamic-plugins-root/dynamic-plugins.extensions.yaml upstream: backstage: extraEnvVars: - name: NODE_ENV value: development- Click Upgrade
Verification
Enable a plugin by using the Extensions UI, restart your RHDH application, and refresh the UI to confirm that you enabled the plugin.
14.2.5.2.4. View plugins
You can view available plugins for your Red Hat Developer Hub application on the Extensions page.
Procedure
- Open your RHDH application and click Administration > Extensions.
Go to the Catalog tab to view a list of available plugins and related information.

14.2.5.2.5. Search for plugins by name
You can use the search bar in the header to filter the Extensions plugin cards by name. For example, if you type “A” into the search bar, Extensions shows only the plugins that contain the letter “A”.
Procedure
In the header search bar, enter a plugin name, such as "Dynatrace".

- Optional: Refine your search by selecting one of the following filters:
- Category
- Author
- Support type
Verification
- The Extensions list updates to display only the plugins that match your search text and selected filters.
14.2.5.2.6. View installed plugins
Using the Dynamic Plugins Info front-end plugin, you can view plugins that your Red Hat Developer Hub application currently has installed. Red Hat Developer Hub enables the Dynamic Plugins Info plugin by default.
Procedure
- Open your Developer Hub application and click Administration > Extensions.
- Go to the Installed tab to view a list of installed plugins and related information.
14.2.5.2.7. Install and configure portal plugins
You can install and configure plugins by using Extensions.
Prerequisites
- You have configured RHDH to allow plugins installation from Extensions.
- You have added a custom Developer Hub application configuration.
Procedure
- Navigate to Extensions.
- Select a plugin to install.
Click the Install button.

The code editor is displayed that displays the plugin default configuration.
Update the plugin configuration, if necessary.

- Click Install
To view the plugins that require a restart, click View plugins in the alert message.

- Restart your RHDH application.
Verification
- After you restart your RHDH application, navigate to Extensions.
- Select the plugin that you have installed.
- The Actions button is displayed.
14.2.5.2.8. Use RHDH Local to test installing plugins by using Extensions
RHDH Local provides a ready-to-use environment for testing the Extensions feature without additional configuration. Extensions is enabled by default, allowing you to install and test plugins directly from the RHDH web interface.
Red Hat maintains RHDH Local as an open source project, but does not support it or subject it to any service level agreement (SLA). There is no official, or commercial support for RHDH Local. Use RHDH Local at your own risk.
RHDH Local is NOT a substitute for Red Hat Developer Hub. It’s intended use is for development and testing purposes only, not for production use.
RHDH Local is designed for individual developers to try out various RHDH features, not for use by development teams as there is no out-of-the-box RBAC support.
For information about installing and using RHDH Local to manage plugins through the Extensions UI, see Managing plugins from the UI in the RHDH Local documentation.
14.2.5.2.9. Enable and disable portal plugins
Use this procedure to enable or disable plugins through the Extensions interface.
Prerequisites
- You have configured RHDH to allow plugins installation from Extensions.
- You have added a custom Developer Hub application configuration.
Procedure
- Navigate to Extensions.
- Select a plugin to enable or disable.
Click the Enable/Disable slider.

To view the plugins that require a restart, click View plugins in the alert message.

- Restart your RHDH application.
Verification
- After you restart your RHDH application, navigate to Extensions.
- Select the plugin that you have installed.
- Verify that the system updated the Enable/Disable slider.
14.2.5.2.10. Disable the Extensions UI
The Extensions feature is available by default. To remove the Extensions interface (Marketplace) from your instance, you must disable the relevant plugins.
Procedure
Edit your
dynamic-plugins.yamlwith the following content.plugins: - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-extensions disabled: true - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-catalog-backend-module-extensions-dynamic disabled: true - package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-extensions-backend-dynamic disabled: trueNoteDisabling these plugins removes the Catalog and Installed tabs. You can still view a basic list of installed plugins by selecting Administration > Extensions.
14.2.7. Configure route bindings and mount points for component integration
14.2.7.1. Configure route bindings and mount points for component integration
Bind dynamic plugins to existing routes and attach custom UI components to predefined mount points. Route bindings and mount points enable plugins to extend entity pages, application headers, and providers without modifying the core platform layout.
14.2.7.2. Bind dynamic plugins to existing routes
You can bind to existing plugins and their routes, and declare new targets sourced from dynamic plugins as shown in the following routeBindings configuration:
# dynamic-plugins-config.yaml plugins: - plugin: <plugin_path_or_url> disabled: false pluginConfig: dynamicPlugins: frontend: my-plugin: routeBindings: targets: - name: <plugin_name>Plugin importName: <plugin_key>Plugin module: CustomModule bindings: - bindTarget: "<plugin_name>Plugin.externalRoutes" bindMap: headerLink: "<plugin_name>Plugin.routes.root"
where:
my-plugin- The plugin package name.
targets- A new bind target.
name-
Optional: Defaults to
importName. Explicit name of the plugin that exposes the bind target. importName-
Required: Explicit import name that references a
BackstagePlugin<{}>implementation. module-
Optional: Same as the key in
scalprum.exposedModulesin thepackage.jsonfile of the plugin. bindTarget- Required: One of the supported or imported bind targets.
bindMap-
Required: A map of route bindings similar to
bindfunction options.
To configure routeBindings, complete the following steps:
-
Define new targets using
routeBindings.targets. Set the requiredimportNameto aBackstagePlugin<{}>implementation. Declare route bindings using the
routeBindings.bindingsfield by settingbindTargetto the name of the target to bind to. This is a dynamic or static target, such as:-
catalogPlugin.externalRoutes -
catalogImportPlugin.externalRoutes -
techdocsPlugin.externalRoutes scaffolderPlugin.externalRoutesYou can extend existing pages with additional content by using mount points. The application defines these identifiers throughout the system.
-
14.2.7.3. Configure mount points to attach custom UI components
14.2.7.3.1. Configure mount points to attach custom UI components
Attach UI components to predefined locations in the Red Hat Developer Hub interface by using mount points. Mount points let plugins inject content into entity pages, application headers, listeners, and providers without modifying the core application code.
14.2.7.3.2. Customize the entity page
You can extend catalog components and additional views.
The available mount points include the following:
| Mount point | Description | Visible even when you enable no plugins |
|---|---|---|
|
|
Administration plugins page |
NO |
|
|
Administration RBAC page |
NO |
|
|
Catalog entity menu |
YES for all entities |
|
|
Catalog entity overview page |
YES for all entities |
|
|
Catalog entity Topology tab |
NO |
|
|
Catalog entity Issues tab |
NO |
|
|
Catalog entity Pull Requests tab |
NO |
|
|
Catalog entity CI tab |
NO |
|
|
Catalog entity CD tab |
NO |
|
|
Catalog entity Kubernetes tab |
NO |
|
|
Catalog entity Image Registry tab |
NO |
|
|
Catalog entity Monitoring tab |
NO |
|
|
Catalog entity Lighthouse tab |
NO |
|
|
Catalog entity API tab |
YES for entity of |
|
|
Catalog entity Dependencies tab |
YES for entity of |
|
|
Catalog entity Documentation tab |
YES for entity that satisfies |
|
|
Catalog entity Definitions tab |
YES for entity of |
|
|
Catalog entity Diagram tab |
YES for entity of |
|
|
Search result type |
YES, default catalog search type is available |
|
|
Search filters |
YES, default catalog kind and lifecycle filters are visible |
|
|
Search results content |
YES, default catalog search is present |
Mount points within a catalog such as entity.page. render as tabs and become visible only if at least one plugin contributes to them, or if they can render static content.
Each entity.page. mount point has the following variations:
-
/contexttype that serves to create React contexts -
/cardstype for regular React components
The following is an example of the overall configuration structure of a mount point:
# dynamic-plugins-config.yaml plugins: - plugin: <plugin_path_or_url> disabled: false pluginConfig: dynamicPlugins: frontend: my-plugin: # The plugin package name mountPoints: # (Optional): Uses existing mount points - mountPoint: <mountPointName>/[cards|context] module: CustomModule importName: <pluginName>PluginPage config: # (Optional): Lets you pass additional configuration to the component layout: {} # Used only in/cardstype if: # Used only in/cardstype allOf|anyOf|oneOf: - isMyPluginAvailable - isKind: component - isType: service - hasAnnotation: annotationKey props: {} # React props passed to the component
Each mount point supports additional configuration:
-
layout: Used only in*/cardstype which renders visible content. Lets you pass MUI sx properties to the component. This is useful when you want to control the layout of the component. Theentity.page.*mount points are rendered as CSS grid, so SX property lets you to control the grid layout and exact positioning of the rendered component. -
props: React props passed to the component. Useful when you want to pass additional data to the component. -
if: Used only in\*/cardstype which renders visible content. Passed to<EntitySwitch.Case if={<here>}.
The available conditions include:
-
allOf: The configuration must meet all conditions -
anyOf: The configuration must meet at least one condition -
oneOf: The configuration must meet only one condition
Conditions are:
-
isKind: Accepts a string or a list of string with entity kinds. For exampleisKind: componentrenders the component only for entity ofkind: Component. -
isType: Accepts a string or a list of string with entity types. For exampleisType: servicerenders the component only for entities ofspec.type: 'service'. -
hasAnnotation: Accepts a string or a list of string with annotation keys. For examplehasAnnotation: my-annotationrenders the component only for entities that have definedmetadata.annotations['my-annotation']. -
Condition imported from the
moduleof the plugin: Must be function name exported from the samemodulewithin the plugin. For exampleisMyPluginAvailablerenders the component only ifisMyPluginAvailablefunction returnstrue. The function must have the following signature:(e: Entity) ⇒ boolean.
The entity page supports adding more items to the menu at the top right of the page. The exported component is a form of dialog wrapper component that accepts an open boolean property and an onClose event handler property as shown in the following example:
export type SimpleDialogProps = {
open: boolean;
onClose: () => void;
};
You can configure the menu entry by using the props configuration entry for the mount point. The title and icon properties sets the text and icon of the menu item. You can use any system icon or icon added through a dynamic plugin. The following is an example configuration:
# dynamic-plugins-config.yaml
plugins:
- plugin: <plugin_path_or_url>
disabled: false
pluginConfig:
dynamicPlugins:
frontend:
my-dynamic-plugin-package:
appIcons:
- name: dialogIcon
importName: DialogIcon
mountPoints:
- mountPoint: entity.context.menu
importName: SimpleDialog
config:
props:
title: Open Simple Dialog
icon: dialogIcon14.2.7.3.3. Add application headers
You can customize global headers by specifying configurations in the app-config.yaml file as shown in the following example:
# app-config.yaml
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
mountPoints:
- mountPoint: application/header # Adds the header as a global header
importName: <header_component> # Specifies the component exported by the global header plugin
config:
position: above-main-content # Supported values: (`above-main-content`| above-sidebar`)
To configure many global headers at different positions, add entries to the mountPoints field.
14.2.7.3.4. Add application listeners
You can add application listeners by using the application/listener mount point as shown in the following example:
# app-config.yaml
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
mountPoints:
- mountPoint: application/listener
importName: <exported listener component>
You can configure many application listeners by adding entries to the mountPoints field.
14.2.7.3.5. Add application providers
You can add application providers by using the application/provider mount point. You can use a mount point to configure a context provider as shown in the following example:
# app-config.yaml
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
dynamicRoutes:
- path: /<route>
importName: Component # The component to load on the route
mountPoints:
- mountPoint: application/provider
importName: <exported provider component>-
You can configure many application providers by adding entries to the
mountPointsfield. -
The
package_namekey underdynamicPlugins.frontendmust match thescalprum.namevalue in thepackage.jsonfile of your plugin. This ensures your dynamic plugin loads correctly at runtime.
14.2.7.4. Customize and extend catalog entity tabs
You can customize and extend the set of tabs by using the entityTabs configuration as in the following example:
# dynamic-plugins-config.yaml
plugins:
- plugin: <plugin_path_or_url>
disabled: false
pluginConfig:
dynamicPlugins:
frontend:
<package_name>: # The plugin package name
entityTabs:
# Specifies a new tab
- path: /new-path
title: My New Tab
mountPoint: entity.page.my-new-tab
# Changes an existing tab's title or mount point
- path: /
title: General
mountPoint: entity.page.overview # Can be customized
# Specifies the sub-path route in the catalog where this tab is available
- path: "/pr"
title: "Changed Pull/Merge Requests" # Specifies the title you want to display
priority: 1
# The base mount point name available on the tab
mountPoint: "entity.page.pull-requests"
- path: "/"
title: "Changed Overview"
mountPoint: "entity.page.overview"
# Specifies the order of tabs. The tabs with higher priority values appear first
priority: -6
Each entity tab entry requires the following attributes: * path: Specifies the sub-path route in the catalog where this tab is available. * title: The title displayed to the user. * mountPoint: The base mount point name available on the tab. This name is expanded to create two mount points per tab, one appended with /context and the second appended with /cards. * priority: (Optional): Determines the order of tabs. Tabs with higher priority values appear first. You can set a negative priority to hide default tabs.
You can configure dynamic front-end plugins to target the mount points exposed by the entityTabs configuration. The following are the default catalog entity routes in the default order:
| Route | Title | Mount Point | Entity Kind |
|---|---|---|---|
|
|
Overview |
|
Any |
|
|
Topology |
|
Any |
|
|
Issues |
|
Any |
|
|
CPull/Merge Requests |
|
Any |
|
|
CI |
|
VAny |
|
|
CD |
|
Any |
|
|
Kubernetes |
|
Any |
|
|
Image Registry |
|
Any |
|
|
Monitoring |
|
Any |
|
|
Lighthouse |
|
Any |
|
|
Api |
|
kind: Service or kind: Component |
|
|
Dependencies |
|
kind: Component |
|
|
Docs |
|
Any |
|
|
Definition |
|
kind: API |
|
|
Diagram |
|
kind: System |
Mount points within Catalog such as `entity.page.*` render as tabs and become visible only if at least one plugin contributes to them, or if they can render static content.
14.2.7.5. Customize the platform theme using front-end plugins
You can customize Developer Hub themes from a dynamic plugin with various configurations as shown in the following example:
import { lightTheme } from './lightTheme';
import { darkTheme } from './darkTheme';
import { UnifiedThemeProvider } from '@backstage/theme';
export const lightThemeProvider = ({ children }: { children: ReactNode }) => (
<UnifiedThemeProvider theme={lightTheme} children={children} />
);
export const darkThemeProvider = ({ children }: { children: ReactNode }) => (
<UnifiedThemeProvider theme={darkTheme} children={children} />
);For more information about creating a custom theme, see creating a custom theme.
You can declare the theme by using the themes configuration as shown in the following example:
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
themes:
# are `light` or `dark`. Using 'light' overrides the app-provided light theme
- id: light
title: Light
variant: light
icon: someIconReference
importName: lightThemeProvider
# The theme name displayed to the user on the *Settings* page. Using 'dark' overrides the app-provided dark theme
- id: dark
title: Dark
variant: dark
icon: someIconReference # A string reference to a system or app icon
# The name of the exported theme provider function, the function signature should match `({ children }: { children: ReactNode }): React.JSX.Element`
importName: darkThemeProvider14.2.8. Configure specialized front-end extensions for APIs and features
14.2.8.1. Configure specialized front-end extensions for APIs and features
Configure specialized front-end extensions including custom sign-in pages, Scaffolder field extensions, utility APIs, authentication provider settings, and TechDocs add-ons. These extensions enable advanced UI customization beyond standard route and mount point configuration.
14.2.8.2. Configure custom sign-in pages for authentication
In Red Hat Developer Hub (RHDH), the SignInPage component manages authentication flow. By default, Developer Hub uses a static SignInPage.
When you configure a custom SignInPage:
-
Only one
signInPageis specified and used by the application. -
The system loads the specified
importNamecomponent from your dynamic plugin. -
The component returns a configured
SignInPagethat connects the required authentication provider factories. -
The optional
modulefield specifies the set of assets that should be accessed within the dynamic plugin. By default, the system uses thePluginRootmodule.
dynamicPlugins:
frontend:
<package_name>: # The plugin package name
signInPage:
importName: CustomSignInPage
The package_name specified under dynamicPlugins.frontend must match the scalprum.name value in the package.json file of your plugin to ensure the dynamic plugin loads correctly at runtime.
14.2.8.3. Add custom Scaffolder field extensions
With the Scaffolder component in Red Hat Developer Hub (RHDH), you can create software components by using templates through a guided wizard. You can extend the functionality of the Scaffolder by adding custom form fields as dynamic plugins by using the scaffolderFieldExtensions configuration.
With custom field extensions, you can add specialized form fields that capture domain-specific data during the scaffolding process, such as environment selectors, input validations, or repository checks.
When you configure custom Scaffolder field extensions:
-
The dynamic plugin exposes the field extension component using
createScaffolderFieldExtension. - You can register multiple field extensions by listing each one in the configuration.
-
Each field extension requires a unique
importNamefor registration. The name should reference the value returned by the scaffolder field extension API.
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
scaffolderFieldExtensions:
- importName: MyNewFieldExtension # References the exported Scaffolder field extension component from your plugin
The module field is optional and specifies which set of assets to access within the plugin. By default, the system uses the PluginRoot module, consistent with the scalprum.exposedModules key in the package.json file of your package.
14.2.8.4. Configure additional utility APIs
If a dynamic plugin exports the plugin object returned by createPlugin, the createApp API receives it. All API factories exported by the plugin are automatically registered and available in the front-end application.
You can add an entry to the dynamicPlugins.frontend configuration when a dynamic plugin has only API factories as shown in the following example:
# app-config.yaml
dynamicPlugins:
frontend:
my-dynamic-plugin-package-with-api-factories: {}
However, when the dynamic plugin is not exporting the plugin object, you must explicitly configure each API factory. Use the apiFactories configuration to register them with the createApp API as shown in the following example:
# app-config.yaml
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
apiFactories:
# (Optional): Specify the import name that references a `AnyApiFactory<{}>` implementation. (Defaults to `default` export)
- importName: BarApi
# (Optional): An argument which specifies the assets you want to access within the plugin. If not provided, the default module named `PluginRoot` is used
module: CustomModule
An API factory from a dynamic plugin overrides the API factories that the Developer Hub application initializes when both specify the same API ref ID. A dynamic plugin can export AnyApiFactory<{}> to cater for some specific use case as shown in the following example:
export const customScmAuthApiFactory = createApiFactory({
api: scmAuthApiRef,
deps: { githubAuthApi: githubAuthApiRef },
factory: ({ githubAuthApi }) =>
ScmAuth.merge(
ScmAuth.forGithub(githubAuthApi, { host: "github.someinstance.com" }),
ScmAuth.forGithub(githubAuthApi, {
host: "github.someotherinstance.com",
}),
),
});
The corresponding configuration that overrides the default ScmAuth API factory that Developer Hub defaults to is as shown in the following example:
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
apiFactories:
- importName: customScmAuthApiFactory14.2.8.5. Add custom authentication provider settings to verify identities
You can install new authentication providers from a dynamic plugin that either adds additional configuration support for an existing provider or adds a new authentication provider. The user settings section lists these providers under the Authentication Providers tab.
You can use the providerSettings configuration to add entries for an authentication provider from a dynamic plugin, as shown in the following example:
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
providerSettings:
# The title for the authentication provider shown above the user's profile image if available
- title: My Custom Auth Provider
# The description of the authentication provider
description: Sign in using My Custom Auth Provider
# The ID of the authentication provider as provided to the `createApiRef` API call.
provider: core.auth.my-custom-auth-provider
provider looks up the corresponding API factory for the authentication provider to connect the provider’s Sign In/Sign Out button.
14.2.8.6. Configure custom TechDocs add-ons
If a plugin provides many add-ons, each techdocsAddon entry specifies a unique importName corresponding to the add-on. Front-end plugins expose the TechDocs add-on component by using the techdocsAddons configuration as shown in the following example:
dynamicPlugins:
frontend:
my-plugin: # The plugin package name
techdocsAddons:
- importName: ExampleAddon # The exported add-on component
config:
props: ... # (Optional): React props to pass to the add-on14.2.9. Filter plugins by support badges
14.2.9.1. Filter plugins by support badges
Filter available plugins by support level and maturity badges to identify production-ready components. Support badges classify plugins by support tier and development maturity to help you assess production readiness.
14.3. Develop custom dynamic plugins to support custom workflows
14.3.1. Develop custom dynamic plugins to support custom workflows
Develop, package, and deploy custom dynamic plugins when standard plugins do not meet organizational requirements. Custom plugin development enables teams to extend Red Hat Developer Hub with bespoke functionality and business logic.
14.3.2. Prepare your development environment to write custom plugins
14.3.2.1. Prepare your development environment to write custom plugins
Set up the required development toolchain including Node.js, NPM, Yarn, and the Red Hat Developer Hub Plugin Factory to begin developing custom dynamic plugins.
14.3.2.2. The development toolchain
Before creating or converting plugins for Red Hat Developer Hub (RHDH), set up a local development toolchain to write, convert, and package plugins for deployment.
Required skills and languages: To develop dynamic plugins, you must have experience with the following:
- JavaScript and TypeScript
- Used for Backstage frontend and backend development.
- React
- Used for building frontend plugin components.
- Node.js ecosystem
- Includes package management (NPM/Yarn) and module handling.
14.3.2.2.1. The development toolchain
The following tools are required to initialize, build, and package your plugins:
- Node.js (via NVM)
Node.js is the engine that runs JavaScript on your computer.
RHDH requires Node v22. Use Node Version Manager (NVM) to switch between Node versions and ensure compatibility with the RHDH backend system.
- Yarn 4
Yarn is a package manager that handles all the library dependencies that your application needs.
The Backstage project structure is optimized for Yarn (specifically Yarn Classic 1.x) to manage workspaces and dependencies efficiently.
- Containerization tools (Docker or Podman)
These tools used to run containers and package applications.
- Packaging: Dynamic plugins are distributed as OCI images. Use Docker or Podman to package your derived plugin assets into an image that can be pushed to a registry, for example, Quay.io and sideloaded into RHDH.
- RHDH plugin tools
These specialized tools convert standard plugins into the dynamic architecture required by RHDH.
- RHDH Plugin Factory and rhdh-cli: These tools assist converting existing standard Backstage plugins into the RHDH dynamic plugin format.
-
rhdh-cli (
@red-hat-developer-hub/cli): This command-line tool is critical for the export process. It allows you to run commands like export-dynamic-plugin, which repackages your code into a derived package containing the necessary configuration (like Scalprum for frontend) and dependency handling (bundling private dependencies versus sharing platform dependencies)
Additional resources
14.3.3. Develop and test new plugin components locally
14.3.3.1. Develop and test new plugin components locally
Create, implement, and test new plugin components in a local development environment before deploying to a cluster. Local development with a Backstage application enables rapid iteration and debugging of plugin functionality.
14.3.3.2. Determine RHDH version
To ensure your plugin uses dependencies compatible with the RHDH instance that it will run on, check the target RHDH version and identify the compatible Backstage version.
Table 14.1. RHDH compatibility matrix
| RHDH version | Backstage version | create-app version |
|---|---|---|
|
1.10 |
1.49.1 |
0.8.1 |
|
1.9 |
1.45.3 |
0.7.6 |
|
1.8 |
1.42.5 |
0.7.3 |
|
1.7 |
1.39.1 |
0.6.2 |
14.3.3.3. Create a new Backstage application
To ensure that you use the compatible version of the Backstage CLI to create your plugin, create a new Backstage application in your workspace by using the create-app command.
Prerequisites
-
Determine the
create-appversion based on the RHDH compatibility matrix.
Procedure
Create a directory for your workspace:
$ mkdir rhdh-plugin-dev $ cd rhdh-plugin-dev
Initialize the Backstage application:
$ npx @backstage/create-app@0.7.6 --path .
Verification
Your workspace should contain the following:
-
packages/app/folder -
packages/backend/folder -
plugins/folder -
package.jsonfile containing the Backstage dependencies.
14.3.3.4. Create a new plugin
Use the yarn new command to create a new Backstage plugin in your application root folder with the appropriate folder structure and configuration files.
Prerequisites
- You have created a Backstage application.
Procedure
In your Backstage application root folder, create a new plugin by using the
yarn newcommand, for example:$ cd rhdh-plugin-dev $ yarn new
Output from the
yarn newcommand:? What do you want to create? (Use arrow keys) ❯ frontend-plugin - A new frontend plugin backend-plugin - A new backend plugin backend-plugin-module - A new backend module that extends an existing backend plugin plugin-web-library - A new web library plugin package plugin-node-library - A new Node.js library plugin package plugin-common-library - A new isomorphic common plugin package web-library - A library package, exporting shared functionality for web environments
-
Select the type of plugin to create, for example,
frontend-plugin. Enter the ID of the plugin, for example:
? What do you want to create? frontend-plugin - A new frontend plugin ? Enter the ID of the plugin [required] simple-example
(Optional) To preview your plugin with RHDH styling, configure the RHDH theme package in the plugin:
$ cd plugins/simple-example $ yarn add --dev @red-hat-developer-hub/backstage-plugin-theme
Update
dev/index.tsxfile, as follows, to use RHDH themes:// Import the RHDH themes from the plugin import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme'; // ... // ... createDevApp() // ... // ... // Add RHDH themes to the development harness .addThemes(getAllThemes()) .render();NoteThis configuration is only for the local development harness (
dev/index.tsx). When deployed to RHDH, the application provides theming automatically.
Verification
The system generates a new Backstage plugin using your provided ID, then automatically builds and integrates it into the application. The plugins/simple-example/ directory must exist with src/, dev/ folders, and a package.json file.
You can also serve the plugin in isolation by running yarn start in the plugin directory, for example:
$ cd plugins/simple-example $ yarn start
14.3.3.5. Implement a plugin component
By default, the frontend plugin already has a sample page component defined in src/components/ExampleComponent/. This page is automatically registered in src/plugin.ts as SimpleExamplePage.
One of the common extensions is to create a new entity card component.
Procedure
-
In the
src/components/directory create anExampleCardsub-directory. Create an
ExampleCard.tsxfile, as follows:import React from 'react'; import { InfoCard } from '@backstage/core-components'; import { useEntity } from '@backstage/plugin-catalog-react'; export const ExampleCard = () => { const { entity } = useEntity(); return ( <InfoCard title="Simple Example Info"> <p>Entity: {entity.metadata.name}</p> </InfoCard> ); };In the
src/components/ExampleCarddirectory, create and edit theindex.tsfile, as follows:export { ExampleCard } from './ExampleCard';To register the new entity card component, edit the
src/plugin.tsfile to add the new component to the plugin, as follows:import { createComponentExtension } from '@backstage/core-plugin-api'; // ... // ... export const ExampleCard = simpleExamplePlugin.provide( createComponentExtension({ name: 'ExampleCard', component: { lazy: () => import('./components/ExampleCard').then(m => m.ExampleCard), }, }), );Export all components in
src/index.tsso they can be loaded dynamically:export { simpleExamplePlugin, SimpleExamplePage, ExampleCard } from './plugin';
Verification
Your plugin should have the following new files:
-
src/components/ExampleCard/ExampleCard.tsx -
src/components/ExampleCard/index.ts.
The src/plugin.ts should export ExampleCard, and src/index.ts should re-export it.
14.3.3.6. Test a plugin locally
You can test a plugin locally by using your Backstage application.
You can also use RHDH Local to test your plugins by copying the generated dist-dynamic/ folder contents to the RHDH Local local-plugins folder. For more details, see Verify plugins locally.
For example, to test your component card locally in your Backstage application by using the development harness, update the dev/index.tsx file to include the new component card.
This file is the entry point for the Local Development Sandbox, it serves as a testing harness.
When you are developing a plugin, you do not need to boot up an entire Backstage (or RHDH) production-grade instance just to see a UI change. Instead, you use the Dev App which is a lightweight, stripped-down version of the Backstage frontend.
Primary functions of the Dev App:
- Plugin isolation
- It allows you to run your plugin in a standalone wrapper. This is what loads when you run yarn start from within the plugin directory.
- Mocking the environment
-
Since the plugin usually expects to live inside a Backstage App,
dev/index.tsxprovides the necessary context: - Identity mocks
- Simulating a logged-in user.
- API mocks
- Registering test versions of APIs (similar to a mock CatalogApi) so the plugin doesn’t try to call a real backend that isn’t there.
- Route registration
- It defines how the plugin is mounted within this mini-dev-app, usually using createDevApp().
Procedure
Add Backstage dependencies:
$ yarn add @backstage/catalog-model @backstage/plugin-catalog-react
Edit your
dev/index.tsxfile, as follows:// ... // ... import { Entity } from '@backstage/catalog-model'; import { EntityProvider } from '@backstage/plugin-catalog-react'; import { Page, Header, Content } from '@backstage/core-components'; import { Grid } from '@material-ui/core'; import { ExampleCard } from '../src/plugin'; // Mock entity for the component card const mockEntity: Entity = { apiVersion: 'backstage.io/v1alpha1', kind: 'Component', metadata: { name: 'example-service', description: 'An example service component for plugin development.', annotations: { 'backstage.io/techdocs-ref': 'dir:.', }, }, spec: { type: 'service', lifecycle: 'production', owner: 'team-platform', }, }; // Create a page with the mock entity and the component card const entityPage = ( <EntityProvider entity={mockEntity}> <Page themeId="service"> <Header title={mockEntity.metadata.name} subtitle={`${mockEntity.kind} · ${mockEntity.spec?.type}`} /> <Content> <Grid container spacing={3} alignItems="stretch"> <Grid item md={6} xs={12}> <ExampleCard /> </Grid> </Grid> </Content> </Page> </EntityProvider> ); createDevApp() // ... // ... .addPage({ element: entityPage, title: 'Entity Page', path: '/simple-example/entity', }) // ... // ... .render();Run the development server:
$ yarn start
Verification
Navigate to http://localhost:3000/simple-example/entity in your browser. You should see the Entity Page with your ExampleCard component displaying "Entity: example-service".
14.3.3.7. Integrate custom user interface components
Front-end plugin wiring integrates dynamic front-end plugin components, such as new pages, UI extensions, icons, and APIs, into Red Hat Developer Hub.
Because the dynamic plugins load at runtime, the core application must discover and connect the exported assets of the plugin to the appropriate user interface systems and locations.
Procedure
Register and configure dynamic front-end plugins in the
dynamic-plugins.yamlfile.ImportantIf you are using RHDH Local for development and testing, use
dynamic-plugins.override.yamlinstead.This configuration determines how the plugin is integrated with the RHDH interface, such as adding routes, sidebar menu items, and mount points.
dynamic-plugins.yamlexampleplugins: # Option 1: Load from an OCI image - package: oci://quay.io/<namespace>/simple-example:v0.1.0 disabled: false pluginConfig: dynamicPlugins: frontend: # The package name must match package.json internal.backstage-plugin-simple-example: dynamicRoutes: - path: /simple-example # Must match the export in src/index.ts importName: SimpleExamplePage menuItem: icon: extension text: Simple Example mountPoints: - mountPoint: entity.page.overview/cards # Must match the export in src/index.ts importName: ExampleCard config: layout: gridColumnEnd: 'span 4' if: allOf: - isKind: component # Option 2: Load from local directory (for local RHDH testing) # - package: ./local-plugins/simple-example # disabled: false # pluginConfig: ... (same as above)
Verification
After restarting RHDH, confirm that Simple Example appears in the sidebar menu. Click Simple Example and verify that the plugin page displays correctly. Navigate to a Component entity page and verify that the ExampleCard appears in the Overview tab.
Additional resources
14.3.4. Convert standard plugins into dynamic plugins using the Plugin Factory
14.3.4.1. Convert standard plugins into dynamic plugins using the Plugin Factory
Convert standard Backstage plugins into dynamic plugins by using the Dynamic Plugin Factory. The factory model automates the export and packaging process to produce runtime-loadable plugin packages compatible with Red Hat Developer Hub.
14.3.4.2. The dynamic plugin factory model
You can automate the conversion and packaging of standard Backstage plugins into RHDH dynamic plugins by using the RHDH Dynamic Plugin Factory tool.
Red Hat maintains the Dynamic Plugin Factory as an open source project, but does not support it or subject it to any service level agreement (SLA).
Manually converting Backstage plugins to RHDH dynamic plugins requires configuring webpack, managing dependencies, and building container images. This process can be both time-consuming and error-prone. The Dynamic Plugin Factory automates this entire workflow, providing a reproducible way to convert plugins from source code to deployable containers without requiring deep knowledge of build tools.
This approach is particularly valuable when you are:
- Converting multiple community plugins from the Backstage marketplace.
- Testing custom plugin changes during active development.
- Ensuring consistent builds across development teams.
- Applying patches to plugin source code before building.
14.3.4.2.1. How the Dynamic Plugin Factory works
The core function of the Dynamic Plugin Factory tool is to streamline the dynamic plugin build process, offering the following capabilities:
- Source repository management
- Clones and checks out plugin source repositories.
- Multi-workspace support
- Exports plugins from multiple workspaces across different repositories in a single run.
- Patch and overlay system
- Applies custom modifications to plugin source code before exporting.
- Dependency management
- Automates yarn installation with TypeScript compilation, and automated private dependency handling for backend dynamic plugins.
- Dynamic plugin packaging
- Builds, exports and, packages plugins using the RHDH CLI.
- Container image publishing
- Optionally pushes to container registries such as Quay or OpenShift.
The Dynamic Plugin Factory tool provides a simplified, reproducible method for developers and platform engineers to create and test dynamic plugins. Using a pre-configured dynamic plugin factory container and documentation, the tool eases migration and testing.
Additional resources
14.3.4.3. Convert a custom plugin into a dynamic plugin
Use the RHDH CLI to convert a custom plugin into a dynamic plugin format and package it as a container image for deployment.
Procedure
Use the RHDH CLI to prepare the plugin you want to export. The following command uses the plugin files in the
distfolder that was generated by theyarn build:allcommand, and creates adist-dynamicfolder containing adist-scalprumsub-folder that contains the necessary configuration and source files to enable dynamic loading:cd plugins/simple-example npx @red-hat-developer-hub/cli@latest plugin export
When this command packages a frontend plugin, it uses a default Scalprum configuration if one is not found. The Scalprum configuration is used to specify the plugin entry point and exports, and then to build a
dist-scalprumfolder that contains the dynamic plugin. The default Scalprum configuration is suitable for most plugins.Package the plugin into a container image and publish it to Quay.io.
export QUAY_USER=_<username>_ export PLUGIN_NAME=simple-example export VERSION=$(cat package.json | jq .version -r) npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION
Push to Quay.io
podman push quay.io/$QUAY_USER/$PLUGIN_NAME:$VERSION
14.3.5. Package and deploy dynamic plugins as OCI images
14.3.5.1. Package and deploy dynamic plugins as OCI images
Package dynamic plugins as OCI images and deploy them to container registries for distribution. OCI packaging enables versioned, portable plugin artifacts that integrate with standard container workflows and air-gapped deployment strategies.
14.3.5.2. Deploy custom dynamic plugins
To add a custom dynamic plugin to Red Hat Developer Hub, update the dynamic-plugins.yaml file with the configuration generated by the RHDH CLI packaging command.
plugins: - package: oci://quay.io/<account-name>/<image-name>:_<tag>_ disabled: false pluginConfig: {}
If you are using RHDH Local for development and testing, use the dynamic-plugins.override.yaml file instead.
Procedure
Add the plugin configuration to the
dynamic-plugins.yamlfile.The following example integrates a plugin named
simple-examplewith RHDH and includes theplugin-configthat you must add to display a frontend plugin:plugins: # Option 1: Load from an OCI image - package: oci://quay.io/<namespace>/simple-example:v0.1.0 disabled: false pluginConfig: dynamicPlugins: frontend: # The package name must match package.json (usually internal.backstage-plugin-<id>) internal.backstage-plugin-simple-example: dynamicRoutes: - path: /simple-example # Must match the export in src/index.ts importName: SimpleExamplePage menuItem: icon: extension text: Simple Example mountPoints: - mountPoint: entity.page.overview/cards # Must match the export in src/index.ts importName: ExampleCard config: layout: gridColumnEnd: 'span 4' if: allOf: - isKind: component + # Option 2: Load from local directory (for local RHDH testing) # - package: ./local-plugins/simple-example # disabled: false # pluginConfig: ... (same as above)where
frontend:dynamic-routes- Enter the sidebar menu item and the plugin route.
frontend:mountPointsEnter the configuration to mount components exposed by the plugin.
NoteEnsure that your container images are publicly accessible, or that you have configured a pull secret in your environment. A pull secret provides Red Hat Developer Hub with credentials to authenticate pulling your plugin container images from a container registry. For more details, see Loading a plugin packaged as an OCI image.
14.3.5.3. Add a custom dynamic plugin to Red Hat Developer Hub
Use this procedure to add custom dynamic plugins to Red Hat Developer Hub by updating the dynamic-plugins.yaml configuration file.
Procedure
To add your custom dynamic plugins to Red Hat Developer Hub, update the
dynamic-plugins.yamlfile by using the following configuration that thenpx @red-hat-developer-hub/cli@latest plugin packagecommand generates:plugins: - package: oci://quay.io/_<user_name>_/entity-feedback-plugin:0.5.0 disabled: false - package: oci://quay.io/_<user_name>_/entity-feedback-plugin-backend:0.6.0 disabled: falseNoteEnsure that your container images are publicly accessible, or that you have configured a pull secret in your environment. A pull secret provides Red Hat Developer Hub with credentials to authenticate pulling your plugin container images from a container registry.
14.3.5.4. Load a plugin packaged as a JavaScript package
Use this procedure to load a dynamic plugin from a JavaScript package into Red Hat Developer Hub.
Prerequisites
You have packaged the custom plugin as a dynamic plugin in a JavaScript package.
For more information about packaging a custom plugin, see Section 14.3.5, “Package and deploy dynamic plugins as OCI images”.
Procedure
Run the following command to obtain the integrity hash from the NPM registry:
$ npm view --registry <registry_link> <npm_package>@<version> dist.integrity
Specify the package name, version, and its integrity hash in the
dynamic-plugins.yamlfile as follows:plugins: - disabled: false package: @example/backstage-plugin-myplugin@1.0.0 integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA==If you are using a custom NPM registry, create a
.npmrcfile with the registry URL and authentication details:registry=<registry_link> //<registry_link>:_authToken=<auth_token>
When using OpenShift Container Platform or Kubernetes:
Use the Helm chart to add the
.npmrcfile by creating a secret. For example:apiVersion: v1 kind: Secret metadata: name:
<release_name>-dynamic-plugins-npmrctype: Opaque stringData: .npmrc: | registry=<registry_link> //<registry_link>:_authToken=<auth_token>Replace
<release_name>with your Helm release name. This name is a unique identifier for each chart installation in the Kubernetes cluster.For RHDH Helm chart, name the secret using the following format for automatic mounting:
<release_name>-dynamic-plugins-npmrc
- To apply the changes, restart the RHDH application.
14.3.5.5. Load a plugin packaged as a TGZ file
Use this procedure to load a dynamic plugin from a TGZ file into Red Hat Developer Hub.
Prerequisites
You have packaged the custom plugin as a dynamic plugin in a TGZ file.
For more information about packaging a custom plugin, see Section 14.3.5, “Package and deploy dynamic plugins as OCI images”.
Procedure
Specify the archive URL and its integrity hash in the
dynamic-plugins.yamlfile using the following example:plugins: - disabled: false package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz integrity: sha512-9WlbgEdadJNeQxdn1973r5E4kNFvnT9GjLD627GWgrhCaxjCmxqdNW08cj+Bf47mwAtZMt1Ttyo+ZhDRDj9PoA==- To apply the changes, restart the RHDH application.
14.3.5.6. Create a JavaScript package with dynamic packages
Use this procedure to publish a dynamic plugin to a private NPM registry.
Do not publish the derived dynamic plugin JavaScript packages to the public NPM registry. If you must publish to the NPM registry, use a private registry.
Procedure
-
Navigate to the
dist-dynamicdirectory. Run the following command to publish the package to your private NPM registry:
$ npm publish --registry <npm_registry_url>
TipYou can add the following to your
package.jsonfile before running theexportcommand:{ "publishConfig": { "registry": "<npm_registry_url>" } }If you change
publishConfigafter exporting the dynamic plugin, re-run theplugin exportcommand to ensure that the correct configuration is in the package.
14.3.5.7. Create a TGZ file with dynamic packages
Use this procedure to package a dynamic plugin as a TGZ file and host it on a web server.
Prerequisites
package-and-deploy-dynamic-plugins-as-oci-images
Procedure
-
Navigate to the
dist-dynamicdirectory. Run the following command to create a
tgzarchive:$ npm pack
You can obtain the integrity hash from the output of the
npm packcommand by using the--jsonflag as follows:$ npm pack --json | head -n 10
Host the archive on a web server accessible to your RHDH instance, and reference its URL in the
dynamic-plugin-config.yamlfile as follows:plugins: - package: https://example.com/backstage-plugin-myplugin-1.0.0.tgz integrity: sha512-<hash>Run the following command to package the plugins:
$ npm pack --pack-destination ~/test/dynamic-plugins-root/
TipTo create a plugin registry using HTTP server on OpenShift Container Platform, run the following commands:
$ oc project my-rhdh-project $ oc new-build httpd --name=plugin-registry --binary $ oc start-build plugin-registry --from-dir=dynamic-plugins-root --wait $ oc new-app --image-stream=plugin-registry
Configure your RHDH to use plugins from the HTTP server by editing the
dynamic-plugin-config.yamlfile:plugins: - package: http://plugin-registry:8080/backstage-plugin-myplugin-1.9.6.tgz
14.3.5.8. Create an OCI image with dynamic packages
Use this procedure to package a dynamic plugin as an OCI image and push it to a container registry.
Prerequisites
-
You have installed
podmanordocker.
Procedure
-
Navigate to the plugin’s root directory (not the
dist-dynamicdirectory). Run the following command to package the plugin into an OCI image:
$ npx @red-hat-developer-hub/cli@latest plugin package --tag quay.io/example/image:v0.0.1
In the earlier command, the
--tagargument specifies the image name and tag.Ensure that your container runtime (
podmanordocker) is running and that you are logged in to the target image registry:$ podman login quay.io
Run one of the following commands to push the image to a registry:
$ podman push quay.io/example/image:v0.0.1
$ docker push quay.io/example/image:v0.0.1
The output of the
package-dynamic-pluginscommand provides the plugin’s path for use in thedynamic-plugin-config.yamlfile.
14.3.6. Verify plugins locally
RHDH Local enables you to test a dynamic plugin that you have built before publishing it to a registry.
During boot, the install-dynamic-plugins container reads the contents of the plugin configuration file and activates, configures, or downloads any plugins listed. RHDH Local supports two ways of specifying dynamic plugin configuration:
-
Default path:
configs/dynamic-plugins/dynamic-plugins.yaml -
User override path:
configs/dynamic-plugins/dynamic-plugins.override.yaml
The dynamic-plugins.override.yaml configuration takes precedence over the dynamic-plugins.yaml configuration. You should not modify the default dynamic-plugins.yaml file, use the dynamic-plugins.override.yaml to override the default file settings.
In addition, the local-plugins directory is mounted into the install-dynamic-plugins container at /opt/app-root/src/local-plugins. Any plugins placed there can be activated or configured the same way without downloading.
Prerequisites
You have exported a custom plugin by using the
npx @red-hat-developer-hub/cli@latest plugin exportcommand that has generated adist-dynamicdirectory containing the following:- dist-scalprum: A directory that contains the Webpack federated modules.
-
package.json: A modified version of your
package.jsonfile optimized for dynamic loading.
Procedure
Copy the
dist-dynamicdirectory directly into thelocal-pluginsfolder, for example:# Copy the dynamic distribution to {product-local-very-short} $ cp -r dist-dynamic/ <{product-very-short}_LOCAL_PATH>/local-plugins/example-pluginNoteThe
local-plugins/simple-example/directory in your RHDH Local installation should contain the plugin files fromdist-dynamicdirectory, including thedist-scalprumdirectory and thepackage.jsonfile- Ensure that permissions allow the container to read the files.
-
Configure your plugin in the
configs/dynamic-plugins/dynamic-plugins.override.yamlfile.
Additional resources
14.3.7. Export custom plugins in Red Hat Developer Hub
To use plugins in Red Hat Developer Hub, you can export plugins as derived dynamic plugin packages. These packages contain the plugin code and dependencies, ready for dynamic plugin integration into Developer Hub.
Prerequisites
You have installed the
@red-hat-developer-hub/clipackage. Use the latest version (@latesttag) for compatibility with the most recent features and fixes.NoteUse the
npx @red-hat-developer-hub/cli@latest plugin exportcommand to export an existing custom plugin as a derived dynamic plugin package.You must use this command when you have the source code for a custom plugin and want to integrate it into RHDH as a dynamic plugin.
The command processes the plugin’s source code and dependencies and generates the necessary output for dynamic loading by RHDH.
For an example of using this command, see Example of installing a custom plugin in Red Hat Developer Hub.
- You have installed and configured Node.js and NPM.
- The custom plugin is compatible with your Red Hat Developer Hub version. For more information, see Version compatibility matrix.
The custom plugin must have a valid
package.jsonfile in its root directory, containing all required metadata and dependencies.- Backend plugins
To ensure compatibility with the dynamic plugin support and enable their use as dynamic plugins, existing backend plugins must be compatible with the new Backstage backend system. Additionally, these plugins must be rebuilt using a dedicated CLI command.
You must export the new Backstage backend system entry point (created using
createBackendPlugin()orcreateBackendModule()) as the default export from either the main package or analphapackage. Export as analphapackage if the plugin instance support still usesalphaAPIs. This does not add any additional requirement on top of the standard plugin development guidelines of the plugin instance.The dynamic export mechanism identifies private dependencies and sets the
bundleDependenciesfield in thepackage.jsonfile. This export mechanism ensures that you publish the dynamic plugin package as a self-contained package, with its private dependencies bundled in a privatenode_modulesfolder.Certain plugin dependencies require specific handling in the derived packages, such as:
Shared dependencies: The RHDH application provides these dependencies and lists them as
peerDependenciesin thepackage.jsonfile. The dynamic plugin package does not bundle shared dependencies. For example, by default, all@backstagescoped packages use sharing.You can use the
--shared-packageflag to specify shared dependencies that Red Hat Developer Hub application provides and that the dynamic plugin package does not bundle.To treat a
@backstagepackage as private, use the negation prefix (!). For example, when a plugin depends on the package in@backstagethat is not provided by the Red Hat Developer Hub application.Embedded dependencies: The dynamic plugin package bundles these dependencies with their dependencies hoisted to the top level. By default, the package embeds packages with
-nodeor-commonsuffixes.You can use the
--embed-packageflag to specify additional embedded packages. For example, packages from the same workspace that do not follow the default naming convention.The following is an example of exporting a dynamic plugin with shared and embedded packages:
$ npx @red-hat-developer-hub/cli@latest plugin export --shared-package '!/@backstage/plugin-notifications/' --embed-package @backstage/plugin-notifications-backend
In the earlier example:
-
The export treats the
@backstage/plugin-notificationspackage as a private dependency and bundles it in the dynamic plugin package, despite being in the@backstagescope. -
The export marks the
@backstage/plugin-notifications-backendpackage as an embedded dependency and bundles it in the dynamic plugin package.
- Front-end plugins
Front-end plugins can use
scalprumfor configuration. The CLI can generate this configuration automatically during the export process. When running the following command, the CLI logs the generated default configuration:$ npx @red-hat-developer-hub/cli@latest plugin export
The following is an example of default
scalprumconfiguration:"scalprum": { "name": "<package_name>", // The Webpack container name matches the NPM package name, with "@" replaced by "." and "/" removed. "exposedModules": { "PluginRoot": "./src/index.ts" // The default module name is "PluginRoot" and doesn't need explicit specification in the app-config.yaml file. } }You can add a
scalprumsection to thepackage.jsonfile. For example:"scalprum": { "name": "custom-package-name", "exposedModules": { "BazModuleName": "./src/baz.ts", "QuxModuleName": "./src/qux.ts" // Define multiple modules here, with each exposed as a separate entry point in the Webpack container. } }Dynamic plugins might need adjustments for Developer Hub needs, such as static JSX for mountpoints or dynamic routes. These changes are optional but might be incompatible with static plugins.
To include static JSX, define an additional export and use it as the dynamic plugin’s
importName. For example:// For a static plugin $ export const EntityTechdocsContent = () => {...} // For a dynamic plugin $ export const DynamicEntityTechdocsContent = { element: EntityTechdocsContent, staticJSXContent: ( <TechDocsAddons> <ReportIssue /> </TechDocsAddons> ), };
Procedure
Use the
plugin exportcommand from the@red-hat-developer-hub/clipackage to export the plugin:$ npx @red-hat-developer-hub/cli@latest plugin export
Ensure that you run the earlier command in the root directory of the plugin’s JavaScript package (containing
package.jsonfile).The
dist-dynamicsubdirectory has the resulting derived package. The exported package name consists of the original plugin name with-dynamicappended.WarningDo not publish the derived dynamic plugin JavaScript packages to the public NPM registry. For more appropriate packaging options, see Section 14.3.5, “Package and deploy dynamic plugins as OCI images”. If you must publish to the NPM registry, use a private registry.
14.3.8. Override Core Backend Service Configuration
Customize core backend services by installing them as BackendFeatures using dynamic plugin functionality.
The Red Hat Developer Hub (RHDH) backend platform consists of several core services that are well encapsulated. The RHDH backend installs these default core services statically during initialization.
Customize a core service by installing it as a BackendFeature by using the dynamic plugin functionality.
Procedure
Configure Developer Hub to allow a core service override, by setting the corresponding core service ID environment variable to
truein the Developer Hubapp-config.yamlconfiguration file.The following table describes the environment variables and their corresponding core service IDs:
Variable Overrides the related service ENABLE_CORE_AUTH_OVERRIDEcore.authENABLE_CORE_CACHE_OVERRIDEcore.cacheENABLE_CORE_ROOTCONFIG_OVERRIDEcore.rootConfigENABLE_CORE_DATABASE_OVERRIDEcore.databaseENABLE_CORE_DISCOVERY_OVERRIDEcore.discoveryENABLE_CORE_HTTPAUTH_OVERRIDEcore.httpAuthENABLE_CORE_HTTPROUTER_OVERRIDEcore.httpRouterENABLE_CORE_LIFECYCLE_OVERRIDEcore.lifecycleENABLE_CORE_LOGGER_OVERRIDEcore.loggerENABLE_CORE_PERMISSIONS_OVERRIDEcore.permissionsENABLE_CORE_ROOTHEALTH_OVERRIDEcore.rootHealthENABLE_CORE_ROOTHTTPROUTER_OVERRIDEcore.rootHttpRouterENABLE_CORE_ROOTLIFECYCLE_OVERRIDEcore.rootLifecycleENABLE_CORE_SCHEDULER_OVERRIDEcore.schedulerENABLE_CORE_USERINFO_OVERRIDEcore.userInfoENABLE_CORE_URLREADER_OVERRIDEcore.urlReaderENABLE_EVENTS_SERVICE_OVERRIDEevents.serviceInstall your custom core service as a
BackendFeatureas shown in the following example:// Create the BackendFeature $ export const customRootHttpServerFactory: BackendFeature = rootHttpRouterServiceFactory({ configure: ({ app, routes, middleware, logger }) => { logger.info( 'Using custom root HttpRouterServiceFactory configure function', ); app.use(middleware.helmet()); app.use(middleware.cors()); app.use(middleware.compression()); app.use(middleware.logging()); // Add a the custom middleware function before all // of the route handlers app.use(addTestHeaderMiddleware({ logger })); app.use(routes); app.use(middleware.notFound()); app.use(middleware.error()); }, }); // Export the BackendFeature as the default entrypoint $ export default customRootHttpServerFactory;In the previous example, as the
BackendFeatureoverrides the default implementation of the HTTP router service, you must set theENABLE_CORE_ROOTHTTPROUTER_OVERRIDEenvironment variable totrueso that the Developer Hub does not install the default implementation automatically.
14.4. Manage containerized plugins securely by migrating to OCI artifacts
14.4.1. Manage containerized plugins securely by migrating to OCI artifacts
Migrate community and custom plugins to OCI artifact registries for improved security, versioning, and distribution. OCI-based plugin management replaces direct NPM registry access with container-native workflows that align with enterprise supply chain requirements.
14.4.2. Migrate community plugins to the GitHub Container Registry
14.4.2.1. Migrate community plugins to the GitHub Container Registry
Migrate community plugins from NPM registries to the GitHub Container Registry (GHCR) for OCI-based distribution. Container registry hosting enables consistent versioning and access control aligned with your existing container image workflows.
14.4.2.2. Update deployment configurations for OCI registry container images
Use this procedure to load a dynamic plugin from an OCI image into Red Hat Developer Hub.
Prerequisites
You packaged the custom plugin as a dynamic plugin in an OCI image.
For more information about packaging a custom plugin, see Section 14.3.5, “Package and deploy dynamic plugins as OCI images”.
Procedure
To retrieve plugins from an authenticated registry, such as a private repository, complete the following steps:
NoteIf your OCI image is stored in a public registry, you can skip this step.
Log in to the container image registry.
podman login <registry>
Verify the content of the
auth.jsonfile created after the login.cat ${XDG_RUNTIME_DIR:-~/.config}/containers/auth.jsonCreate a secret file using the following example:
oc create secret generic _<secret_name>_ --from-file=auth.json=${XDG_RUNTIME_DIR:-~/.config}/containers/auth.json 1-
For an Operator-based deployment, replace <secret_name> with
dynamic-plugins-registry-auth. -
For a Helm-based deployment, replace <secret_name> with
<Helm_release_name>-dynamic-plugins-registry-auth.
-
For an Operator-based deployment, replace <secret_name> with
Define the plugin with the
oci://prefix by using one of the following formats in yourdynamic-plugins.yamlfile:- Standard definition
Use the format
oci://<image_name>:<tag>, as shown in the following example. The installation program automatically extracts the plugin path from the image metadata.Example configuration in
dynamic-plugins.yamlfile:plugins: - disabled: false package: oci://quay.io/example/image:v1.0.0NoteYou must package images with the
@red-hat-developer-hub/clito ensure the system applies theio.backstage.dynamic-packagesannotation.You must define exactly one plugin from that OCI image in the configuration files. The system returns an error if the configuration files contain many plugins or no matching plugins.
- Using image digests
To perform an integrity check, use the image digest in place of the tag in the
dynamic-plugins.yamlfile as shown in the following example:Example configuration in
dynamic-plugins.yamlfile:plugins: - disabled: false package: oci://quay.io/example/image@sha256:28036abec4dffc714394e4ee433f16a59493db8017795049c831be41c02eb5dc- Using version inheritance
To inherit a version from a base configuration file, for example,
dynamic-plugins.default.yaml, use the{{inherit}}placeholder to inherit thev0.0.2tag, as shown in the following example:Example configuration in
dynamic-plugins.default.yamlfile:plugins: - disabled: false package: oci://quay.io/example/image:v0.0.2Example configuration in
dynamic-plugins.yamlfile:includes: - dynamic-plugins.default.yaml plugins: - disabled: false package: oci://quay.io/example/image:{{inherit}}NoteAn error occurs if you use
{{inherit}}in the includes file itself or if no matching plugin key exists in the base configuration.ImportantWhen you use the
{{inherit}}tag, z-stream updates automatically update the plugin to the latest version from the base configuration. If a plugin update causes issues, you can pin the plugin to a specific version. For more information, see Roll back a dynamic plugin to a previous version.
- To apply the changes, restart the RHDH application.
14.5. Enable and configure the Orchestrator extension
14.5.1. Enable and configure the Orchestrator extension
Enable the Orchestrator extension to automate infrastructure tasks by using serverless workflows in Red Hat Developer Hub. The Orchestrator integrates the OpenShift Serverless Logic Operator, SonataFlow runtime, and Data Index to deliver workflow orchestration within the developer portal.
14.5.2. Understand Orchestrator architecture
The Orchestrator architecture is composed of several components, each contributing to the running and management of workflows.
- Red Hat Developer Hub (RHDH)
Serves as the primary interface. It contains the following subcomponents:
- Orchestrator frontend plugins
- Provide the interface for users to run and monitor workflows within RHDH.
- Orchestrator backend plugins
- Get workflow data into Developer Hub.
- Notifications plugins
- Inform users about workflow events.
- OpenShift Serverless Logic Operator
Serves as the workflow engine, and its subcomponents handle running, executing and providing persistence for the workflows. The Red Hat Developer Hub Operator and the Red Hat Developer Hub Helm chart manage the following lifecycle of these subcomponents:
- SonataFlow Runtime/Workflow Application
- Functions as a deployed workflow. Operates as an HTTP server, handling requests for running workflow instances. It is managed as a Kubernetes (K8s) deployment by the Openshift Serverless Logic Operator.
- Data Index Service
- Serves as a repository for workflow definitions, instances, and associated jobs. It exposes a GraphQL API used by the Orchestrator backend plugin to retrieve workflow definitions and instances.
- Job Service
- Orchestrates scheduled tasks for workflows.
- OpenShift Serverless
- Provides serverless capabilities essential for workflow communication. It employs Knative eventing to interface with the Data Index service and uses Knative functions to introduce more complex logic to workflows.
- PostgreSQL Server
- Provides a database solution essential for data persistence within the Orchestrator ecosystem. The system uses PostgreSQL Server for storing both SonataFlow information and Developer Hub data.
- OpenShift AMQ Streams (Strimzi/Kafka)
Provides enhanced reliability of the eventing system. Eventing can work without Kafka by using direct HTTP calls, however, this approach is not reliable.
Optional: The current deployment iteration does not natively integrate or include the AMQ Streams Operator. However, you can add the Operator post-install for enhanced reliability if you require it.
14.5.3. Getting started with Orchestrator
To start using Orchestrator in RHDH, you must install the required infrastructure components and configure your Backstage custom resource or Helm values file.
- Install the required infrastructure components, such as OpenShift Serverless Operator, and OpenShift Serverless Logic Operator
- Configure your Backstage custom resource (CR) or Helm values file for Orchestrator
When using the RHDH Operator, you must first install the required infrastructure components. The Operator then provisions the dependent SonataFlow resources once the Orchestrator plugins are enabled in the Backstage CR.
When using the RHDH Helm chart, the required infrastructure components are installed automatically using the dedicated redhat-developer-hub-orchestrator-infra Helm chart before enabling the Orchestrator plugins in the main RHDH chart.
14.5.4. Orchestrator plugin dependencies for Operator installation
When you enable the Orchestrator plugin in your Backstage custom resource (CR), the Operator automatically provisions required dependencies.
-
A
SonataflowPlatformCR -
NetworkPoliciesthat allow traffic between infrastructure resources (Knative, Serverless Logic Operator), monitoring traffic, and intra-namespace traffic
The Orchestrator plugin requires these components to run. For example, to communicate with the SonataFlow platform, the Orchestrator plugin uses the sonataflow-platform-data-index-service, which is created by the SonataFlowPlatform CR.
The SonataFlowPlatform CR contains Data Index service that requires PostgreSQL database as shown in the following example:
persistence:
postgresql:
secretRef:
name: backstage-psql-secret-{{backstage-name}}
userKey: POSTGRES_USER
passwordKey: POSTGRES_PASSWORD
serviceRef:
name: backstage-psql-{{backstage-name}} # # Namespace where the Backstage CR is created
namespace: {{backstage-ns}} # Namespace where the Backstage (CR) is created
databaseName: backstage_plugin_orchestratorBy default, the Orchestrator plugin dependencies use the following:
-
The PostgreSQL database named
backstage_plugin_orchestratorcreated by Backstage -
A Secret created by Backstage Operator for the PostgreSQL with
POSTGRES_USERandPOSTGRES_PASSWORDkeys as the database credentials in the Backstage CR namespace. -
A Service created by Backstage Operator for the PostgreSQL database with the name
backstage-psql-{{backstage-name}}in the Backstage CR namespace.
To enable the Backstage Operator to work with the SonataFlow platform, its ServiceAccount must have the appropriate permissions.
The Operator automatically creates the required Role and RoleBinding resource in profile/rhdh/plugin-rbac directory.
Additional resources
14.5.5. Configure Orchestrator plugins
To use the Orchestrator, enable the Orchestrator plugins for Red Hat Developer Hub that are disabled by default.
- Orchestrator-frontend plugin
backstage-plugin-orchestrator- Provides the interface for users to run and monitor workflows within RHDH. You can run and track the execution status of processes.
- Orchestrator-backend plugin
backstage-plugin-orchestrator-backend- Gets workflow data into Developer Hub making sure RHDH processes critical workflow metadata and runtime status fulfilling your need for visibility.
- Orchestrator-form-widget
backstage-plugin-orchestrator-form-widgets- Provides custom widgets for the workflow execution form, allowing you to customize input fields and streamline the process of launching workflows.
- Orchestrator-scaffolder-backend-module
scaffolder-backend-module-orchestrator-
Provides callable actions from Scaffolder templates, such as
orchestrator:workflow:runororchestrator:workflow:get_params.
Prerequisites
You have installed the following operators:
- OpenShift Serverless
- OpenShift Serverless Logic (OSL)
- (Optional) For managing the Orchestrator project, you have an instance of Argo CD or Red Hat OpenShift GitOps in the cluster. It is disabled by default.
- (Optional) To use Tekton tasks and the build pipeline, you have an instance of Tekton or Red Hat OpenShift Pipelines in the cluster. These features are disabled by default.
Procedure
Locate your Developer Hub configuration and enable the Orchestrator plugins and the supporting notification plugins.
The
{{inherit}}attribute in the package field automatically resolves to the default plugin version and configuration for your version of RHDH.plugins: - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:{{inherit}}" disabled: false - package: "./dynamic-plugins/dist/backstage-plugin-notifications" disabled: false - package: "./dynamic-plugins/dist/backstage-plugin-signals" disabled: false - package: "./dynamic-plugins/dist/backstage-plugin-notifications-backend-dynamic" disabled: false - package: "./dynamic-plugins/dist/backstage-plugin-signals-backend-dynamic" disabled: falseNoteIf you need a specific plugin version, replace
{{inherit}}with the version tag, for example:oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:1.3.0.Optional: Restrict where the Workflows tab appears.
By default, the Workflows tab appears on all entity types. To display it only on specific entities, add the
pluginConfigsection with filtering conditions.plugins: - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}" disabled: false pluginConfig: dynamicPlugins: frontend: red-hat-developer-hub.backstage-plugin-orchestrator: appIcons: - importName: OrchestratorIcon name: orchestratorIcon dynamicRoutes: - importName: OrchestratorPage menuItem: icon: orchestratorIcon text: Orchestrator textKey: menuItem.orchestrator path: /orchestrator entityTabs: - path: /workflows title: Workflows titleKey: catalog.entityPage.workflows.title mountPoint: entity.page.workflows mountPoints: - mountPoint: entity.page.workflows/cards importName: OrchestratorCatalogTab config: layout: gridColumn: 1 / -1 if: anyOf: - IsOrchestratorCatalogTabAvailableWhere:
IsOrchestratorCatalogTabAvailable- A condition function exported by the Orchestrator plugin that checks whether the entity has workflow-related data or annotations.
layout.gridColumn-
Controls the grid layout positioning. The value
1 / -1spans the full width of the grid. if.anyOfSpecifies that the tab appears if any of the listed conditions are met. Add conditions like
isKind: componentto further restrict where the tab appears.ImportantMake sure the indentation is correct:
ifmust be at the same level aslayoutunderconfig, and conditions underanyOfmust be indented two more levels. Incorrect indentation can cause the Workflows tab to appear on all entity types, including User and Group entities.To restrict the Workflows tab to only
Componententities, modify theifcondition:if: allOf: - IsOrchestratorCatalogTabAvailable - isKind: component
14.5.6. Enable the Orchestrator plugins using the Operator
You can enable the Orchestrator plugins in RHDH by configuring dynamic plugins in your Backstage custom resource (CR).
Prerequisites
- You have installed RHDH on OpenShift Container Platform.
- You have access to edit or create ConfigMaps in the namespace where the Backstage CR is deployed.
Procedure
To enable the Orchestrator plugins with default settings, set
disabled: falsefor the corresponding packages.The
{{inherit}}attribute in the package field automatically resolves to the default plugin version and configuration for your version of RHDH.- package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend:{{inherit}}" disabled: false dependencies: - ref: sonataflow - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:{{inherit}}" disabled: falseNoteIf you need a specific plugin version, replace
{{inherit}}with the version tag, such as1.3.0. When you use the Operator, theref: sonataflowfield installs the OpenShift Serverless and OpenShift Serverless Logic resources.The following example shows a complete configuration of the Orchestrator plugin
dynamic-pluginsconfig map:apiVersion: v1 kind: ConfigMap metadata: name: orchestrator-plugin data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend:{{inherit}}" disabled: false dependencies: - ref: sonataflow - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:{{inherit}}" disabled: false(Optional) Configure backend authentication to allow Orchestrator components to communicate with the RHDH API.
This step is required only when your workflow definitions include API calls to RHDH plugins, such as the notifications or scaffolding plugins.
apiVersion: v1 kind: ConfigMap metadata: name: app-config-rhdh data: app-config.yaml: |- backend: auth: externalAccess: - type: static options: token: ${BACKEND_SECRET} subject: orchestrator --- apiVersion: v1 kind: Secret metadata: name: backend-auth-secret stringData: # Run the following command to generate a secure random value: # node -p 'require("crypto").randomBytes(24).toString("base64")' BACKEND_SECRET: "<GENERATED_VALUE>"ImportantReplace
<GENERATED_VALUE>with a securely generated random token. Do not use example or placeholder values in production environments.If you have configured backend authentication in the previous step, update your Backstage CR to reference the secret:
apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: orchestrator spec: application: appConfig: configMaps: - name: app-config-rhdh dynamicPluginsConfigMapName: orchestrator-plugin extraEnvs: secrets: - name: backend-auth-secret
Verification
- In the RHDH console, confirm that the Orchestrator frontend and backend features are available.
14.5.7. Install components using the RHDH helper script
You can use the RHDH helper script plugin-infra.sh to quickly install the OpenShift Serverless infrastructure and OpenShift Serverless Logic infrastructure required by the Orchestrator plugin.
Do not use plugin-infra.sh in production.
Procedure
Download the
plugin-infra.shscript as shown in the following example:$ curl -sSLO https://raw.githubusercontent.com/redhat-developer/rhdh-operator/refs/heads/release-1.10/config/profile/rhdh/plugin-infra/plugin-infra.sh # Specify the Red Hat Developer Hub version in the URL or use main
Run the script:
$ ./plugin-infra.sh
14.5.8. Install Orchestrator components manually on OpenShift Container Platform
Use manual installation when you want full control of the setup process and component versions. Manual installation method focuses on setting up the underlying infrastructure.
Procedure
- Install the OpenShift Serverless components manually by following the instructions in the Red Hat OpenShift Serverless documentation.
(Optional) If required, deploy a custom PostgreSQL database.
ImportantPrevent workflow context from being lost when the Pod restarts by configuring workflow persistence. You can configure persistence at the namespace level by using the
SonataFlowPlatformorSonataFlowcustom resources (CR). For more information, check the Managing workflow persistence documentation.
14.5.9. Install Orchestrator software templates
To enable software templates on RHDH, you must install two additional Helm charts.
Prerequisites
- You have installed RHDH and the Orchestrator plugin by using the Helm chart.
-
You have installed the
redhat-developer-hub-orchestrator-infrachart.
Procedure
-
Install the
orchestrator-software-templates-infrachart. -
Install the
orchestrator-software-templateschart.
14.5.10. Configure Orchestrator to connect to existing PostgreSQL infrastructure
Connect the Orchestrator plugins to your existing PostgreSQL database to leverage centralized database management and meet compliance requirements.
By default, when you enable the Orchestrator plugin by using the Operator, the dependencies: - ref: sonataflow field automatically provisions a SonataFlowPlatform custom resource (CR) and creates the required PostgreSQL database resources. The Operator uses specific naming patterns for these resources (such as backstage-psql-{{backstage-name}} for the service and backstage-psql-secret-{{backstage-name}} for the secret).
However, when you use an external PostgreSQL database that the Operator does not manage, these default resources and naming patterns do not exist. You must explicitly configure the SonataFlowPlatform CR to reference your external database resources and remove the automatic dependency provisioning.
Prerequisites
- You have installed RHDH by using the Operator.
- You have configured Developer Hub to use an external PostgreSQL database.
- You have access to create jobs, secrets, config maps, and custom resources in the namespace where you deploy the Backstage CR.
Procedure
Create the
backstage_plugin_orchestratordatabase on your external PostgreSQL server by applying the following job:apiVersion: batch/v1 kind: Job metadata: name: create-sonataflow-database-developer-hub spec: ttlSecondsAfterFinished: 30 activeDeadlineSeconds: 120 template: spec: containers: - name: psql image: quay.io/fedora/postgresql-15:latest resources: limits: cpu: "100m" memory: "128Mi" requests: cpu: "100m" memory: "64Mi" securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false runAsNonRoot: true capabilities: drop: - ALL envFrom: - secretRef: name: <SECRET-NAME-WITH-DB-CREDENTIALS> command: [ "sh", "-c" ] args: - | set -e # Check if the backstage_plugin_orchestrator database exists DB_EXISTS=$(PGPASSWORD=${POSTGRES_PASSWORD} psql -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} -tAc "SELECT 1 FROM pg_database WHERE datname='backstage_plugin_orchestrator'" postgres) if [ -z "$DB_EXISTS" ]; then # Create the database if it does not exist PGPASSWORD=${POSTGRES_PASSWORD} psql -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} -c "CREATE DATABASE backstage_plugin_orchestrator;" postgres fi restartPolicy: NeverCreate a
SonataFlowPlatformCR that references your external PostgreSQL service:apiVersion: sonataflow.org/v1alpha08 kind: SonataFlowPlatform metadata: name: sonataflow-platform spec: monitoring: enabled: true services: dataIndex: enabled: true persistence: postgresql: secretRef: name: <SECRET-NAME-WITH-DB-CREDENTIALS> userKey: POSTGRES_USER passwordKey: POSTGRES_PASSWORD serviceRef: name: <SERVICE-NAME-TO-DB> namespace: <RHDH-NAMESPACE> databaseName: backstage_plugin_orchestrator jobService: enabled: true persistence: postgresql: secretRef: name: <SECRET-NAME-WITH-DB-CREDENTIALS> userKey: POSTGRES_USER passwordKey: POSTGRES_PASSWORD serviceRef: name: <SERVICE-NAME-TO-DB> namespace: <RHDH-NAMESPACE> databaseName: backstage_plugin_orchestratorImportantUnlike the default configuration that uses the
dependencies: - ref: sonataflowfield to automatically provision database resources with specific naming patterns, this configuration explicitly references your external database Service and Secret. TheSonataFlowPlatformCR will use these resources to connect to your external database instead of creating new database resources.Configure the Orchestrator plugins in your dynamic plugins config map to remove the default
sonataflowdependency and explicitly reference the SonataFlowPlatform services:apiVersion: v1 kind: ConfigMap metadata: name: orchestrator-plugin data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: # Orchestrator plugins - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator:{{inherit}}" disabled: false - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-backend:{{inherit}}" disabled: false pluginConfig: orchestrator: dataIndexService: url: http://<SERVICE-NAME-SONATAFLOW-PLATFORM-DATA-INDEX> dependencies: [{}] # Empty array removes default 'ref: sonataflow' to prevent automatic database provisioning - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:{{inherit}}" disabled: false pluginConfig: orchestrator: dataIndexService: url: http://<SERVICE-NAME-SONATAFLOW-PLATFORM-DATA-INDEX> dependencies: [{}] # Empty array removes default 'ref: sonataflow' to prevent automatic database provisioning - package: "oci://registry.access.redhat.com/rhdh/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:{{inherit}}" disabled: falseUpdate your Backstage CR to reference the orchestrator plugin config map and inject the database credentials secret:
apiVersion: rhdh.redhat.com/v1alpha5 kind: Backstage metadata: name: orchestrator spec: application: appConfig: configMaps: - name: app-config-rhdh dynamicPluginsConfigMapName: orchestrator-plugin extraEnvs: secrets: - name: <SECRET-NAME-WITH-DB-CREDENTIALS>
Verification
Verify that the
SonataFlowPlatformCR is running:$ oc get sonataflowplatform sonataflow-platform -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' True- In the RHDH console, confirm that the Orchestrator frontend and backend features are available and can connect to your external database.
14.5.11. Configure Orchestrator to connect to existing PostgreSQL infrastructure using Helm
Connect the Orchestrator plugins to your existing PostgreSQL database when deploying with the Helm chart to leverage centralized database management and meet compliance requirements.
By default, when you enable the Orchestrator plugin by using the Helm chart with orchestrator.enabled=true, the chart automatically provisions a SonataFlowPlatform custom resource (CR) and creates the required PostgreSQL database resources. The chart uses the orchestrator.sonataflowPlatform values to configure these resources.
However, when you use an external PostgreSQL database that the Helm chart does not manage, you must explicitly configure the orchestrator.sonataflowPlatform values to reference your external database resources.
Prerequisites
- You have installed RHDH by using the Helm chart.
- You have configured Developer Hub to use an external PostgreSQL database.
- You have access to create jobs, secrets, services, and custom resources in the namespace where you deploy RHDH.
Procedure
Create the
backstage_plugin_orchestratordatabase on your external PostgreSQL server by applying the following job:apiVersion: batch/v1 kind: Job metadata: name: create-sonataflow-database-developer-hub spec: ttlSecondsAfterFinished: 30 activeDeadlineSeconds: 120 template: spec: containers: - name: psql image: quay.io/fedora/postgresql-15:latest resources: limits: cpu: "100m" memory: "128Mi" requests: cpu: "100m" memory: "64Mi" securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false runAsNonRoot: true capabilities: drop: - ALL envFrom: - secretRef: name: <SECRET-NAME-WITH-DB-CREDENTIALS> command: [ "sh", "-c" ] args: - | set -e # Check if the backstage_plugin_orchestrator database exists DB_EXISTS=$(PGPASSWORD=${POSTGRES_PASSWORD} psql -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} -tAc "SELECT 1 FROM pg_database WHERE datname='backstage_plugin_orchestrator'" postgres) if [ -z "$DB_EXISTS" ]; then # Create the database if it does not exist PGPASSWORD=${POSTGRES_PASSWORD} psql -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -U ${POSTGRES_USER} -c "CREATE DATABASE backstage_plugin_orchestrator;" postgres fi restartPolicy: NeverConfigure your external PostgreSQL database for Orchestrator in your Helm configuration file
values.yaml:orchestrator: enabled: true sonataflowPlatform: externalDBsecretRef: <SECRET-NAME-WITH-DB-CREDENTIALS> externalDBName: backstage_plugin_orchestrator externalDBHost: <SERVICE-NAME-TO-DB> externalDBPort: "5432"Where:
orchestrator.enabled-
Set to
trueto enable the Orchestrator plugin. orchestrator.sonataflowPlatform.externalDBsecretRef-
The secret name containing database credentials with
POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_HOST, andPOSTGRES_PORTkeys. orchestrator.sonataflowPlatform.externalDBName-
The database name for Orchestrator data (must be
backstage_plugin_orchestrator). orchestrator.sonataflowPlatform.externalDBHost- The Kubernetes Service name pointing to your external database.
orchestrator.sonataflowPlatform.externalDBPortThe PostgreSQL port (typically
5432).ImportantUnlike the default configuration where the Helm chart automatically provisions database resources, this configuration explicitly references your external database Service and Secret. The
SonataFlowPlatformCR will use these resources to connect to your external database instead of creating new database resources.
Apply the configuration changes in your Helm configuration file
values.yaml:$ helm upgrade -n <your_namespace> <your_deploy_name> openshift-helm-charts/redhat-developer-hub -f values.yaml --version 1.10.1
Verification
Verify that the
SonataFlowPlatformCR is running:$ oc get sonataflowplatform sonataflow-platform -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}' True- In the RHDH console, confirm that the Orchestrator frontend and backend features are available and can connect to your external database.
14.5.12. Compatibility guide for Orchestrator
To verify that your serverless workflows run reliably, use the validated Orchestrator plugin and infrastructure versions listed in the following table.
Red Hat does not support or guarantee Orchestrator plugin functionality with unvalidated infrastructure versions. Use only the specific versions of OpenShift Serverless Logic (OSL) and other components listed in the following table.
The following table lists compatible Orchestrator and infrastructure versions:
|
Orchestrator plugin version |
Red Hat Developer Hub (RHDH) version |
OpenShift version |
OpenShift Serverless Logic (OSL) version |
OpenShift Serverless version |
|
Orchestrator |
|
|
OSL |
|
|
Orchestrator |
|
|
OSL |
|
|
Orchestrator |
|
|
OSL |
|
|
Orchestrator 1.8.2 |
1.8 |
|
OSL |
|
|
Orchestrator 1.10.0 |
1.10 |
|
OSL 1.38.0 |
1.37.1 |
The Orchestrator plugin supports the same OpenShift Container Platform versions as RHDH. See the Life Cycle page.
14.5.13. Workflow review pages for your approval requirements
You can replace the default Orchestrator review page with a custom component to meet organizational standards, show warnings, require acknowledgment before run, or integrate with design systems in Red Hat Developer Hub.
Custom review pages are optional. If you do not implement a custom review component, the Orchestrator continues to use the default review page without any impact on functionality.
Use a custom review page when you need to perform the following actions:
- Display workflow data in a specific layout that matches your organization’s documentation or approval standards.
- Apply client-side checks or show warnings before the workflow runs.
- Include additional context, such as help text or links to documentation, for reviewers.
- Integrate with custom UI component libraries or design systems.
Custom review pages are compatible with existing workflows. The same workflow definitions, schemas, and data structures work with both default and custom review pages. You can switch between review page types without modifying your workflow configurations.
14.5.14. Build custom review pages for workflows
To build a custom review page that displays workflow data in a specific layout, or integrates with a design system, you must implement the getReviewComponent() method in the form API.
Prerequisites
- You have configured the Orchestrator plugins in your Developer Hub instance.
-
You have a plugin or module that implements the
OrchestratorFormApiinterface from theorchestrator-form-apipackage. - You are familiar with React component development and TypeScript.
Procedure
In your plugin that implements
OrchestratorFormApi, import the required types:import type { OrchestratorFormApi, ReviewComponentProps, } from '@red-hat-developer-hub/backstage-plugin-orchestrator-form-api';Import the helper utilities from the
orchestrator-form-reactpackage:import { generateReviewTableData, schemaHasUiHiddenFields, ReviewHiddenParametersAlert, NestedReviewTable, } from '@red-hat-developer-hub/backstage-plugin-orchestrator-form-react';These utilities handle hidden fields, password masking, and nested data structures in your custom review page.
Create your custom review page component:
import React from 'react'; import { Button, Box, Typography } from '@mui/material'; export const CustomReviewPage = (props: ReviewComponentProps) => { const { busy, schema, data, handleBack, handleExecute } = props; const [showHiddenFields, setShowHiddenFields] = React.useState(false); const reviewData = React.useMemo( () => generateReviewTableData(schema, data, { includeHiddenFields: showHiddenFields }), [schema, data, showHiddenFields] ); const hasHiddenFields = schemaHasUiHiddenFields(schema); return ( <Box> <Typography variant="h5">Review Your Workflow Data</Typography> {hasHiddenFields && ( <ReviewHiddenParametersAlert showHiddenFields={showHiddenFields} onShowHiddenFieldsChange={setShowHiddenFields} /> )} <NestedReviewTable data={reviewData} /> <Box sx={{ mt: 2, display: 'flex', gap: 1 }}> <Button onClick={handleBack} disabled={busy}> Back </Button> <Button variant="contained" onClick={handleExecute} disabled={busy} > Execute Workflow </Button> </Box> </Box> ); };Add the
getReviewComponent()method to yourOrchestratorFormApiimplementation:export class MyFormApi implements OrchestratorFormApi { getReviewComponent() { return CustomReviewPage; } // ... other OrchestratorFormApi methods }- Register your custom form API with the Orchestrator plugin according to your plugin’s extension mechanism.
Verification
- Open the Orchestrator plugin in the Developer Hub web interface.
- Select a workflow and complete the workflow form.
- Proceed to the review step.
- Confirm that your custom review page displays with the correct layout and styling.
- Click Back and confirm that the workflow form is populated.
- Click Execute Workflow and verify that the workflow runs successfully.
Next steps
To revert to the default Orchestrator review page, return undefined from the getReviewComponent() method:
export class MyFormApi implements OrchestratorFormApi {
getReviewComponent() {
return undefined; // Uses default review page
}
}14.5.15. Custom review page API reference
The custom review page API provides the ReviewComponentProps interface, helper utilities for data processing, and UI components to implement custom review pages for Red Hat Developer Hub Orchestrator workflows.
14.5.15.1. ReviewComponentProps interface
Your custom review component receives the following properties through the ReviewComponentProps interface:
| Property | Type | Description |
|---|---|---|
|
|
|
Indicates whether a workflow run is in progress. Disable action buttons when this value is |
|
|
|
Defines field structure, titles, and UI hints such as hidden fields for the workflow form. |
|
|
|
Contains the user-submitted form values structured according to the schema and awaiting review before the workflow runs. |
|
|
|
Returns to the previous step (same behavior as the default review page). This callback matches the default review page behavior. |
|
|
|
Runs the workflow with the reviewed data. Call this function when the user clicks Run to start the workflow. |
14.5.15.2. Helper utilities
The orchestrator-form-react package exports the following utilities to help you build custom review pages that handle data correctly:
| Function | Signature | Description |
|---|---|---|
|
|
|
Processes form data for display. Respects |
|
|
|
Returns |
14.5.15.3. Helper components
The orchestrator-form-react package exports the following React components for use in custom review pages:
| Component | Props | Description |
|---|---|---|
|
|
|
Renders form data in a nested table structure. Accepts data processed by |
|
|
|
Displays an alert with a toggle switch for showing or hiding fields marked as |
14.5.15.4. OrchestratorFormApi method
To provide a custom review page, implement the following method in your OrchestratorFormApi implementation:
| Method | Return Type | Description |
|---|---|---|
|
|
|
Returns your custom review page component, or |
Chapter 15. Troubleshoot
15.1. Troubleshoot
Diagnose and resolve common issues with authentication, configuration, deployments, and integrations to maintain platform availability.
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 and configuration issues that prevent users from accessing the platform.
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.yamlfile, setomitIdentityTokenOwnershipClaimtotrueas 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
- Check the Identity Provider (IdP) session timeout: the IdP might have a shorter session lifetime than Developer Hub.
-
Check the
sessionDurationparameter for your authentication provider. -
Check the AutoLogout
idleTimeoutMinutessetting, if auto-logout is enabled.
Additional resources
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.autologoutsettings in yourapp-config.yamlfile.
Additional resources
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
- Verify that your Developer Hub version includes the upstream session expiration fix.
-
Verify that your authentication provider is correctly configured with valid
metadataUrl,clientId, andclientSecretsettings.
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:
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.
- 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.
- 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.yamlfile, ensure thatdisableIdentityResolutionis not set totruefor 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
preferredUsernameMatchingUserEntityNameinstead ofemailMatchingUserEntityProfileEmail.
15.2.2.7. 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.7.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=*)For more information about LDAP user filters, see Enable user provisioning with LDAP.
15.2.2.7.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.githubsection is configured in yourapp-config.yamlfile with valid GitHub App credentials. For more information, see Import users and groups from GitHub.
15.2.2.7.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.gitlabsection is configured in yourapp-config.yamlfile with a valid GitLab personal access token. For more information, see Import users and groups from GitLab.
15.2.3. Troubleshoot configuration issues
15.2.3.1. Troubleshoot configuration issues
Resolve common configuration issues in Red Hat Developer Hub, such as Helm overwriting predefined array values.
15.2.3.2. Maintain dynamic plugin settings in Helm deployments
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
For
extraEnvVars, add the following content to yourvalues.yamlfile: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" . }}'For
extraVolumeMounts, add the following content to yourvalues.yamlfile:extraVolumeMounts: - name: dynamic-plugins-root mountPath: /opt/app-root/src/dynamic-plugins-root - name: temp mountPath: /tmpFor
extraVolume, add the following content to yourvalues.yamlfile: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 deployment errors in plugins and serverless workflows to restore automation capabilities.
15.3.2. Troubleshoot pod startup failures
To ensure successful pod startup during a RHDH upgrade, update Orchestrator plugin versions to match the RHDH 1.8.6 configuration (version 1.8.12). This update enables the Orchestrator to automatically infer integrity hashes and prevents configuration errors.
Prerequisites
- You have an Operator-backed instance of RHDH 1.8.5 with Orchestrator 1.8.9.
You encounter the following error when upgrading to RHDH 1.8.6:
InstallException: No integrity hash provided for Package @redhat/backstage-plugin-orchestrator@1.8.9
Procedure
Edit the
dynamic-pluginsConfigMap to update the Orchestrator plugin version to1.8.12:$ oc edit configmap dynamic-plugins-rhdh -n <your_namespace>
Update the plugin versions in the ConfigMap:
apiVersion: v1 kind: ConfigMap metadata: name: dynamic-plugins-rhdh data: dynamic-plugins.yaml: | includes: - dynamic-plugins.default.yaml plugins: - package: "@redhat/backstage-plugin-orchestrator@1.8.12" disabled: false - package: "@redhat/backstage-plugin-orchestrator-backend-dynamic@1.8.12" disabled: false dependencies: - ref: sonataflow - package: "@redhat/backstage-plugin-scaffolder-backend-module-orchestrator-dynamic@1.8.12" disabled: false - package: "@redhat/backstage-plugin-orchestrator-form-widgets@1.8.12" disabled: false- Save and close the ConfigMap. The RHDH pods restart automatically.
Verification
Monitor the status of the RHDH pods to ensure they restart:
$ oc get pods -w
-
Verify that all RHDH pods are in
Runningstatus with no errors.
15.3.3. 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
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"
-
Verify the required configuration by inspecting the
dynamic-plugins.default.yamlfile that lists the required environment variables for each plugin. The variables for each plugin are in the format of${PLUGIN_VARIABLE_NAME}. 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: OpaqueMount the secret:
If you deployed RHDH by using the Operator, update your
BackstageCR, as follows:spec: application: extraEnvs: secrets: - name: rhdh-secretsIf you deployed RHDH by using the Helm chart, in the
upstream.backstagekey in your Helm chart values, enter the name of the Developer Hubrhdh-secretssecret as the value for theextraEnvVarsSecretsfield. For example:upstream: backstage: extraEnvVarsSecrets: - rhdh-secrets
15.3.4. Restore workflow visibility by removing duplicate entries
To restore clear workflow visibility in the Orchestrator UI, identify workflows that share the same ID and assign unique identifiers. When you deploy multiple versions with distinct IDs, you remove duplicate entries and maintain accurate workflow tracking.
Prerequisites
- You have administrator access to the RHDH instance.
- You have access to the workflow definitions and deployment manifests.
Procedure
Identify duplicate workflows in the Orchestrator UI:
- Navigate to the Orchestrator plugin in RHDH.
- Review the workflow list for entries that appear multiple times with the same workflow name.
Note the version information displayed in the version column of the workflow list and on the workflow details page to distinguish between duplicate entries.
NoteThe version column displays metadata from the workflow definition, retrieved from the Data Index GraphQL schema. This information helps you identify which workflows share the same ID but does not prevent the duplicate entries. If a workflow definition does not specify a version, the field appears empty in the UI. Duplicate entries can occur when you deploy the same workflow ID to different runtime servers over time, because the Data Index records all executions.
Verify the workflow IDs in your workflow definitions:
-
Locate the workflow definition files (
.sw.yamlor.sw.jsonfiles). -
Check the
idfield in each workflow definition. -
Identify workflows that use the same
idvalue, even if they have differentversionvalues. Review the
versionfield in each workflow definition to understand how workflows appear in the UI.Example of problematic workflow definitions:
# First deployment id: customer-onboarding version: "1.0" name: Customer Onboarding # Second deployment (causes duplicate) id: customer-onboarding version: "2.0" name: Customer Onboarding
-
Locate the workflow definition files (
Determine which workflow version to retain:
- Review the workflow instances and their execution history.
- Identify which version is currently in active use.
- Check for any running instances of older versions that must complete before removal.
Update workflow definitions with unique IDs:
For the new workflow version, modify the
idfield to include a version identifier:id: customer-onboarding-v2 version: "2.0" name: Customer Onboarding
- Maintain the original workflow ID for the current deployment.
- Build and deploy the updated workflow definition.
Remove outdated workflow deployments:
- After confirming the new workflow operates correctly, remove the old workflow deployment.
- Verify that all instances of the old workflow have completed.
Delete the workflow resources from your cluster:
oc delete sonataflow <old-workflow-name> -n <workflow-namespace>
NoteDeleting the workflow deployment removes it from the cluster but preserves historical execution records in the Data Index. Users can still view past workflow runs in RHDH.
Clean historical data if necessary:
If duplicate entries persist in the UI after you remove the workflow deployments, the Data Index database has historical records from earlier workflow executions. These records preserve the execution history of workflows that ran on different runtime servers over time.
ImportantBack up your workflow execution records before you remove historical data from the Data Index database. Removing this data permanently prevents access to past execution records.
- Connect to the Data Index database to verify the duplicate entries.
Query the workflow definitions to identify duplicate entries:
SET search_path TO "sonataflow-platform-data-index-service"; SELECT id, version, name FROM definitions;
- Evaluate whether to remove the historical data. You can keep the historical data to retain past workflow execution records, which allows you to view the execution history and results of completed workflow instances. Alternatively, contact your system administrator or Red Hat Support for guidance on safely removing historical duplicate entries from the Data Index without affecting active workflow operations.
Verification
- Navigate to the Orchestrator plugin in RHDH.
- Confirm that the UI shows only one entry for each workflow.
- Verify that the version information displays correctly for each workflow.
- Test workflow execution to confirm the correct version runs.
15.3.5. Troubleshooting workflow deployments
Identify and resolve issues related to plugin visibility, pipeline execution, or resource synchronization.
Visibility issues
- Missing Orchestrator plugin
- If Orchestrator features do not appear in RHDH, make sure you have updated the RHDH Helm chart with the required plugins.
- Software templates not appearing
-
Make sure the
orchestrator-software-templateschart is installed and theorchestrator-auth-secretexists in the correct namespace.
Pipeline failure (CI)
- GitHub or GitLab actions failure
-
The GitOps automation includes a GitHub Action or GitLab CI step that creates a
PipelineRunmanifest from aPipelineRuntemplate. Examine the failed GitHub or GitLab actions logs. Failures often occur due to invalid Git credentials or misconfigured runner permissions. You can also create thePipelineRunfile manually to bypass automation issues. - Build or push issues
Check the CI tab in the RHDH Catalog.
If RHDH does not display the status, use the OpenShift Container Platform console to monitor pipeline instances and triggered jobs. Navigate to Pipelines > PipelineRuns for detailed logs.
If the Tekton pipeline fails during the build or push stages:
-
Verify that your
Quay.iorobot account has Write permissions. -
Ensure the
docker-registry-credentialssecret exists in therhdhnamespace.
-
Verify that your
Resource visibility and Sync issues (CD)
- Pipeline succeeds but workflows are missing
If the CI pipeline succeeds but the workflow does not appear in the CD tab:
Make sure the target namespace is labeled for Argo CD:
$ oc label ns <target_namespace> rhdh.redhat.com/argocd-namespace=true-
Make sure the ArgoCD ServiceAccount has the required permissions to manage resources in the
rhdhnamespace.
- Argo CD sync failure
-
If resources appear but remain in an
OutOfSyncstate, click Refresh in the Argo CD UI or verify that the AppProject exists in theorchestrator-gitopsnamespace. - PostgreSQL authentication failures in Argo CD
If the Orchestrator fails to connect to the PostgreSQL database when you deploy by using Argo CD, the failure is often due to a mismatch in password generation.
The Orchestrator Helm chart uses the Helm
lookupfunction to check for an existing PostgreSQL secret. Because Argo CD useshelm templateto render manifests, it cannot query the live cluster. Consequently, the chart generates a new, random password instead of retrieving the existing one, resulting in an authentication failure.To resolve this failure, you must complete the following steps:
Create the database secret manually with the correct credentials:
$ kubectl create secret generic <backstage-postgresql-svcbind-postgres> --from-literal=password=<your_password>
Update your Helm configuration (for example, in
values.yaml) to disable automatic service binding generation:upstream: postgresql: serviceBindings: enabled: false auth: username: postgres database: backstage existingSecret: backstage-postgresql-svcbind-postgres secretKeys: adminPasswordKey: password userPasswordKey: password- Sync the application in Argo CD to apply the changes.
15.3.6. Diagnose serverless workflow issues
15.3.6.1. Diagnose serverless workflow issues
Use the following information to diagnose and resolve serverless workflow and visibility issues.
15.3.6.2. Troubleshoot 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 code | Description | Possible cause |
|---|---|---|
|
|
Unauthorized access |
The token, password, or username provided for the endpoint might be incorrect or expired. |
|
|
Forbidden |
The server understood the request but refused to process it due to insufficient permissions to a resource or action. |
|
|
Conflict |
The workflow attempted to create or update a resource (for example, Kubernetes or OpenShift resources) that already exists. |
Additional resources
15.3.6.3. Troubleshoot common deployment errors
Use these steps to diagnose and resolve common workflow deployment, connectivity, or configuration failures.
Procedure
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
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
- To resolve the SSL certificate error, load the additional CA certificate into the running workflow container.
15.3.6.4. Troubleshoot cross-namespace configuration
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
- Identify required namespaces.
-
Retrieve the namespace value where RHDH is running using
oc get backstage -A. Identify the SonataFlow Services Namespace by checking for either a
sonataflowclusterplatformorsonataflowplatforminstance.NoteBy default, the SonataFlow namespace must be the same as the RHDH namespace.
If the workflow is deployed to a namespace outside the core SonataFlow services, configure network policies to permit the necessary inter-namespace traffic.
# Example
NetworkPolicyconfiguration 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-logicAdd
SonataFlowClusterPlatformCustom 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_NAMESPACETo allow communication between RHDH namespace and the workflow namespace, create the following network policies:
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_NAMESPACEAllow 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
-
(Optional) Create an
allow-intra-namespacepolicy in the workflow namespace to enable unrestricted communication among all pods within that namespace. If workflow persistence is required, perform the following configuration steps:
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
Configure the workflow
serviceRefproperty 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: 5432namespace- Enter the namespace where the PostgreSQL server is deployed.
If the
sonataflow-platform-data-index-servicecannot connect to the PostgreSQL database on startup, perform the following diagnostic checks:-
Verify that the PostgreSQL Pod has fully transitioned to a
runningand operational status. Allow additional time for database initialization before expecting related service pods (DataIndex,JobService) to establish a connection. - 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.
-
Verify that the PostgreSQL Pod has fully transitioned to a
15.3.6.5. Troubleshoot missing workflows
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
- 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.
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:
- It attempts to create its schema in the database (if persistence is active).
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.
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>/graphqlUse 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
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.
Make sure the Data Index properties are set in the
-managed-propsConfigMap 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
NoteThe
-managed-propsConfigMap 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.
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.
Make sure you have enabled Data Index and Job Service in the
SonataFlowPlatformcustom resource (CR) as shown in the following configuration:services: dataIndex: enabled: true jobService: enabled: trueIf you fail to enable the Data Index and the Job Services in the
SonataFlowPlatformcustom resource (CR), the Orchestrator plugin fails to fetch the available workflows.NoteYou can also manually edit the
SonataFlowPlatformCR instance to trigger the re-creation of workflow-related manifests.Configure role-based access control (RBAC) permissions to ensure workflows are visible in the Orchestrator UI.
NoteWhen the RBAC plugin is enabled, the Orchestrator UI does not display workflows by default. You must explicitly grant read permissions.
-
Check your RHDH
app-config.yamlfile to confirm if the RBAC plugin is enabled. -
Confirm your user or role has the
orchestrator.workflowpermission with thereadaction. If this permission is missing, add the following to your RBAC CSV (
rbac-policy.csv) file:p, role:default/workflowUser, orchestrator.workflow, read, allow
Make sure
policyFileReloadis set totruein your configuration, or restart the RHDH application:permission: enabled: true rbac: policyFileReload: true
-
Check your RHDH
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 AI Connector and Model Context Protocol tools to restore intelligent platform features.
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 sidecar containers. You must gather logs from these components and provide them to Red Hat Support for diagnostic analysis.
15.4.2.2. Troubleshoot 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.
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.1. Verify dynamic plugin status
Validate that the dynamic plugins have been successfully installed into your RHDH project Pod by using the following command:
$ oc logs -c install-dynamic-plugins deployment/<your RHDH deployment>
In the install-dynamic-plugin logs, you can check the following installation logs for successful logs:
-
red-hat-developer-hub-backstage-plugin-catalog-backend-module-model-catalog(Entity Provider) -
red-hat-developer-hub-backstage-plugin-catalog-techdoc-url-reader-backend(TechDoc URL Reader)
15.4.2.2.2. Inspect plugin logs
View the OpenShift AI Connector for Red Hat Developer Hub plugins in the backstage-backend container. Items to look for:
| Plugin Component | Logger Service Target | Common Log Text |
|---|---|---|
|
Model Catalog Entity Provider |
|
|
|
Model Catalog TechDoc URL Reader |
|
|
To enable debug logging, set the LOG_LEVEL environment variable to debug on the backstage-backend container. For more information, see Monitoring and logging.
15.4.2.2.3. Inspect the OpenShift AI Connector for RHDH
The OpenShift AI Connector for RHDH sidecars manage the data fetching and storage:
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'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
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.3. Query model registries
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 | jqExample showing how to fetch model versions
$ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/model_versions | jqExample showing how to fetch model artifacts
$ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/model_artifacts | jqExample showing how to fetch inference services
$ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/inference_services | jqExample showing how to fetch serving environments
$ curl -k -H "Authorization: Bearer $TOKEN" ${rhoai-short}_MODEL_REGISTRY_URL/api/model_registry/v1alpha3/serving_environments | jqExample 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 Red Hat 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
Log in to the OCP cluster running RHDH and go to your RHDH project using the following code:
$ oc project my-rhdh-project
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
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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
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:
- Find your Backstage version in the RHDH release notes preface.
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>.TipTo 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. Validate tool inputs using 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 unsupported tool calling errors
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
- Consult your model documentation to confirm its support for tool calling.
- 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
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
Check the token validation status in the Red Hat Developer Lightspeed for Red Hat Developer Hub interface:
- In the Red Hat Developer Lightspeed for Red Hat Developer Hub chat box, click the menu icon (Chatbot options) and select MCP settings.
- Locate the relevant server and check the status message displayed below the token field.
- 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.
Verify the authentication token configuration.
- Ensure a static token is configured for the RHDH MCP server.
-
In your MCP client, verify that the token is set as the bearer token. The authorization header must use the
Bearer <mcp_token>format.
Check the MCP endpoint configuration.
- Confirm that the MCP server URL properly resolves correctly, particularly when using desktop clients.
- Use legacy SSE endpoint if your MCP client requires it instead of the Streamable endpoint. (For more details, see the Configuration topic).
Verify the RHDH
app-config.yamlfile for formatting errors:-
Ensure there are no duplicate
backendentries and that the YAML indentation is accurate. -
Confirm that the configuration for the static token and MCP plugin sources is nested under an existing
backendfield, if one is present. For a reference configuration, see Configure MCP in RHDH.
-
Ensure there are no duplicate
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
Select an appropriate model for tool calling.
- Verify that the model has good support for tool calling.
- Make sure your model is not too small. We recommend a model with at least 7 billion parameters and a context window of 32k.
Refine your queries.
- Use more well-defined queries that limit the amount of data returned in the response from the tool.
- 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
Quick-lookup reference information for Red Hat Developer Hub configuration syntax, permission policies, trace attributes, and Helm chart parameters.
Use this section to look up supported dynamic plugin parameters and configuration paths, permission policy strings and conditional rule schemas for RBAC, OpenTelemetry configuration properties and trace attributes for workflow observability, and Helm chart values for deployment customization.
16.2. Dynamic plugin parameter reference for configuration paths
16.2.1. Dynamic plugin parameter reference for configuration paths
Reference information about the dynamic plugins available in Red Hat Developer Hub, including preinstalled plugins, supported configuration paths, and support tiers.
Use this reference to look up plugin names, package identifiers, and configuration paths when installing, enabling, or customizing dynamic plugins in your Developer Hub deployment. Plugins are organized by support tier: generally available, Technology Preview, deprecated, and other installable plugins.
16.2.2. Preinstalled dynamic plugins reference
Red Hat Developer Hub is preinstalled with a selection of dynamic plugins.
The following 16 preinstalled dynamic plugins are enabled by default:
-
@backstage-community/plugin-analytics-provider-segment -
@backstage-community/plugin-scaffolder-backend-module-regex -
@backstage/plugin-techdocs-backend -
@backstage/plugin-techdocs-module-addons-contrib -
@backstage/plugin-techdocs -
@red-hat-developer-hub/backstage-plugin-adoption-insights-backend -
@red-hat-developer-hub/backstage-plugin-adoption-insights -
@red-hat-developer-hub/backstage-plugin-analytics-module-adoption-insights -
@red-hat-developer-hub/backstage-plugin-catalog-backend-module-extensions -
@red-hat-developer-hub/backstage-plugin-dynamic-home-page -
@red-hat-developer-hub/backstage-plugin-extensions-backend -
@red-hat-developer-hub/backstage-plugin-extensions -
@red-hat-developer-hub/backstage-plugin-global-header -
@red-hat-developer-hub/backstage-plugin-lightspeed-backend -
@red-hat-developer-hub/backstage-plugin-lightspeed -
@red-hat-developer-hub/backstage-plugin-quickstart
The dynamic plugins that require custom configuration are disabled by default.
Upon application startup, for each plugin that is disabled by default, the install-dynamic-plugins init container within the Developer Hub pod log displays a message similar to the following:
======= Skipping disabled dynamic plugin ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic
To enable this plugin, add a package with the same name to the Helm chart and change the value in the disabled field to false. For example:
global:
dynamic:
includes:
- dynamic-plugins.default.yaml
plugins:
- package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic
disabled: false
The default configuration for a plugin is extracted from the dynamic-plugins.default.yaml file, however, you can use a pluginConfig entry to override the default configuration.
16.2.3. Red Hat supported plugins and configuration paths reference
Red Hat provides full support for the following 31 dynamic plugins.
| Name | Plugin | Version | Path and required variables |
|---|---|---|---|
|
Adoption Insights |
0.8.2 |
| |
|
Adoption Insights |
|
0.8.2 |
|
|
Analytics Module Adoption Insights |
|
0.8.2 |
|
|
Analytics Provider Segment |
1.27.0 |
| |
|
Dynamic Home Page |
1.13.1 |
| |
|
GitHub Org |
0.3.20 |
| |
|
GitHub |
0.13.0 |
| |
|
GitHub |
0.9.7 |
| |
|
GitLab Org |
0.2.19 |
| |
|
GitLab |
0.8.1 |
| |
|
Global Header |
1.21.6 |
| |
|
Keycloak |
3.19.2 |
| |
|
Kubernetes |
0.21.2 |
| |
|
Kubernetes |
|
2.17.1 |
|
|
Ldap |
0.12.3 |
| |
|
Lightspeed |
2.8.5 |
| |
|
Lightspeed |
2.8.5 |
| |
|
MS Graph |
0.9.1 |
| |
|
Orchestrator Form Widgets |
|
1.10.7 |
|
|
Orchestrator |
5.7.12 |
| |
|
Orchestrator |
|
8.9.4 |
|
|
Quickstart |
1.9.6 |
| |
|
RBAC |
1.52.4 |
| |
|
Regex |
2.15.1 |
| |
|
Signals |
0.3.13 |
| |
|
Tech Radar |
1.17.0 |
| |
|
Tech Radar |
1.16.0 |
| |
|
TechDocs Module Addons Contrib |
1.1.34 |
| |
|
TechDocs |
1.17.2 |
| |
|
TechDocs |
2.1.6 |
| |
|
Topology |
2.12.3 |
|
16.2.4. Technology Preview plugins
Red Hat provides Technology Preview support for the following 14 plugins.
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.
| Name | Plugin | Version | Path and required variables |
|---|---|---|---|
|
ACR |
1.24.1 |
| |
|
Bulk Import |
7.3.5 |
| |
|
Bulk Import |
7.3.5 |
| |
|
Extensions |
0.17.1 |
| |
|
Extensions |
|
0.17.1 |
|
|
Extensions |
0.17.1 |
| |
|
GitLab |
0.11.4 |
| |
|
Kubernetes |
0.12.17 |
| |
|
Notifications |
0.5.15 |
| |
|
Notifications |
0.3.19 |
| |
|
Notifications |
0.6.3 |
| |
|
Pingidentity |
|
0.11.1 |
|
|
Scaffolder Relation Processor |
|
2.14.2 |
|
|
Signals |
0.0.29 |
|
16.2.5. Deprecated plugins
There are no deprecated plugins in this release of Red Hat Developer Hub (RHDH)
16.2.6. Other installable plugins
The following Technology Preview plugins are not preinstalled and must be installed from an external source.
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.
| Name | Plugin | Version | Installation Details |
|---|---|---|---|
|
Ansible Automation Platform Frontend |
1.0.0 | ||
|
Ansible Automation Platform |
1.0.0 | ||
|
Ansible Automation Platform Scaffolder Backend |
1.0.0 |
16.2.7. Red Hat community supported plugins
Red Hat provides community support for the following 45 dynamic plugins in ghcr.io.
Replace <tag> with the version tag corresponding to your Developer Hub version. See Determining Tag Values
| Name | Version | Path and required variables |
|---|---|---|
|
3Scale |
3.13.0 |
` |
|
ArgoCD Backend |
1.4.0 |
` |
|
Auth Frontend |
0.1.6 |
` |
|
Azure DevOps Backend |
0.27.0 |
` |
|
Catalog Backend Module Azure DevOps Annotator Processor |
0.18.0 |
` |
|
Catalog Backend Module Bitbucket Cloud |
0.5.9 |
` |
|
Catalog Backend Module Bitbucket Server |
0.5.9 |
` |
|
Datadog |
2.7.2 |
` |
|
Dynatrace |
10.17.0 |
` |
|
GitHub Actions |
0.22.0 |
` |
|
GitHub Deployments |
0.18.0 |
` |
|
GitHub Discussions |
0.10.0 |
` |
|
GitHub Discussions Search Backend Module |
0.11.0 |
` |
|
GitHub Insights |
3.5.0 |
` |
|
GitHub Issues |
0.21.0 |
` |
|
GitHub Pull Requests |
3.7.0 |
` |
|
GitHub Pull Requests Board |
0.16.0 |
` |
|
GitLab Backend |
7.0.1 |
` |
|
JFrog Artifactory |
1.28.0 |
` |
|
Jenkins Backend |
0.27.0 |
` |
|
Jenkins Scaffolder Backend Module |
0.20.0 |
` |
|
Jira |
2.14.0 |
` |
|
Lighthouse Backend |
0.21.0 |
` |
|
Nexus Repository Manager |
1.23.2 |
` |
|
PagerDuty Backend |
0.12.0 |
` |
|
PagerDuty Entity Processor |
0.3.10 |
` |
|
PagerDuty Scaffolder Actions |
0.2.9 |
` |
|
Quay Backend |
1.14.0 |
` |
|
Roadie ArgoCD Backend |
4.8.0 |
` |
|
Scaffolder Backend ArgoCD |
1.8.1 |
` |
|
Scaffolder Backend Module AWS |
2.8.2 |
` |
|
Scaffolder Backend Module Azure |
0.2.19 |
` |
|
Scaffolder Backend Module Azure DevOps |
0.23.0 |
` |
|
Scaffolder Backend Module Bitbucket Cloud |
0.3.4 |
` |
|
Scaffolder Backend Module Bitbucket Server |
0.2.19 |
` |
|
Scaffolder Backend Module DotNet |
0.13.0 |
` |
|
Scaffolder Backend Module Gerrit |
0.2.19 |
` |
|
Scaffolder Backend Module Quay |
2.18.0 |
` |
|
Scaffolder Backend Module ServiceNow |
2.15.1 |
` |
|
Scaffolder Backend Module SonarQube |
2.15.0 |
` |
|
Scaffolder Backend Module Utils |
4.1.2 |
` |
|
Search Backend Module Azure DevOps |
0.5.0 |
` |
|
Security Insights |
3.3.1 |
` |
|
SonarQube Backend |
1.1.1 |
` |
|
Tekton |
3.37.0 |
` |
16.2.7.1. Troubleshooting
Plugin not loading
If a plugin fails to load, perform the following checks:
-
Verify the
ghcr.iopath is correct and the image tag or digest exists. -
Confirm your cluster has network access to
ghcr.io. - Review Developer Hub logs for OCI pull errors.
Determining tag values
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:- Find your Backstage version in the RHDH release notes preface.
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>.TipTo ensure environment stability, use a SHA256 digest instead of a version tag. See Determining SHA256 Digests.
Determining SHA256 digests
You can look up the SHA256 digest using the Skopeo CLI or by searching in the RHDH Plugin Export Overlays repository.
Skopeo CLI
Ensure you have skopeo and jq installed.
- Locate the plugin path in the Dynamic plugins reference.
Run the following command, replacing the plugin path prefix
oci://withdocker://:skopeo inspect docker://<plugin-path>:<tag> | jq '.Digest'
RHDH Plugin Export Overlays Repo
Go to the plugin packages list in the rhdh-plugin-export-overlays repository. Search for your plugin and select the tag that is associated with this release.
16.2.7.2. Additional resources
16.3. Permission policies and conditional rules reference for RBAC configurations
16.3.1. Permission policies and conditional rules reference for RBAC configurations
Reference information about permission policy types, available permissions, and conditional policy rules for RBAC configurations in Red Hat Developer Hub.
Use this reference to look up the permission strings required when defining RBAC policies for catalog, scaffolder, RBAC, Kubernetes, Extensions, and plugin resources. You can also look up conditional policy schemas and examples for defining fine-grained access rules with or without criteria.
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 parameters and definitions
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
|
Enables a user or role to read from the catalog |
|
|
|
Enables a user or role to create catalog entities, including registering an existing component in the catalog | |
|
|
|
|
Enables a user or role to refresh a single or multiple entities from the catalog |
|
|
|
|
Enables a user or role to delete a single or multiple entities from the catalog |
|
|
|
Enables a user or role to read a single or multiple locations from the catalog | |
|
|
|
Enables a user or role to create locations within the catalog | |
|
|
|
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
|
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. |
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
|
Enables the execution of an action from a template |
|
|
|
|
Enables a user or role to read a single or multiple one parameters from a template |
|
|
|
|
Enables a user or role to read a single or multiple steps from a template |
|
|
|
Enables a user or role to trigger software templates which create new scaffolder tasks | |
|
|
|
Enables a user or role to cancel currently running scaffolder tasks | |
|
|
|
Enables a user or role to read all scaffolder tasks and their associated events and logs | |
|
|
|
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
|
Enables a user or role to read permission policies and roles |
|
|
|
Enables a user or role to create a single or multiple permission policies and roles | |
|
|
|
|
Enables a user or role to update a single or multiple permission policies and roles |
|
|
|
|
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
Enables a user to read Kubernetes cluster details under the | |
|
|
|
Enables a user to read information about Kubernetes resources located at | |
|
|
|
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.
Topology plugin does not have its own defined permissions. Kubernetes permissions are used instead.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
Enables a user to read Kubernetes cluster details under the | |
|
|
|
Enables a user to read information about Kubernetes resources located at | |
|
|
|
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.
Tekton plugin does not have its own defined permissions. Kubernetes permissions are used instead.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
Enables a user to read Kubernetes cluster details under the | |
|
|
|
Enables a user to read information about Kubernetes resources located at | |
|
|
|
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
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.
| Name | Resource type | Policy | Description |
|---|---|---|---|
|
|
|
|
Enables a user or role to view plugin configurations in Extensions |
|
|
|
|
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 schemas
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"]
}
}
]
}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.
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.
Additional resources
16.4. Trace attributes and OpenTelemetry configurations
16.4.1. Trace attributes and OpenTelemetry configurations
Reference information about OpenTelemetry configuration properties and trace attributes for serverless workflow observability in Red Hat Developer Hub.
Use this reference to look up configuration properties that control where traces are sent, sampling rates, and service names. You can also look up span attributes and lifecycle events that SonataFlow automatically generates for workflow executions, to build Jaeger queries, filter traces by workflow state, and track requests across service boundaries.
16.4.2. OpenTelemetry configurations
Configuration properties that control where traces are sent, how often they are sampled, and which service name appears in your monitoring dashboard. Reference this table to tune telemetry behavior for your environment.
| Property | Description | Default |
|---|---|---|
|
|
Enables or disables OpenTelemetry support. |
|
|
|
Specify the service name that appears in the trace backend. |
|
|
|
The URL of the OTLP-compatible collector. | |
|
|
The transport protocol. Supported values are |
|
|
|
The sampling strategy. For example, |
|
16.4.3. Trace attributes and lifecycle events
16.4.3.1. Trace attributes and lifecycle events
Reference information about span attributes and lifecycle events that SonataFlow automatically generates for workflow executions.
Use this data dictionary to build Jaeger queries, filter traces by workflow state, and track requests across service boundaries. This data allows you to track a workflow from start to finish, analyze external function calls, and correlate logs across asynchronous boundaries.
16.4.3.2. Trace attribute definitions and filtering keys
Automatic span attributes that identify workflow executions, instances, and states. Use these attributes in Jaeger queries to locate specific workflow runs, filter by version, or trace process instances through various execution states.
To locate specific workflow executions or trace a process through various states, use the automatic span attributes generated by SonataFlow. Each span includes the following specific attributes:
-
sonataflow.process.id: Indicates the ID of the workflow definition. -
sonataflow.process.instance.id: Indicates the unique ID for the specific execution instance. -
sonataflow.process.version: Indicates the version of the workflow definition. -
sonataflow.workflow.state: Indicates the name of the current workflow state, for example,StartEvent. -
sonataflow.process.instance.state: Indicates the current state of the process instance, such asACTIVE,COMPLETED,ERROR, orSUSPENDED. -
sonataflow.transaction.id: Indicates the ID used to correlate multiple workflows in a single business transaction. -
sonataflow.tracker.*: Indicates custom attributes converted fromX-TRACKER-*headers. -
service.nameandservice.version: Indicates the service identification details from the configuration.
16.4.3.3. Process lifecycle events for timeline tracking
OpenTelemetry events that mark workflow execution milestones including start, completion, errors, and state transitions. Use these events to reconstruct the chronological order of workflow execution and identify when failures occurred.
To understand the exact chronological order of a workflow’s execution, look for OpenTelemetry events that are automatically generated at key lifecycle points. SonataFlow attaches the following events and their specific attributes to spans to mark execution milestones:
-
process.instance.start: Indicates the beginning of the execution. This event includes theprocess.instance.id, thetriggerthat started the process, and thereference.id. -
process.instance.complete: Indicates the completion of the workflow. This event includes theprocess.instance.id, the finaloutcome, and the totalduration.ms. -
process.instance.error: Indicates a workflow failure. This event includes theprocess.instance.id, theerror.message, and theerror.type. -
state.startedandstate.completed: Indicate the start and completion of individual workflow states. These events include anevent.descriptionthat details the state execution. -
log.message: Indicates the application log content within the trace span. This event provides thelevel,logger,message,thread.name, andthread.id.
16.4.3.4. Function call attributes for external integration debugging
HTTP and function-specific attributes attached to external service call spans. Use these attributes to debug REST API failures, identify slow external dependencies, and verify correct endpoint invocation in workflow integrations.
When a workflow invokes an external function, for example, a REST service, the function call spans are enriched with additional HTTP attributes:
-
sonataflow.function.name: The name of the function being called. -
sonataflow.function.type: The type of function, such asrestorexpression. -
http.method: The HTTP method used for external REST calls. -
http.url: The full target URL for the external call. -
http.status_code: The resulting HTTP response code from the service.
16.4.3.5. Propagation headers
HTTP headers that SonataFlow extracts and propagates to maintain trace correlation across service boundaries. Use these headers to link workflow executions in distributed transactions and pass custom tracking context through service chains.
SonataFlow extracts and propagates the following headers to maintain observability across service boundaries:
-
X-TRANSACTION-ID: Correlates multiple workflow executions that belong to the same business transaction. -
X-TRACKER-*: Sanitizes and converts any custom tracking context from headers into span attributes, such assonataflow.tracker.*, to simplify querying.
16.5. Helm chart configuration parameters to define advanced deployment
16.5.1. Helm chart configuration parameters to define advanced deployment
Reference information about Helm chart configuration parameters for defining advanced Developer Hub deployments on Kubernetes and OpenShift clusters.
Use this reference to look up supported Helm keys, default values, and parameter override schemas when deploying or upgrading Red Hat Developer Hub. You can customize resource boundaries, networking parameters, and runtime configurations to establish a production-ready environment.
16.5.2. Helm chart configuration parameters
16.5.2.1. Helm chart configuration parameters
Use the overview of default Helm Chart values to configure and customize your RHDH deployment.
The values are organized into five main categories, which cover the key namespaces that organize the chart’s hierarchical configuration structure:
- Global
- Orchestrator
- Route
- Test
- Upstream
16.5.2.2. Display a complete list of Helm Chart values with Helm CLI
Use the available options to configure Red Hat Developer Hub with Helm Charts: the Helm deployment method specific configuration files.
Procedure
Pull the released RHDH Helm Chart, including all its dependencies:
$ helm pull redhat-developer-hub \ --repo https://charts.openshift.io \ --version 1.10.1 \ --untar
View default values:
View default values of the RHDH Chart.
$ helm show values redhat-developer-hub
View default values of the upstream Backstage Chart. The fields can be set under the
upstreamscope when deploying the RHDH Chart.$ helm show values redhat-developer-hub/charts/backstage
Optional: View default values of the upstream PostgreSQL Chart, which is a dependency of the upstream Backstage Chart.
ImportantUsing the local PostgreSQL database is not recommended for production, as you should be using your own external database. However, it allows for visibility into the local database. For more information, see Configuring an external PostgreSQL instance using the Helm Chart.
The fields can be set under the
upstream.postgresqlscope when deploying the RHDH Chart.$ helm show values redhat-developer-hub/charts/backstage/charts/postgresql
16.5.2.3. Root namespace value
Use the root namespace value to customize resource names.
|
Key |
Description |
Type |
Default |
|
|
Lets you customize resource names. Can be used at the root level and upstream level. |
string |
|
16.5.2.4. Global namespace values
Use the global namespace values to define cross-cutting configurations that affect multiple chart components.
| Key | Description | Type | Default |
|---|---|---|---|
|
|
Enables service authentication within Backstage instance. |
object |
|
|
|
Backend service to service authentication. |
object |
|
|
|
Enables backend service to service authentication. Generates a secret value unless configured otherwise. |
bool |
|
|
|
Uses an existing secret. |
string |
|
|
|
Uses a specified value. |
string |
|
|
|
Catalog index configuration for automatic plugin discovery. The |
object |
|
|
|
Catalog index image registry. |
string |
|
|
|
Catalog index image repository. |
string |
|
|
|
Catalog index image tag or digest. |
string |
|
|
|
Shorthand for users who do not want to specify a custom hostname. Used only with the default upstream.backstage.appConfig value and with OpenShift Container Platform Route enabled. |
string |
|
|
|
Array of |
list |
|
|
|
List of dynamic plugins included inside the RHDH container image. |
string |
|
|
|
List of dynamic plugins. Every plugin package can be defined as an OCI artifact, NPM or local package reference. This list can potentially override the list of plugins in include files. |
list |
|
|
|
Custom hostname shorthand that overrides |
string |
|
|
|
Global Docker registry secret names as an array. |
list |
|
|
|
Global Docker image registry. |
string |
|
16.5.2.5. Orchestrator namespace values
Use orchestrator namespace values to configure the orchestrator subsystem.
| Key | Description | Type | Default |
|---|---|---|---|
|
|
Enables orchestrator integration. |
bool |
|
|
|
List of orchestrator plugins and their configuration. |
list |
default list of orchestrator plugins to enable when |
|
|
Enables |
bool |
|
|
|
Image for the container used by the |
string |
|
|
|
Image for the container used by the SonataFlow data index. Note This is an optional image for disconnected environments. |
string |
|
|
|
Specifies which broker to integrate into SonataFlow event-driven workflows. |
string |
|
|
|
Specifies the Kubernetes namespace that contains the broker resource to integrate into SonataFlow event-driven workflows. |
string |
|
|
|
Host for the user-configured external database. |
string |
|
|
|
Name for the user-configured external database. |
string |
|
|
|
Port for the user-configured external database. |
string |
|
|
|
Name for the user-created secret to connect an external database. |
string |
|
|
|
Image for the |
string |
|
|
|
Image for the container used by the SonataFlow jobs service. Note This is an optional value used for disconnected environments. |
string |
|
|
|
Controls if monitoring is enabled for SonataFlow when using the Orchestrator. |
bool |
|
|
|
Sets the maximum CPU allocation for SonataFlow’s build resources. |
string |
|
|
|
Sets the maximum memory allocation for SonataFlow’s build resources. |
string |
|
|
|
Sets the minimum CPU allocation for SonataFlow’s build resources. |
string |
|
|
|
Sets the minimum memory allocation for SonataFlow’s build resources. |
string |
|
16.5.2.6. Route namespace values
Use route namespace values to configure OpenShift Container Platform route-specific settings.
| Key | Description | Type | Default |
|---|---|---|---|
|
|
OpenShift Route parameters. |
object |
|
|
|
Route-specific annotations. |
object |
|
|
|
Enables the creation of the route resource. |
bool |
|
|
|
Sets the host attribute to a custom value. If not set, the value is generated by OpenShift. Important
Make sure the value matches your |
string |
|
|
|
Path that the router watches for to route traffic to the service. |
string |
|
|
|
Route TLS parameters. |
object |
|
|
|
Optional value. Cert authority certificate contents. |
string |
|
|
|
Certificate contents. |
string |
|
|
|
CA certificate contents of the final destination. Used by routers for health checks on the secure connection. Important
Provide this file path if you use reencrypt termination. If not specified, the router might provide its own destination CA and perform hostname validation using the short service name ( |
string |
|
|
|
Enable TLS configuration for the host defined with the |
bool |
|
|
|
Indicates the desired behavior for insecure connections to a route. |
string |
|
|
|
Key file contents. |
string |
|
|
|
Specifies TLS termination. |
string |
|
|
|
Wildcard policy for the route. |
string |
|
16.5.2.7. Test namespace values
Use test namespace values to configure parameters that run when tests are initiated with helm test to verify RHDH Helm release.
| Test | Description | Object | Default |
|---|---|---|---|
|
|
Tests pod parameters. |
object |
|
|
|
Enables the test-connection pod used for testing the release using |
bool |
|
|
|
Tests connection pod image registry. |
string |
|
|
|
Test connection pod image repository. Note
The image must contain both the |
string |
|
|
|
Tests connection pod image tag. Note
The image must contain both the |
string |
|
|
|
Injects a fake dynamic plugins Important This value is only used for testing purposes and should not be used in production. |
bool |
|
16.5.2.8. Upstream namespace values
Use the upstream namespace values for configurations that are passed to the upstream Backstage Helm chart.
Specific upstream namespace values are also used in the global configuration of RHDH. Changing these values in the upstream namespace can override the global configuration.
| Key | Description | Type | Default |
|---|---|---|---|
|
|
Upstream Backstage chart configuration. |
object |
OpenShift-compatible settings |
|
|
Ephemeral volume that contains the dynamic plugins installed by the |
object |
|
|
|
Size of the ephemeral volume that contains the dynamic plugins. |
string |
|
|
|
Image used by the |
string |
value of ‘upstream.backstage.image’ |
16.5.2.9. Additional upstream Backstage Chart values
Add the following Backstage Chart values to the upstream namespace to customize your RHDH configuration further.
| Key | Description | Type | Default |
|---|---|---|---|
|
|
Backstage parameters. |
object |
see below |
|
|
Pod assignment affinity. |
object |
|
|
|
Additional custom annotations for the Deployment resource. |
object |
|
|
|
Generates a |
object |
|
|
|
Backstage container command arguments. |
list |
|
|
|
Autoscaling configuration. |
object |
|
|
|
Backstage container command. |
list |
|
|
|
Deployment container ports. |
object |
|
|
|
Container security settings. |
object |
|
|
|
Extra app configuration files to inline into command arguments. |
list |
|
|
|
Deployment sidecars. |
list |
|
|
|
Backstage container environment variables. |
list |
|
|
|
Backstage container environment variables from existing |
list |
|
|
|
Backstage container environment variables from existing secrets. |
list |
|
|
|
Backstage container additional ports. |
list |
|
|
|
Backstage container additional volume mounts. |
list |
|
|
|
Backstage container additional volumes. |
list |
|
|
|
Host Aliases for the pod. |
list |
|
|
|
Backstage image digest. Takes precedence over image tag. Important The image digest must match the repository used for RHDH. |
string |
|
|
|
Specifies the image pull policy. |
string |
|
|
|
Specifies an array of Important Secrets must be manually created in the namespace. |
list |
|
|
|
Backstage image registry. |
string |
|
|
|
Backstage image repository. |
string |
|
|
|
Backstage image tag. Note It is recommended to use immutable tags. |
string |
|
|
|
Backstage container init containers. |
list |
|
|
|
Directory containing the backstage installation. Important
Before using this value, check that there are no restrictions placed on customizing |
string |
|
|
|
Liveness probe. |
object |
|
|
|
Node labels for pod assignment. |
object |
|
|
|
Pod disruption budget configuration. |
object |
|
|
|
Annotations added to the backend deployment pods. |
object |
|
|
|
Labels added to the backend deployment pods. |
object |
|
|
|
Pod security settings. They apply to all containers in the pod. Important Before using this value, check the OpenShift security policy. |
object |
|
|
|
Readiness probe. |
object |
|
|
|
Number of deployment replicas. |
int |
|
|
|
Resource requests and limits. |
object |
|
|
|
Defines the count of deployment revisions to be kept. Note
For GitOps deployment, the count might be set to |
int |
|
|
|
Startup probe. |
object |
|
|
|
Node tolerations for server scheduling to nodes with taints. |
list |
|
|
|
Topology spread constraints for pod assignment. |
list |
|
|
|
Default Kubernetes cluster domain. Important Use this value only if the underlying Backstage chart exposes and uses it. |
string |
|
|
|
Annotations to add to all deployed objects. |
object |
|
|
|
Labels to add to all deployed objects. |
object |
|
|
|
Enables diagnostic mode in the deployment. |
object |
|
|
|
Arguments to override all containers in the deployment. |
list |
|
|
|
Command to override all containers in the deployment. |
list |
|
|
|
Enables diagnostic mode. |
bool |
|
|
|
Array of extra objects to deploy with the release. |
list |
|
|
|
String to fully override |
string |
|
|
|
Ingress parameters. |
object |
|
|
|
Additional annotations for the Ingress resource. |
object |
|
|
|
Name of the |
string |
|
|
|
Enables the creation of the Ingress resource. |
bool |
|
|
|
List of additional hostnames to be covered with this Ingress record, such as |
list |
|
|
|
The TLS configuration for additional hostnames to be covered with this Ingress record. |
list |
|
|
|
Hostname to be used to expose the route to access the Backstage application, such as |
string |
|
|
|
Path to be used to expose the full route to access the Backstage application, such as |
string |
|
|
|
Ingress TLS parameters. |
object |
|
|
|
Enables TLS configuration for the host defined at |
bool |
|
|
|
The name to which the TLS Secret is called. |
string |
|
|
|
Overrides Kubernetes version. |
string |
|
|
|
Metrics configuration. |
object |
|
|
|
Prometheus Operator |
object |
|
|
|
|
object |
|
|
|
Creates a Important Before you enable this value, you must install Prometheus Operator in your cluster. |
bool |
|
|
|
|
string |
|
|
|
Additional |
object |
|
|
|
Important
The |
string |
|
|
|
Important
If you use OpenTelemetry, the port must be explicitly specified. The default port for OpenTelemetry is |
string |
|
|
|
String to partially override |
string |
|
|
|
Additional custom egress rules. |
list |
|
|
|
Denies external connections. Important Do not enable this value when working with external databases. |
bool |
|
|
|
Specifies if a |
bool |
|
|
|
Additional custom Ingress rules. |
list |
|
|
|
Namespace selector label allowed to access the Backstage instance. |
object |
|
|
|
Pod selector label allowed to access the Backstage instance. |
object |
|
|
|
PostgreSQL chart configuration. |
object |
see below |
|
|
PostgreSQL architecture. |
string |
|
|
|
Authentication details of the PostgreSQL database. |
object |
|
|
|
Name of existing secret used for PostgreSQL credentials. |
string |
|
|
|
Password created by custom user. |
string |
|
|
|
The secret keys PostgreSQL looks for to retrieve the relevant password. |
object |
|
|
|
The key in the existing secret where PostgreSQL looks for the admin password. |
string |
|
|
|
The key in the existing secret where PostgreSQL looks for the replication password. |
string |
|
|
|
The key in the existing secret where PostgreSQL looks for the user password. |
string |
|
|
|
Creates a name for a custom user. |
string |
|
|
|
Enables the PostgreSQL helm chart. Note PostgreSQL has many values you can use in RHDH. However, using your own external database is recommended for production. |
bool |
|
|
|
Changes default PostgreSQL image location. |
object |
|
|
|
Service parameters. |
object |
see below |
|
|
Additional custom annotations for Backstage service. |
object |
|
|
|
Backstage service cluster IP. |
string |
|
|
|
Backstage service external traffic policy. |
string |
|
|
|
Extra ports to expose in the Backstage service. Typically used with the sidecar value. |
list |
|
|
|
IP families. |
list |
|
|
|
IP family policy. |
string |
|
|
|
Backstage service Load Balancer IP. |
string |
|
|
|
Load Balancer sources. |
list |
|
|
|
Node port for the Backstage client connections. Note Choose a port between 30000-32767. |
object |
|
|
|
Backstage SVC port for client connections. |
object |
|
|
|
Backstage SVC port name. |
string |
|
|
|
Backstage SVC target port referencing receiving pod container port. |
string |
|
|
|
Controls where client requests go: either the same pod or round-robin. |
string |
|
|
|
Kubernetes service type. |
string |
|
|
|
Service account configuration. |
object |
see below |
|
|
Additional custom annotations for the |
object |
|
|
|
Auto-mounts the service account token in the pod. |
bool |
|
|
|
Enable the creation of a |
bool |
|
|
|
Additional custom labels for the |
object |
|
|
|
Name of the ServiceAccount to use. Note
If you do not set this value and |
string |
|
16.5.2.10. Resource limits for installing Red Hat Developer Hub with the Orchestrator plugin when using Helm
When installing Red Hat Developer Hub (RHDH) with the Orchestrator plugin using Helm, the chart defines default CPU and memory limits for the SonataFlowPlatform component.
These limits are enforced by the cluster so that pods do not exceed their allocated resources.
- Default resource limits
| Resource | Default value |
|---|---|
|
CPU limits |
|
|
Memory limits |
|
You can override these values in any of the following ways:
-
With
values.yaml -
With
--setflags
-
With
Override defaults with
values.yamlas shown in the following example:orchestrator: enabled: true sonataflowPlatform: resources: limits: cpu: "500m" memory: "1Gi"Override with
--setas shown in the following example:$ helm upgrade --install <release_name> openshift-helm-charts/redhat-developer-hub \ --set orchestrator.enabled=true \ --set orchestrator.sonataflowPlatform.resources.requests.cpu=500m \ --set orchestrator.sonataflowPlatform.resources.requests.memory=128Mi \ --set orchestrator.sonataflowPlatform.resources.limits.cpu=1 \ --set orchestrator.sonataflowPlatform.resources.limits.memory=2Gi
NoteThe
--setsetting is applicable only whenorchestrator.enabledistrue. By default, it is set tofalse.
16.5.3. Display a complete list of Orchestrator infrastructure values with Helm CLI
Use the available options to configure Orchestrator infrastructure with Helm Chart: the Helm deployment method specific configuration files.
Procedure
Pull the released RHDH Orchestrator Infrastructure Helm Chart, including all its dependencies:
helm pull redhat-developer-hub-orchestrator-infra --repo https://charts.openshift.io --version 1.10.1
Display the configurable infrastructure values from the chart:
helm show values redhat-developer-hub-orchestrator-infra \ --repo https://charts.openshift.io \ --version 1.10.1
16.5.4. Orchestrator infrastructure Helm Chart values
Use these Helm Chart values to deploy the Orchestrator infrastructure on OpenShift Container Platform.
| Key | Description | Type | Default |
|---|---|---|---|
|
|
Specifies if operator is deployed by the Helm chart. |
bool |
|
|
|
Specifies the namespace where the operator is deployed. |
string |
|
|
|
Specifies the channel of an operator package to subscribe to. |
string |
|
|
|
Specifies if update should be installed automatically. |
string |
|
|
|
Name of the operator package. |
string |
|
|
|
Name of the catalog source. |
string |
|
|
|
Name of the catalog source namespace. |
string |
|
|
|
Specifies the initial version of the operator. Important The version must match the custom resource definitions (CRDs) installed by the chart. |
string |
|
|
|
Specifies if the operator is deployed by the chart. |
bool |
|
|
|
Specifies the namespace where the operator is deployed. |
string |
|
|
|
Specifies the channel of an operator package to subscribe to. |
string |
|
|
|
Specifies if the update is installed automatically. |
string |
|
|
|
Name of the operator package. |
string |
|
|
|
Name of the catalog source. |
string |
|
|
|
Name of the catalog source namespace. |
string |
|
|
|
Specifies if the test pod used for testing the release with helm test is created. |
bool |
|
|
|
Test pod image. |
string |
|





