← Back to Topics
defensive 3 min read Created: Apr 12, 2026

Restricting Prometheus Endpoint Access

Preventing unauthenticated access to Prometheus metrics that expose cluster topology, pod identities, and internal service addresses

Prometheus ships with no authentication enabled by default. Any pod in the cluster that can reach the Prometheus service can query the full metrics database, retrieve container image inventories, map internal services, and read node details, all without touching the Kubernetes API. Two controls close this gap: enabling authentication on the Prometheus HTTP endpoint and restricting network access via NetworkPolicy.

Enabling Basic Auth via web.config.file

Prometheus supports basic auth through a web configuration file passed via the --web.config.file flag. The file uses bcrypt-hashed passwords.

Generate a bcrypt hash for the password:

python3 -c "import bcrypt; print(bcrypt.hashpw(b'your-password', bcrypt.gensalt(rounds=10)).decode())"
$2b$10$OFBLW.e.aIu5vio8uMN3TO4qXzs9BuIj970yGTmOezdwfVavwhLTW

Create the web configuration file:

basic_auth_users:
  admin: $2b$10$OFBLW.e.aIu5vio8uMN3TO4qXzs9BuIj970yGTmOezdwfVavwhLTW

Store it as a ConfigMap and mount it into the Prometheus pod:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-web-config
  namespace: monitoring
data:
  web.yml: |
    basic_auth_users:
      admin: $2b$10$OFBLW.e.aIu5vio8uMN3TO4qXzs9BuIj970yGTmOezdwfVavwhLTW

Pass the flag and mount the volume in the Prometheus deployment:

containers:
  - name: prometheus-server
    args:
      - --web.config.file=/etc/prometheus/web-config/web.yml
    volumeMounts:
      - name: web-config
        mountPath: /etc/prometheus/web-config
volumes:
  - name: web-config
    configMap:
      name: prometheus-web-config

Once the pod restarts, unauthenticated requests return 401 Unauthorized:

HTTP/1.1 401 Unauthorized

Requests with valid credentials return 200 OK:

HTTP/1.1 200 OK

If using the prometheus-community Helm chart, you may need to configure health probes to use basic auth credentials, as the default probes typically use plain HTTP. Consult the chart documentation for the specific configuration options available in your chart version.

Restricting Access with NetworkPolicy

A NetworkPolicy limits which pods can initiate connections to the Prometheus pod. The following policy denies all ingress to the Prometheus pod except from pods carrying the label role: monitoring-access:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: prometheus-restrict-ingress
  namespace: monitoring
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: prometheus
      app.kubernetes.io/component: server
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: monitoring-access
    ports:
    - protocol: TCP
      port: 9090

To also allow access from a specific namespace such as a dedicated Grafana namespace:

  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: grafana
    - podSelector:
        matchLabels:
          role: monitoring-access
    ports:
    - protocol: TCP
      port: 9090

NetworkPolicy enforcement depends on the CNI plugin. CNIs like Calico, Cilium, Weave Net, and others support NetworkPolicy enforcement.

Limitations

  • Authentication weaknesses: Basic auth credentials are transmitted as base64-encoded strings. Without TLS, credentials are readable on the network. Basic auth also lacks modern security features like multi-factor authentication or token expiration.

  • Credential management: The bcrypt passwords must be stored in ConfigMaps or Secrets. Credential rotation requires updating the ConfigMap and restarting Prometheus pods.

  • Network bypass methods: NetworkPolicy only restricts pod-to-pod traffic. It does not protect against kubectl port-forward (which bypasses the pod network), direct node access, or external service exposure via NodePort, LoadBalancer, or Ingress.

  • Administrative endpoints: Basic auth protects the metrics API, but Prometheus exposes administrative endpoints like /-/reload and /-/quit that may require separate protection.

  • RBAC for port-forward: Restricting the pods/portforward verb via RBAC covers kubectl access. A role that grants read access to pods without allowing port-forward:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: prometheus-read-only
  namespace: monitoring
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list"]

Any attempt to port-forward without the pods/portforward verb is rejected at the API server:

error: pods "prometheus-server-8545d4469-dq4td" is forbidden: User "system:serviceaccount:monitoring:restricted-user" cannot create resource "pods/portforward" in API group "" in the namespace "monitoring"

Impact

An open Prometheus endpoint gives an attacker inside the cluster a full map of namespaces, pod names, container images, service IPs, and node details without making a single Kubernetes API call. Enabling authentication and restricting network access removes that passive reconnaissance path.

Mitigation

  • Enable basic auth or TLS on the Prometheus HTTP endpoint using the --web.config.file flag
  • Apply a NetworkPolicy that restricts ingress to the Prometheus pod to only authorized namespaces or pods, blocking arbitrary workloads from querying the metrics API
  • Treat port-forward access to the Prometheus pod as a sensitive operation subject to the same RBAC controls as other privileged resources