If your engineering teams waste time context-switching between Red Hat OpenShift, Argo CD, Tekton, and Quay, your platform needs a unified developer portal. Building on the previous article in this series, this guide shows platform engineers how to deploy and configure Red Hat Developer Hub to bring those tools into a single pane of glass.
The friction of tool switching
Consider what happens during a standard release: starting the pipeline initiates a PipelineRun
. On successful completion of the PipelineRun
, the image tag in the deployment manifest updates with the latest image pushed to the image registry. As soon as the deployment manifest updates, the Argo CD reconciliation loop updates the deployment with the latest image tag. Finally, a new pod starts up with the latest image. Across all of this, reviewing a single PipelineRun
requires switching between the OpenShift console, the Pipelines tab in the OpenShift web console, the Argo CD console, and the image registry.
Imagine pushing a code fix, then having to monitor Tekton logs in one tab, check Quay image tags in another, and watch Argo CD sync status in a third. That constant task-switching disrupts developer flow. For new team members, navigating four separate web consoles creates significant cognitive friction and slows down onboarding. This is where platform engineering steps in—reducing cognitive load by abstracting infrastructure complexity so developers can focus on writing code.
The solution: Red Hat Developer Hub
To overcome this overhead, an internal developer portal provides a thin management layer on top of these key components that brings everything into one place. As a CNCF graduated project, Backstage has emerged as a leading open source framework for internal developer portals. Red Hat Developer Hub is Red Hat's build of Backstage, enabling simple integration with Argo CD, Red Hat OpenShift Pipelines, Quay, and OpenShift clusters. Developer Hub unifies pipeline runs, deployment health, and container image tags into one view so developers don't have to switch across 4 different web consoles.
Red Hat Developer Hub includes preconfigured software templates (often called golden paths) that give developers ready-to-use repositories with automated CI/CD pipelines already configured. Developers starting a new project can quickly bootstrap their environment from a simple self-service form.
Overview of this guide
In this article, you will set up a Red Hat Developer Hub instance to aggregate status from your OpenShift pipeline, Argo CD, and Quay, preparing your environment to visualize the entire CI/CD workflow. A follow-up article will cover translating the simple Go project into a Backstage software template to create a Git repository with built-in CI/CD elements.
This quick start walks through setting up Red Hat Developer Hub along with the required dynamic plug-ins for Quay, Red Hat OpenShift Pipelines, Argo CD, and Kubernetes. Once a platform engineer completes this initial configuration, developers can immediately start onboarding projects through standardized platform templates.
Architecture overview
Red Hat Developer Hub is the abstraction layer that acts as an interface between CI/CD components and provides a self-service layer. Each component connects to Red Hat Developer Hub through plug-ins. The CI/CD pipeline from part 1 remains the same: push triggers → build triggers → deploy.
This guide focuses on the platform engineer setup, with the developer workflow covered in a follow-up article. As a one-time setup, a platform engineer installs Red Hat Developer Hub, configures plug-ins, and writes the golden path template. The next part in this series will demonstrate how developers scaffold components from the template to view CI, CD, images, pods, and topology directly within the Red Hat Developer Hub console.
Prerequisites
Before you begin, complete part 1 of this series. You should have:
- OpenShift cluster (Red Hat OpenShift Service on AWS (ROSA) or self-managed) with
cluster-admin
access - Red Hat OpenShift Pipelines Operator installed with Pipelines-as-Code configured
- Red Hat OpenShift GitOps Operator installed with an Argo CD instance
- GitHub account and organization
Part 1 used Docker Hub as the container registry. Part 2 switches to Quay.io because Red Hat Developer Hub provides a stable Quay plug-in. This plug-in displays image tags, vulnerabilities, and manifest details directly in the developer portal. If you followed part 1 with Docker Hub, you'll need to update your secret to use Quay.io credentials instead. No pipeline changes are required.
This guide uses simplified cluster permissions for proof-of-concept setup; for production deployments, consult the Red Hat Developer Hub documentation to configure RBAC with least privilege.
Platform engineer sets up Red Hat Developer Hub
This section covers setting up Red Hat Developer Hub and its required plug-ins from the perspective of a platform engineer.
Step 1: Install the Red Hat Developer Hub operator
Install the Red Hat Developer Hub operator from OperatorHub in the OpenShift web console. Navigate to Operators → OperatorHub, search for "Red Hat Developer Hub," and select Install. Accept the default settings—the operator installs into the rhdh-operator
namespace.
Step 2: Create secrets
Because Red Hat Developer Hub acts as an integration layer across components like Pipelines, Argo CD applications, and pods, create a secret containing the required credentials. Authenticating users and scaffolding repositories from the template also requires configuring Git credentials.
First, retrieve the default service account token. Red Hat Developer Hub uses this token to query the cluster for pods, deployments, pipeline runs, and routes:
$ cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: default-token
namespace: rhdh-operator
annotations:
kubernetes.io/service-account.name: default
type: kubernetes.io/service-account-token
$ oc create -f secret.yaml
$ oc get secret default-token -o go-template='{{.data.token | base64decode}}' -n rhdh-operator
Next, create a GitHub OAuth app so developers can log in to Red Hat Developer Hub with their GitHub identity. Navigate to GitHub → Settings → Developer settings → OAuth Apps and create a new application. Set both the Homepage URL and Authorization callback URL to your Red Hat Developer Hub route URL. You'll get this URL after deploying Red Hat Developer Hub in step 6—you might need to come back and update the OAuth app at that point.
Now create the secret with all the required credentials:
$ oc create secret generic my-rhdh-secrets \
--from-literal=GITHUB_CLIENT_ID= \
--from-literal=GITHUB_CLIENT_SECRET= \
--from-literal=GITHUB_TOKEN= \
--from-literal=GITHUB_URL=https://github.com \
--from-literal=GITHUB_ORG= \
--from-literal=K8S_SA_TOKEN= \
--from-literal=ARGOCD_ADMIN_USER=admin \
--from-literal=ARGOCD_ADMIN_PASSWORD= \
-n rhdh-operator
The following table explains each variable:
| Variable | Purpose |
|---|---|
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | GitHub OAuth app credentials for the Developer Hub login |
GITHUB_TOKEN | Personal access token for Red Hat Developer Hub to read repos and org membership |
GITHUB_ORG | Your GitHub organization name |
K8S_SA_TOKEN | Service account token so Red Hat Developer Hub can query the Kubernetes API for pods, deployments, and pipeline runs |
ARGOCD_ADMIN_USER / ARGOCD_ADMIN_PASSWORD | Argo CD credentials so Red Hat Developer Hub can create the application, display sync status and history |
Step 3: Create the app config
This ConfigMap serves as Red Hat Developer Hub's main app-config
file to configure authentication, catalog providers, Kubernetes cluster access, Argo CD integration, and the Quay registry integration. Create a file called my-rhdh-app-config.yaml
with the following content:
kind: ConfigMap
apiVersion: v1
metadata:
name: my-rhdh-app-config
namespace: rhdh-operator
data:
default.app-config.yaml: |
app:
baseUrl: https://
auth:
environment: production
providers:
github:
production:
clientId: ${GITHUB_CLIENT_ID}
clientSecret: ${GITHUB_CLIENT_SECRET}
signIn:
resolvers:
- resolver: usernameMatchingUserEntityName
dangerouslyAllowSignInWithoutUserInCatalog: true
signInPage: github
backend:
auth:
externalAccess:
- options:
secret:
subject: legacy-default-config
type: legacy
baseUrl: https://
cors:
origin: https://
catalog:
rules:
- allow: [Component, System, API, Template, Location, Resource, User, Group, Domain]
providers:
githubOrg:
id: githuborg
githubUrl: "${GITHUB_URL}"
orgs: [ "${GITHUB_ORG}" ]
schedule:
frequency:
minutes: 60
initialDelay:
seconds: 15
timeout:
minutes: 15
integrations:
github:
- host: github.com
token: ${GITHUB_TOKEN}
kubernetes:
serviceLocatorMethod:
type: 'multiTenant'
clusterLocatorMethods:
- type: 'config'
clusters:
- url: https://api.:443
name: ocp-cluster-test
authProvider: 'serviceAccount'
skipTLSVerify: true
serviceAccountToken: ${K8S_SA_TOKEN}
customResources:
- group: 'route.openshift.io'
apiVersion: 'v1'
plural: 'routes'
- group: 'tekton.dev'
apiVersion: 'v1'
plural: 'pipelineruns'
- group: 'tekton.dev'
apiVersion: 'v1'
plural: 'taskruns'
argocd:
waitCycles: 25
appLocatorMethods:
- type: 'config'
instances:
- name: argocd1
url: https://openshift-gitops-server-openshift-gitops
username: ${ARGOCD_ADMIN_USER}
password: ${ARGOCD_ADMIN_PASSWORD}
proxy:
endpoints:
'/quay/api':
target: 'https://quay.io'
headers:
X-Requested-With: 'XMLHttpRequest'
changeOrigin: true
secure: true
permission:
enabled: true
rbac:
policies-csv-file: /opt/app-root/src/rbac-policies.csv
policyFileReload: true
admin:
users:
- name: user:default/
quay:
uiUrl: 'https://quay.io'
Here is what each top-level section does:
- auth + signInPage: Configures GitHub OAuth login.
- catalog.providers.githubOrg: Auto-discovers users and groups from your GitHub organization and imports them into the Red Hat Developer Hub catalog every 60 minutes.
- kubernetes: Connects Red Hat Developer Hub to your OpenShift cluster using the service account token. The critical
customResources
block tells the Kubernetes plug-in to also fetch OpenShift routes, TektonPipelineRun
resources, andTaskRun
resources, which powers the Tekton and Topology plug-ins. - argocd: Points to your OpenShift GitOps instance. The
argocd1
name must match what you use in the Argo CD scaffolder plug-in (step 8). - proxy.endpoints./quay/api: Proxies Quay.io API calls through the Red Hat Developer Hub back end, so the Quay plug-in can fetch image tags and manifests.
- permission + rbac: Enables role-based access control with policies loaded from a CSV file mounted into the container (step 5).
Replace all placeholder values—
,
,
, and
—with your actual values.
Note
This configuration assumes a public Quay.io repository. The Quay proxy has no Authorization
header configured. If you use a private Quay repository, add Authorization: 'Bearer '
under the headers section of the Quay proxy endpoint.
Step 4: Configure dynamic plug-ins
Red Hat Developer Hub supports dynamic plug-ins, allowing you to add integrations at runtime without rebuilding container images. This ConfigMap tells Red Hat Developer Hub which plug-ins to enable. Create a file called dynamic-plugins-rhdh.yaml
:
kind: ConfigMap
apiVersion: v1
metadata:
name: dynamic-plugins-rhdh
namespace: rhdh-operator
data:
dynamic-plugins.yaml: |
includes:
- dynamic-plugins.default.yaml
plugins:
- package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic'
disabled: false
- package: './dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-dynamic'
disabled: false
- package: './dynamic-plugins/dist/backstage-plugin-scaffolder-backend-module-github-dynamic'
disabled: false
- package: './dynamic-plugins/dist/backstage-community-plugin-rbac'
disabled: false
- package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-tekton:bs_1.45.3__3.33.3'
disabled: false
- package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/backstage-community-plugin-quay:bs_1.45.3__1.28.1'
disabled: false
- package: './dynamic-plugins/dist/backstage-plugin-kubernetes'
disabled: false
- package: './dynamic-plugins/dist/backstage-plugin-kubernetes-backend-dynamic'
disabled: false
- package: './dynamic-plugins/dist/backstage-community-plugin-topology'
disabled: false
- package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-scaffolder-backend-argocd:bs_1.45.3__1.8.1'
disabled: false
- package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-backstage-plugin-argo-cd-backend:bs_1.45.3__4.6.0'
disabled: false
- package: 'oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/roadiehq-backstage-plugin-argo-cd:bs_1.45.3__2.12.4'
disabled: false
pluginConfig:
dynamicPlugins:
frontend:
roadiehq.backstage-plugin-argo-cd:
mountPoints:
- config:
if:
allOf:
- isArgocdAvailable
layout:
gridColumnEnd:
lg: span 8
xs: span 12
importName: EntityArgoCDOverviewCard
mountPoint: entity.page.overview/cards
- config:
if:
allOf:
- isArgocdAvailable
layout:
gridColumn: 1 / -1
importName: EntityArgoCDHistoryCard
mountPoint: entity.page.cd/cards
The following table summarizes what each plug-in group provides in Red Hat Developer Hub:
| Plug-in group | What it shows in Red Hat Developer Hub |
|---|---|
| GitHub (3 plug-ins) | Catalog discovery from GitHub, scaffolding repos, org user/group sync |
| RBAC | Permission management UI |
| Tekton | Pipeline runs and task logs in the CI tab |
| Quay | Container image tags, digests, and layers in the Image Registry tab |
| Kubernetes + Topology | Pod details and visual topology graph in dedicated tabs |
| Argo CD / Roadie (3 plug-ins) | Sync status, health, and history cards in the CD tab and overview page |
The Argo CD front-end plug-in configuration at the bottom mounts 2 cards: EntityArgoCDOverviewCard
on the component overview page (so developers see sync status at a glance) and EntityArgoCDHistoryCard
on the dedicated CD tab (for full sync history).
Step 5: Configure RBAC
RBAC controls what authenticated users can see and do in Red Hat Developer Hub. Without these policies, users might see empty tabs or get permission errors even though the plug-ins are correctly configured. Create a file called rbac-policies.csv
:
p, role:default/team-member, quay.view.read, read, allow
p, role:default/team-member, catalog-entity, read, allow
p, role:default/team-member, catalog.entity.create, create, allow
p, role:default/team-member, catalog.entity.refresh, update, allow
p, role:default/team-member, catalog.entity.delete, delete, allow
p, role:default/team-member, catalog.location.create, create, allow
p, role:default/team-member, catalog.location.read, read, allow
p, role:default/team-member, scaffolder-template, read, allow
p, role:default/team-member, scaffolder-template, create, allow
p, role:default/team-member, scaffolder-action, use, allow
p, role:default/team-member, scaffolder.task.create, create, allow
p, role:default/team-member, scaffolder.task.cancel, use, allow
p, role:default/team-member, scaffolder.task.read, read, allow
p, role:default/team-member, kubernetes.proxy, use, allow
p, role:default/team-member, ocm.entity.read, read, allow
p, role:default/team-member, ocm.cluster.read, read, allow
p, role:default/team-member, topology.view.read, read, allow
p, role:default/team-member, policy-entity, read, allow
g, user:default/rishabhsvats, role:default/team-member
if you want to assign the role to already existing group
#g, group:default/developer, role:default/team-member
This policy file defines a single role role:default/team-member
with permissions across 6 areas:
- Catalog: Read, create, and refresh catalog entities and locations
- Scaffolder: Read templates and execute scaffolder actions (use the golden path template)
- Kubernetes proxy: Access pod details, logs, and resource status through Red Hat Developer Hub
- Open Cluster Management (OCM): Read cluster information
- Topology: View the topology graph
- Policy: Read RBAC policies
The last line (g, group:default/developer, role:default/team-member
) assigns this role to all members of your GitHub organization. Replace rishabhsvats
with your GitHub username. Create the ConfigMap from this file:
$ oc create configmap rbac-policies \
--from-file=rbac-policies.csv \
-n rhdh-operator
Step 6: Deploy Red Hat Developer Hub
With the ConfigMaps and secret in place, apply them and create the Backstage custom resource. First, apply the configuration:
$ oc apply -f my-rhdh-app-config.yaml -n rhdh-operator
$ oc apply -f dynamic-plugins-rhdh.yaml -n rhdh-operator
Now create a file called my-rhdh-cr.yaml
with the Backstage custom resource:
apiVersion: rhdh.redhat.com/v1alpha5
kind: Backstage
metadata:
name: my-rhdh-custom-resource
namespace: rhdh-operator
spec:
application:
appConfig:
mountPath: /opt/app-root/src
configMaps:
- name: my-rhdh-app-config
extraEnvs:
secrets:
- name: my-rhdh-secrets
dynamicPluginsConfigMapName: dynamic-plugins-rhdh
extraFiles:
mountPath: /opt/app-root/src
configMaps:
- name: rbac-policies
route:
enabled: true
database:
enableLocalDb: true
Apply it:
$ oc apply -f my-rhdh-cr.yaml -n rhdh-operator
Here is what each field in the CR does:
- appConfig.configMaps: Mounts the app configuration from step 3 into the Red Hat Developer Hub container.
- extraEnvs.secrets: Injects the secret values from step 2 as environment variables. The
${GITHUB_TOKEN}
,${K8S_SA_TOKEN}
, and other references in the app config resolve these. - dynamicPluginsConfigMapName: Loads the dynamic plug-in configuration from step 4.
- extraFiles.configMaps: Mounts the RBAC CSV file from step 5 into the container at
/opt/app-root/src/rbac-policies.csv
. - route.enabled:
true
: Creates an OpenShift route so Red Hat Developer Hub is accessible externally. - enableLocalDb:
true
: Uses a local PostgreSQL database. For production deployments, consider using an external database.
Wait for the Red Hat Developer Hub pod to come up:
$ oc get pods -n rhdh-operator -w
Once the pod is running, retrieve the route URL:
$ oc get route -n rhdh-operator
Copy this URL—this is your
. If you haven't already, go back and update the app config (step 3) and your GitHub OAuth app (step 2) with this URL, then re-apply:
$ oc apply -f my-rhdh-app-config.yaml -n rhdh-operator
The Red Hat Developer Hub pod will restart automatically to pick up the updated configuration.
Step 7: Configure service account permissions
Red Hat Developer Hub's service account needs read access to the namespaces it monitors. Without this, the Kubernetes, Tekton, and Argo CD plug-ins will show empty tabs.
$ oc adm policy add-role-to-user view \
system:serviceaccount:rhdh-operator:default \
-n openshift-gitops
$ oc adm policy add-role-to-user view \
system:serviceaccount:rhdh-operator:default \
-n pipeline-test
The first command grants read access to the openshift-gitops
namespace so Red Hat Developer Hub can query Argo CD application state. The second grants access to the pipeline-test
namespace where your workloads and pipeline runs live.
If you didn't label the application namespace in part 1, label it now so Argo CD can manage resources in it:
$ oc label namespace pipeline-test \
argocd.argoproj.io/managed-by=openshift-gitops
Your portal foundation is officially ready. With the core operators, secrets, and plug-ins wired together, you have a live Developer Hub instance connected directly to OpenShift, Tekton, Argo CD, and Quay.io.
Verification and next steps
Before moving to part 3, log in to your new Red Hat Developer Hub portal using your GitHub account and verify that you are able to access Catalog -> Register Existing Component
. In the next article, we will transform our Go project into a standardized software template for instant developer self-service and automated repository creation.
Facts Only
* The friction arises from switching between OpenShift console, Pipelines tab, Argo CD console, and the image registry during a standard release workflow.
* Red Hat Developer Hub integrates Red Hat OpenShift Pipelines, Argo CD, Quay, and OpenShift clusters into a single view.
* Setup requires installing the Red Hat Developer Hub operator from OperatorHub.
* Secrets are created for authentication, including GitHub credentials, Argo CD credentials, and Kubernetes Service Account tokens.
* A main configuration file (ConfigMap) is used to define authentication, catalog providers, and integrations with GitHub, Kubernetes, Argo CD, and Quay.io.
* Dynamic plug-ins are configured via a separate ConfigMap to enable integration with specific components like Tekton and Quay.
* RBAC policies are defined in a CSV file and applied to grant permissions across the Hub features.
* The setup results in an accessible route for the Developer Hub instance.
* Service account permissions are configured to allow the Hub to read data from Argo CD and pipeline namespaces.
