Kuadrant Plugin Installation Guide¶
This guide covers installing the Kuadrant plugins into an existing Red Hat Developer Hub (RHDH) or Backstage instance.
For plugin development, see the main README.
Packages¶
| Plugin | Package | Type |
|---|---|---|
| Frontend | @kuadrant/kuadrant-backstage-plugin-frontend | Frontend |
| Backend | @kuadrant/kuadrant-backstage-plugin-backend-dynamic | Backend |
Why Two Packages?¶
We publish only two packages that work for both dynamic (RHDH) and static (Backstage) deployments:
-
Frontend plugin: Published directly from
plugins/kuadrant. Frontend plugins are bundled by the app's webpack at build time, so the dynamic plugin system simply needs the source to be available. Thedist-scalprum/assets for dynamic loading are included alongside the standard build output in the same package. -
Backend plugin: Published from
plugins/kuadrant-backend/dist-dynamic(not the root). Backend plugins run in Node.js and are loaded at runtime, not bundled by webpack. For dynamic loading to work, the backend code must be pre-bundled as a self-contained module with all dependencies embedded. The@janus-idp/cli export-dynamiccommand generates this indist-dynamic/with its ownpackage.json. This is a separate package because the dependency structure differs from the source plugin.
In short: frontend plugins are bundled by the consuming app (so source is fine), while backend plugins must be pre-bundled for runtime loading (so we publish the generated dist-dynamic output).
Prerequisites¶
Kubernetes Cluster with Kuadrant¶
The plugins require a Kubernetes cluster with Kuadrant installed. You can either:
- Use the development setup (recommended for testing): This creates a kind cluster with:
- Kuadrant operator
- Gateway API CRDs v1.2.0
- Istio service mesh
- APIProduct and APIKey CRDs
- Demo resources (toystore)
-
RHDH service account with proper RBAC
-
Use an existing cluster with:
- Kuadrant operator installed
- Gateway API CRDs
- Developer Portal controller (included in Kuadrant)
Service Account Setup¶
Create a service account with permissions to manage Kuadrant resources:
apiVersion: v1
kind: Namespace
metadata:
name: rhdh
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: rhdh-kuadrant
namespace: rhdh
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: rhdh-kuadrant
rules:
- apiGroups: ["devportal.kuadrant.io"]
resources: ["apiproducts", "apikeys"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["kuadrant.io"]
resources: ["planpolicies"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list", "create", "delete"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: rhdh-kuadrant
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: rhdh-kuadrant
subjects:
- kind: ServiceAccount
name: rhdh-kuadrant
namespace: rhdh
Generate a long-lived token:
Installation on Red Hat Developer Hub (RHDH)¶
This section covers installing the plugins using rhdh-local for local development with Docker Compose. For production RHDH deployments, see Deploying to Production RHDH.
1. Configure Dynamic Plugins¶
Add the plugins to configs/dynamic-plugins/dynamic-plugins.override.yaml:
includes:
- dynamic-plugins.default.yaml
plugins:
# Kuadrant Backend
- package: "@kuadrant/kuadrant-backstage-plugin-backend-dynamic"
disabled: false
integrity: <sha512-integrity-hash>
# Kuadrant Frontend
- package: "@kuadrant/kuadrant-backstage-plugin-frontend"
integrity: <sha512-integrity-hash>
disabled: false
pluginConfig:
dynamicPlugins:
frontend:
internal.plugin-kuadrant:
appIcons:
- name: kuadrantIcon
importName: KuadrantIcon
dynamicRoutes:
- path: /kuadrant
importName: KuadrantPage
menuItem:
icon: kuadrantIcon
text: Kuadrant
- path: /kuadrant/api-products/:namespace/:name
importName: ApiProductDetailPage
- path: /kuadrant/api-keys/:namespace/:name
importName: ApiKeyDetailPage
mountPoints:
- mountPoint: entity.page.api/cards
importName: EntityKuadrantApiKeyManagementTab
config:
layout:
gridColumn: "1 / -1"
if:
allOf:
- isKind: api
- mountPoint: entity.page.api/cards
importName: EntityKuadrantApiProductInfoContent
config:
layout:
gridColumn: "1 / -1"
if:
allOf:
- isKind: api
To get the integrity hash:
npm view @kuadrant/kuadrant-backstage-plugin-frontend dist.integrity
npm view @kuadrant/kuadrant-backstage-plugin-backend-dynamic dist.integrity
2. Configure Kubernetes Access¶
Add to configs/app-config/app-config.yaml:
kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- name: production
url: https://host.docker.internal:<port>
authProvider: serviceAccount
serviceAccountToken: <your-token>
skipTLSVerify: true
Note: Use
host.docker.internalto access the host machine's kind cluster from Docker. Get the port withkubectl cluster-info.
3. Configure RBAC¶
Add to configs/app-config/app-config.yaml:
permission:
enabled: true
rbac:
policies-csv-file: /opt/app-root/src/configs/rbac-policy.csv
policyFileReload: true
Create configs/rbac-policy.csv with the RBAC policy content.
4. Start RHDH¶
Visit http://localhost:7007/kuadrant
Deploying to Production RHDH¶
For production RHDH deployments (Operator or Helm), the configuration is the same but stored in Kubernetes ConfigMaps instead of local files:
| rhdh-local File | Production RHDH |
|---|---|
configs/dynamic-plugins/dynamic-plugins.override.yaml |
ConfigMap referenced by spec.application.dynamicPluginsConfigMapName in Backstage CR |
configs/app-config/app-config.yaml |
ConfigMap referenced by spec.application.appConfig in Backstage CR |
configs/rbac-policy.csv |
ConfigMap mounted as a volume |
Key differences:
-
Dynamic Plugins ConfigMap:
-
Backstage CR reference:
-
Kubernetes credentials as Secret:
Reference in Backstage CR:
-
Cluster URL: Use the actual cluster API URL instead of
host.docker.internal. -
TLS: Set
skipTLSVerify: falseand configure proper TLS certificates. -
Verify installation at
<rhdh-url>/api/dynamic-plugins-info/loaded-plugins.
Installation on Backstage¶
This section covers installing the plugins on a standard Backstage instance.
Important: RBAC Plugin Requirement¶
The Kuadrant backend plugin includes an RBAC module that integrates with the Backstage permission framework. Standard Backstage does not include the RBAC plugin that RHDH provides.
To use the RBAC module on Backstage, you need to install the community RBAC plugin:
yarn --cwd packages/backend add @backstage-community/plugin-rbac-backend @backstage-community/plugin-rbac-node
If you don't need RBAC, you can skip the RBAC module - the core plugin functionality works without it.
1. Install Dependencies¶
Frontend (packages/app):
Backend (packages/backend):
2. Register Backend Plugin¶
Edit packages/backend/src/index.ts:
import { createBackend } from '@backstage/backend-defaults';
import {
kuadrantPlugin,
catalogModuleApiProductEntityProvider,
} from '@kuadrant/kuadrant-backstage-plugin-backend-dynamic';
const backend = createBackend();
// ... other plugins ...
// Kuadrant plugin
backend.add(kuadrantPlugin);
backend.add(catalogModuleApiProductEntityProvider);
backend.start();
3. Register Frontend Routes¶
Edit packages/app/src/App.tsx:
import {
KuadrantPage,
ApiProductsPage,
ApiProductDetailPage,
ApiKeysPage,
ApiKeyDetailPage,
} from '@kuadrant/kuadrant-backstage-plugin-frontend';
// In your routes:
const routes = (
<FlatRoutes>
{/* ... other routes ... */}
<Route path="/kuadrant" element={<KuadrantPage />} />
<Route path="/kuadrant/api-products" element={<ApiProductsPage />} />
<Route path="/kuadrant/api-products/:namespace/:name" element={<ApiProductDetailPage />} />
<Route path="/kuadrant/api-keys" element={<ApiKeysPage />} />
<Route path="/kuadrant/api-keys/:namespace/:name" element={<ApiKeyDetailPage />} />
</FlatRoutes>
);
4. Add Sidebar Navigation (Optional)¶
Edit packages/app/src/components/Root/Root.tsx:
import ExtensionIcon from '@material-ui/icons/Extension';
// In your sidebar:
<SidebarItem icon={ExtensionIcon} to="kuadrant" text="Kuadrant" />
5. Configure Kubernetes Access¶
Add to app-config.yaml:
kubernetes:
serviceLocatorMethod:
type: multiTenant
clusterLocatorMethods:
- type: config
clusters:
- name: production
url: https://127.0.0.1:<port>
authProvider: serviceAccount
serviceAccountToken: <your-token>
skipTLSVerify: true
6. Configure Catalog Rules¶
Add to app-config.yaml:
7. Configure Permissions¶
Add to app-config.yaml:
8. Start Backstage¶
Visit http://localhost:3000/kuadrant
RBAC Policy¶
Example rbac-policy.csv for Kuadrant permissions:
# api consumer: browses apis, requests access
p, role:default/api-consumer, kuadrant.apiproduct.read.all, read, allow
p, role:default/api-consumer, kuadrant.apiproduct.list, read, allow
p, role:default/api-consumer, kuadrant.apikey.create, create, allow, apiproduct:*/*
p, role:default/api-consumer, kuadrant.apikey.read.own, read, allow
p, role:default/api-consumer, kuadrant.apikey.update.own, update, allow
p, role:default/api-consumer, kuadrant.apikey.delete.own, delete, allow
p, role:default/api-consumer, catalog.entity.read, read, allow
# api owner: publishes apis they own, approves requests for their apis
p, role:default/api-owner, kuadrant.planpolicy.read, read, allow
p, role:default/api-owner, kuadrant.planpolicy.list, read, allow
p, role:default/api-owner, kuadrant.apiproduct.create, create, allow
p, role:default/api-owner, kuadrant.apiproduct.read.all, read, allow
p, role:default/api-owner, kuadrant.apiproduct.update.own, update, allow
p, role:default/api-owner, kuadrant.apiproduct.delete.own, delete, allow
p, role:default/api-owner, kuadrant.apiproduct.list, read, allow
p, role:default/api-owner, kuadrant.apikey.create, create, allow, apiproduct:*/*
p, role:default/api-owner, kuadrant.apikey.read.own, read, allow
p, role:default/api-owner, kuadrant.apikey.update.own, update, allow
p, role:default/api-owner, kuadrant.apikey.delete.own, delete, allow
p, role:default/api-owner, kuadrant.apikey.approve, update, allow
p, role:default/api-owner, catalog.entity.read, read, allow
# api admin: platform engineers who manage all api products
p, role:default/api-admin, kuadrant.planpolicy.read, read, allow
p, role:default/api-admin, kuadrant.planpolicy.list, read, allow
p, role:default/api-admin, kuadrant.apiproduct.create, create, allow
p, role:default/api-admin, kuadrant.apiproduct.read.all, read, allow
p, role:default/api-admin, kuadrant.apiproduct.update.all, update, allow
p, role:default/api-admin, kuadrant.apiproduct.delete.all, delete, allow
p, role:default/api-admin, kuadrant.apiproduct.list, read, allow
p, role:default/api-admin, kuadrant.apikey.create, create, allow, apiproduct:*/*
p, role:default/api-admin, kuadrant.apikey.read.all, read, allow
p, role:default/api-admin, kuadrant.apikey.update.all, update, allow
p, role:default/api-admin, kuadrant.apikey.delete.all, delete, allow
p, role:default/api-admin, kuadrant.apikey.approve, update, allow
p, role:default/api-admin, catalog.entity.read, read, allow
# assign groups to roles
g, group:default/api-consumers, role:default/api-consumer
g, group:default/api-owners, role:default/api-owner
g, group:default/api-admins, role:default/api-admin
Exposed Modules¶
Frontend¶
| Import Name | Description |
|---|---|
KuadrantPage |
Main page with API products and approval queue |
ApiProductsPage |
API products list page |
ApiProductDetailPage |
Single API product detail page |
ApiKeysPage |
API keys list page |
ApiKeyDetailPage |
Single API key detail page |
EntityKuadrantApiAccessCard |
API key request card for entity overview |
EntityKuadrantApiKeyManagementTab |
Full API keys management tab |
EntityKuadrantApiKeysContent |
API keys content component |
EntityKuadrantApiProductInfoContent |
APIProduct details tab |
KuadrantIcon |
Kuadrant logo icon for navigation |
Backend¶
| Export | Description |
|---|---|
kuadrantPlugin |
Main backend plugin with HTTP router |
catalogModuleApiProductEntityProvider |
Catalog entity provider for APIProduct sync |
rbacModule |
RBAC module for permission integration (requires RBAC plugin) |
Verification¶
After installation:
- Navigate to
/kuadrant- you should see the main Kuadrant page - Check the catalog for APIProduct entities synced from Kubernetes
- Navigate to an API entity and verify Kuadrant components appear
Troubleshooting¶
APIProduct entities not appearing¶
- Check backend logs for entity provider sync messages
- Verify Kubernetes connectivity
- Ensure APIProduct CRDs exist in your cluster
- Check catalog rules allow APIProduct kind
API key requests failing¶
- Verify Kubernetes write permissions for the service account
- Check backend logs for detailed error messages
- Ensure the target namespace exists and is accessible
Related Documentation¶
- RBAC Permissions - Detailed permissions guide
- Kuadrant Docs - Kuadrant documentation
- RHDH Local - RHDH local development