Kyverno Policy Reports logo

Backstage Kyverno Policy Reports Plugin

Created by Terasky

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

Copy
yarn add --cwd packages/app @terasky/backstage-plugin-kyverno-policy-reports

Add the Kyverno tab to the entity page

Edit packages/app/src/components/catalog/EntityPage.tsx

Import the plugin exports

Copy
// 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

Copy
// 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

Copy
<EntityLayout.Route path="/kyverno" title="Kyverno">
  <EntityKyvernoPolicyReportsContent />
</EntityLayout.Route>

Optional show a card on the overview tab

Place the card inside the overview grid

Copy
// 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

Copy
# 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: production

Configure 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

Copy
# 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: false

If your cluster still uses v1alpha2 switch apiVersion to v1alpha2

Copy
kubernetes:
  customResources:
    - group: wgpolicyk8s.io
      apiVersion: v1alpha2
      plural: policyreports
      objectType: PolicyReport
      namespaced: true
    - group: wgpolicyk8s.io
      apiVersion: v1alpha2
      plural: clusterpolicyreports
      objectType: ClusterPolicyReport
      namespaced: false

Make sure the Kubernetes backend is installed

If your app already uses the Kubernetes plugin you can skip this step

Install the backend package

Copy
yarn add --cwd packages/backend @backstage/plugin-kubernetes-backend

New backend system

Register the Kubernetes backend plugin

Copy
// 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

Copy
// 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

Copy
// 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

Copy
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
      - watch

Bind this role to the service account used by your Backstage backend

Copy
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: backstage

Notes

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 8 months ago, and based on the code located here. 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

  • Upgrade Backstage to 1.43.3 for the Kyverno plugin. #89 merged 10 days ago
  • Upgrade Backstage to 1.42.5 for all plugins. #82 merged 27 days ago
  • Upgrade Backstage to 1.40 for all plugins. #54 merged 3 months ago
  • Bump dependencies with backstage cli versions bump. #19 merged 8 months ago

Set up Backstage in minutes with Roadie