This repository has been archived on 2026-06-16. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
headlamp-polaris-plugin/claude.md
T
Chris Farhood cc3cc81af9 docs: add service proxy RBAC/security requirements and update outdated docs
The README, CLAUDE.md, and artifacthub-pkg.yml all referenced the old
ConfigMap-based data source. Updated to document the actual Kubernetes
service proxy path, the correct RBAC Role/RoleBinding (services/proxy
get), and added sections for token-auth mode, NetworkPolicy, audit
logging, and troubleshooting. Also updated the project structure and
feature descriptions to match the current codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 10:25:59 -05:00

5.1 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

Headlamp plugin that surfaces Fairwinds Polaris audit results inside the Headlamp UI. Queries the Polaris dashboard API via the Kubernetes service proxy (/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json). Target Headlamp ≥ v0.26.

Build & Development Commands

# Install dependencies
npm install

# Build the plugin (standard Headlamp plugin build)
npx @kinvolk/headlamp-plugin build

# Start development mode with hot reload
npx @kinvolk/headlamp-plugin start

# Type-check without emitting
npx tsc --noEmit

# Lint
npx eslint src/

Architecture

src/
├── index.tsx                           # Entry point: registers sidebar entries + routes
├── api/
│   ├── polaris.ts                      # Types (AuditData schema), usePolarisData hook, countResults utilities, refresh settings
│   └── PolarisDataContext.tsx           # React context provider for shared data fetch
└── components/
    ├── DashboardView.tsx                # Overview / Full Audit page (score, check summary, cluster info)
    ├── NamespaceDetailView.tsx          # Per-namespace drill-down with resource table
    ├── DynamicSidebarRegistrar.tsx       # Registers namespace sidebar entries from live audit data
    └── PolarisSettings.tsx              # Plugin settings (refresh interval selector)

Top-level sidebar section at /polaris with sub-routes for full audit (/polaris/full-audit) and per-namespace views (/polaris/ns/:namespace). Data is fetched via ApiProxy.request to the Polaris dashboard service proxy and refreshed on a user-configurable interval (stored in localStorage under polaris-plugin-refresh-interval, default 5 minutes). Score is computed from result counts (pass/total).

Security / RBAC Requirements

The plugin reaches Polaris through the Kubernetes API server's service proxy sub-resource (/api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/...). The Headlamp service account (or the user's bearer token when Headlamp runs in token-auth mode) must be granted:

Verb API Group Resource Resource Name Namespace
get "" (core) services/proxy polaris-dashboard polaris

Minimal RBAC example:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: polaris-proxy-reader
  namespace: polaris
rules:
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["polaris-dashboard"]
    verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: headlamp-polaris-proxy
  namespace: polaris
subjects:
  - kind: ServiceAccount
    name: headlamp            # adjust to match your Headlamp SA
    namespace: kube-system
roleRef:
  kind: Role
  name: polaris-proxy-reader
  apiGroup: rbac.authorization.k8s.io

Additional considerations:

  • NetworkPolicy: If the polaris namespace enforces network policies, allow ingress from the Headlamp pod (or the API server, since it performs the proxy hop) to polaris-dashboard on port 80.
  • Polaris dashboard listen address: The Polaris Helm chart exposes the dashboard on a ClusterIP service (polaris-dashboard:80). If the chart is installed with dashboard.enabled: false, the service won't exist and the proxy request will 404.
  • No write operations: The plugin only performs GET requests through the proxy. No create, update, or delete verbs are required. Do not grant broader service proxy access than get.
  • Token-auth mode: When Headlamp is configured for user-supplied tokens (rather than a fixed service account), each user's own RBAC bindings must include the role above. A 403 from the plugin means the logged-in user lacks the binding.
  • Audit logging: Kubernetes API audit logs will record every proxied request as a get on services/proxy in the polaris namespace. Set an appropriate audit policy level if request volume from the auto-refresh interval is a concern.

Key Constraints

  • Data source: Polaris dashboard API via K8s service proxy. Requires Polaris deployed in the polaris namespace with a polaris-dashboard service. No CRDs, no cluster write operations.
  • UI components: Use only Headlamp-provided components (@kinvolk/headlamp-plugin/lib/CommonComponents). Do not import raw MUI packages. No custom theming.
  • Error handling: Must handle 403 (RBAC denied), 404 (Polaris not installed), malformed JSON, and loading states with distinct visual states.
  • TypeScript strictness: No any, no implicit unknown casting, no dead code, no unused imports.
  • Packaging: @kinvolk/headlamp-plugin is a peer dependency. Do not bundle React or MUI.

MCP Servers

The project has MCP server integrations configured in .mcp.json:

  • Gitea (git.farh.net): Source control via gitea-mcp-server
  • Kubernetes (local): Cluster access via kubernetes-mcp-server
  • Flux (local): Flux Operator access via flux-operator-mcp