Kyverno Policy Reports capture the results of policy checks inside your Kubernetes clusters. They record which resources passed or failed specific rules. They update as your cluster changes. For engineers, this gives a clear way to see the current compliance state without scraping logs or switching tools.
The Kyverno Policy Reports Backstage plugin brings those reports into the software catalog view you already use. On a service page you can see summary counts for pass fail warn skip and error. You can drill into a resource to understand what triggered a result. You can open the policy YAML in a viewer. You can copy it or download it for a quick review. This helps platform and security teams spot patterns across clusters. It helps service owners fix issues near the code and ownership context. Common uses include checking release readiness, tracking recurring violations, and giving developers fast feedback during migrations or policy rollouts.
Companies are adopting similar Backstage views for Kyverno results. VELUX published an open approach that integrates Kyverno policy reports into Backstage. In their words, “The Backstage policy reporter plugin integrates Policy Reporter with Backstage to provide a clear and detailed view of Kyverno Policies applied to your workloads.” See their repo at.
Installation Instructions
These instructions apply to self-hosted Backstage only.
Install the frontend package
yarn add --cwd packages/app @terasky/backstage-plugin-kyverno-policy-reportsAdd the Kyverno tab to the entity page
Edit packages/app/src/components/catalog/EntityPage.tsx
Import the plugin exports
// packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import { EntityLayout } from '@backstage/plugin-catalog';
import {
  EntityKyvernoPolicyReportsContent,
  isKyvernoPolicyReportsAvailable,
} from '@terasky/backstage-plugin-kyverno-policy-reports';
import { EntitySwitch, EntitySwitchCase } from '@backstage/plugin-catalog';Add a Kyverno route to the entity layout
// Inside your <EntityLayout>
<EntityLayout.Route path="/kyverno" title="Kyverno">
  <EntitySwitch>
    <EntitySwitchCase if={isKyvernoPolicyReportsAvailable}>
      <EntityKyvernoPolicyReportsContent />
    </EntitySwitchCase>
  </EntitySwitch>
</EntityLayout.Route>If your app does not use EntitySwitch yet, you can render the content directly
<EntityLayout.Route path="/kyverno" title="Kyverno">
  <EntityKyvernoPolicyReportsContent />
</EntityLayout.Route>Optional show a card on the overview tab
Place the card inside the overview grid
// packages/app/src/components/catalog/EntityPage.tsx
import React from 'react';
import Grid from '@material-ui/core/Grid';
import {
  KyvernoPolicyReportsCard,
  isKyvernoPolicyReportsAvailable,
} from '@terasky/backstage-plugin-kyverno-policy-reports';
import { EntitySwitch, EntitySwitchCase } from '@backstage/plugin-catalog';
// Inside your Overview content
<Grid container spacing={3}>
  <EntitySwitch>
    <EntitySwitchCase if={isKyvernoPolicyReportsAvailable}>
      <Grid item xs={12}>
        <KyvernoPolicyReportsCard />
      </Grid>
    </EntitySwitchCase>
  </EntitySwitch>
</Grid>Add Kubernetes annotations to your entities
The plugin resolves reports for a component through Kubernetes annotations. Add at least the Kubernetes id. Add namespace if you need it
# catalog-info.yaml
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: my-service
  annotations:
    backstage.io/kubernetes-id: my-service
    backstage.io/kubernetes-namespace: my-namespace
spec:
  type: service
  owner: team-a
  lifecycle: productionConfigure the Kubernetes plugin to read PolicyReport resources
Add the PolicyReport custom resources to your Kubernetes config. Use the version that matches your cluster. v1beta1 is common today
# app-config.yaml
kubernetes:
  # your cluster definitions go here
  # ...
  customResources:
    - group: wgpolicyk8s.io
      apiVersion: v1beta1
      plural: policyreports
      objectType: PolicyReport
      namespaced: true
    - group: wgpolicyk8s.io
      apiVersion: v1beta1
      plural: clusterpolicyreports
      objectType: ClusterPolicyReport
      namespaced: falseIf your cluster still uses v1alpha2 switch apiVersion to v1alpha2
kubernetes:
  customResources:
    - group: wgpolicyk8s.io
      apiVersion: v1alpha2
      plural: policyreports
      objectType: PolicyReport
      namespaced: true
    - group: wgpolicyk8s.io
      apiVersion: v1alpha2
      plural: clusterpolicyreports
      objectType: ClusterPolicyReport
      namespaced: falseMake sure the Kubernetes backend is installed
If your app already uses the Kubernetes plugin you can skip this step
Install the backend package
yarn add --cwd packages/backend @backstage/plugin-kubernetes-backendNew backend system
Register the Kubernetes backend plugin
// packages/backend/src/index.ts
import { createBackend } from '@backstage/backend-defaults';
import { kubernetesPlugin } from '@backstage/plugin-kubernetes-backend';
const backend = createBackend();
backend.add(kubernetesPlugin());
export default backend;Old backend system
Create the plugin wireup
// packages/backend/src/plugins/kubernetes.ts
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { createRouter } from '@backstage/plugin-kubernetes-backend';
export default async function createPlugin(env: PluginEnvironment): Promise<Router> {
  return await createRouter({
    logger: env.logger,
    config: env.config,
    discovery: env.discovery,
    tokenManager: env.tokenManager,
    httpAuth: env.httpAuth,
    permissions: env.permissions,
  });
}Register the router
// packages/backend/src/index.ts
import kubernetes from './plugins/kubernetes';
// inside main bootstrap where apiRouter is created
apiRouter.use('/kubernetes', await kubernetes(env));Grant the backend access to your cluster
The Kubernetes plugin needs credentials that can read PolicyReport and ClusterPolicyReport. Grant get list watch on those resources. Use your normal cluster onboarding for the Backstage service account
Example cluster role
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: backstage-kubernetes-read
rules:
  - apiGroups:
      - ''
    resources:
      - pods
      - services
      - deployments
      - replicasets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - wgpolicyk8s.io
    resources:
      - policyreports
      - clusterpolicyreports
    verbs:
      - get
      - list
      - watchBind this role to the service account used by your Backstage backend
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: backstage-kubernetes-read-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: backstage-kubernetes-read
subjects:
  - kind: ServiceAccount
    name: backstage
    namespace: backstageNotes
This plugin is frontend only. There is no separate plugin backend to install. It reads data through the Kubernetes backend you already run in Backstage
Export names can change between versions. If the imports shown do not exist in your version check the package exports. Common exports include a content component for the entity page and a small card for the overview tab
Changelog
This changelog is produced from commits made to the Kyverno Policy Reports plugin since 9 months ago. It may not contain information about all commits. Releases and version bumps are intentionally omitted. This changelog is generated by AI.
Breaking changes
- Kyverno Policy Reports plugin now uses a backend plugin instead of calling the Kubernetes plugin from the frontend. You must install and configure the Kyverno backend plugin. Review permissions in your backend app. #89 merged 10 days ago
Features
- Add MCP Action support in the Kyverno Policy Reports plugin. #89 merged 10 days ago
- Add support for the new Frontend System in Backstage for the Kyverno plugin. #83 merged 26 days ago
Maintenance
Set up Backstage in minutes with Roadie
Focus on using Backstage, rather than building and maintaining it.
