NorthScope is a read-only Kubernetes topology debugger. Security is especially important because the application runs inside a cluster and watches cluster resources.
NorthScope is currently pre-beta and requires Kubernetes 1.20 or newer. Security fixes target the main branch and the latest published container image.
Please do not open a public issue for security vulnerabilities.
Use GitHub private vulnerability reporting if it is enabled for this repository. If private reporting is not available, contact the maintainer listed in MAINTAINERS.md before sharing public details.
Helpful report details:
- Affected version or commit
- Deployment method and Helm values, if relevant
- Impacted Kubernetes permissions or exposed data
- Reproduction steps
- Suggested mitigation, if known
NorthScope should remain read-only:
- Kubernetes RBAC should use only
get,list, andwatch. - The application should not exec into Pods, proxy traffic, mutate resources, or create CRDs.
- The UI should not expose secrets or sensitive object data.
- The container should run as non-root with a minimal runtime image.
- The UI, API, and WebSocket should require a sign-in unless an operator explicitly disables it.
Changes that weaken this model require explicit maintainer review.
The Helm chart enables NorthScope's built-in sign-in by default. It is a single shared login meant to keep cluster topology away from anyone who can merely reach the Service; it is not a multi-user identity system.
- Credentials come from files in the directory passed with
-auth-dir:username,password, andsession-key. The chart mounts them read-only from a Secret. NorthScope never reads Secrets through the Kubernetes API, and its RBAC grants no Secret access. - Without
-auth-dir, NorthScope runs without authentication and logs a warning at startup. With-auth-dirset, a missing or empty file, or a session key shorter than 32 characters, stops startup. - Usernames and passwords are compared as SHA-256 digests in constant time. Failed sign-ins return one generic message.
- Failed sign-ins are throttled per client: 5 attempts, then one more every 30 seconds. Behind a proxy on a private, shared, or loopback address, the client is the last
X-Forwarded-Forentry (appended by the proxy itself) orX-Real-IP, and all clients of that proxy share a wider budget of 50 failed attempts plus one every 2 seconds, so forged forwarded addresses cannot bypass the limit. - Sessions are stateless HMAC-SHA256-signed cookies (
HttpOnly,SameSite=Lax,Path=/, 12 hours by default via-auth-session-ttl).Secureis set for HTTPS requests orX-Forwarded-Proto: https; set-auth-cookie-secure(auth.cookieSecure) totrueto always require it. Open WebSocket streams are closed when their session expires. - Signing out clears the cookie in that browser only. To revoke every session, change the password or the session key and restart NorthScope; the signing key is derived from both.
- Sign-in and sign-out forms reject cross-site posts. Every response sets
Content-Security-Policy(same-origin resources only,frame-ancestors 'none'),X-Frame-Options: DENY,X-Content-Type-Options: nosniff, andReferrer-Policy: no-referrer. /healthz,/readyz, and/metricsstay open for probes and Prometheus./readyz?verboselists resource names only. Set-auth-protect-metrics(auth.protectMetrics) to require a session for/metricswhen nothing scrapes it.
Built-in sign-in does not replace TLS. Serve NorthScope over HTTPS whenever traffic leaves a trusted network, and use an identity-aware proxy or SSO gateway in front of it when you need per-user identities or audit trails.
The default Helm chart creates read-only cluster-wide permissions because traffic paths commonly cross namespaces and Node placement is part of the topology. Set watchNamespace to use a namespaced Role for namespaced resources while retaining a small ClusterRole for Nodes and class metadata.
| API group | Resources | Purpose |
|---|---|---|
| core | nodes | Backend Node placement |
| core | pods, services, endpoints | Backend Pod readiness, Service routing, and legacy Endpoints fallback |
| discovery.k8s.io | endpointslices | EndpointSlice and selector-less Service resolution |
| networking.k8s.io | ingressclasses, ingresses | Ingress ownership, hosts, paths, and controller mapping |
| gateway.networking.k8s.io | gatewayclasses, gateways, grpcroutes, httproutes, tcproutes, tlsroutes, udproutes, referencegrants | Optional Gateway API topology and cross-namespace backend authorization when the CRDs are installed |
| cis.f5.com | ingresslinks, virtualservers, transportservers | Optional F5 CIS topology when the CRDs are installed |
The chart does not grant access to Secrets, ConfigMaps, Events, Pod logs, Pod exec, or resource mutation verbs such as create, update, patch, or delete.
Gateway API and F5 discovery can be disabled independently. Their optional RBAC rules and runtime watches are omitted when disabled.
If you disable chart-managed RBAC with rbac.create=false, provide an equivalent read-only role before starting NorthScope.
NorthScope can display internal topology metadata, including:
- hostnames and Ingress paths
- Service names and ports
- Pod names, readiness state, and Pod IPs
- Node names
- EndpointSlice and legacy Endpoints addresses, including external endpoint IPs for selector-less Services
- Gateway API and F5 CIS object names and selected routing fields when those CRDs are present
Published topology snapshots contain only resources connected to supported Ingress, Gateway API, or F5 traffic roots. In default mode, inventory counters remain cluster-wide. With watchNamespace set, namespaced counters and routes are limited to that namespace while Node and class metadata remain cluster-scoped.
NorthScope also exposes /metrics with operational counters and gauges such as readiness, snapshot size, build errors, build duration, websocket clients, and per-resource watch health. /api/status and the UI health banner include the latest Kubernetes API error for degraded resources, which can name the NorthScope ServiceAccount and the API server address; /api/status requires a session when authentication is enabled. /metrics stays open by default, so keep it behind the same trusted boundary as the UI or set auth.protectMetrics.
Route health labels are derived from Kubernetes object status, backend references, ports, readiness, and endpoint data. They are not active network probes and must not be treated as proof that an application or external load balancer is reachable.
Run NorthScope behind trusted internal access controls. Keep the built-in sign-in enabled, and if NorthScope is exposed through Ingress, configure TLS and consider an identity-aware proxy at the ingress controller or platform edge. See Production Access for examples.
Recommended production settings:
- use a private/internal hostname
- keep
auth.enabled=true, and enable TLS before exposing the UI outside a trusted network - set
auth.cookieSecure=truewhen every browser reaches NorthScope over HTTPS - manage credentials with
auth.existingSecretwhen the chart is rendered byhelm templateor a GitOps tool - enable
networkPolicywhere your CNI enforces NetworkPolicy - enable
podDisruptionBudgetwhen running more than one replica - keep
securityContextandpodSecurityContexthardened - pin chart versions for production changes and verify the chart checksum from the GitHub release
- verify the published container provenance attestation before promotion