TLS


https://prometheus.io/docs/prometheus/latest/configuration/https/
https://prometheus.io/docs/guides/tls-encryption/
https://prometheus.io/docs/prometheus/latest/configuration/configuration/#tls_config

1. Important Points#

Prometheus TLS has two common directions:
    inbound:
        users / API clients connect to Prometheus over HTTPS

    outbound:
        Prometheus scrapes HTTPS targets
        Prometheus sends alerts to HTTPS Alertmanager
        Prometheus remote_write to HTTPS endpoint

recommended:
    use --web.config.file for HTTPS server
    use tls_config for scrape / alertmanager / remote_write clients
    keep insecure_skip_verify=false

2. Inbound HTTPS#

web.yml#

tls_server_config:
  cert_file: /etc/prometheus/tls/server.crt
  key_file: /etc/prometheus/tls/server.key
  min_version: TLS12

start#

prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --web.config.file=/etc/prometheus/web.yml

verify#

curl --cacert /etc/ssl/company-ca.pem https://prometheus.example.com:9090/-/ready

3. Outbound TLS#

scrape HTTPS target#

scrape_configs:
  - job_name: order-api
    scheme: https
    static_configs:
      - targets:
          - order-api.example.com:8443
    tls_config:
      ca_file: /etc/prometheus/ca/company-ca.pem
      server_name: order-api.example.com
      min_version: TLS12

alertmanager over HTTPS#

alerting:
  alertmanagers:
    - scheme: https
      static_configs:
        - targets:
            - alertmanager.example.com:9093
      tls_config:
        ca_file: /etc/prometheus/ca/company-ca.pem
        server_name: alertmanager.example.com

4. Java#

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class PrometheusTlsExample {
  public static void main(String[] args) throws Exception {
    // Import company CA into JVM truststore, or use javax.net.ssl.trustStore.
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://prometheus.example.com:9090/api/v1/query?query=up"))
        .GET()
        .build();

    HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println(response.body());
  }
}

5. Python#

pip install requests
import requests

response = requests.get(
    "https://prometheus.example.com:9090/api/v1/query",
    params={"query": "up"},
    verify="/etc/ssl/company-ca.pem",
    timeout=5,
)
response.raise_for_status()
print(response.json())

6. Go#

package main

import (
	"crypto/tls"
	"crypto/x509"
	"io"
	"net/http"
	"os"
)

func main() {
	ca, _ := os.ReadFile("/etc/ssl/company-ca.pem")
	pool := x509.NewCertPool()
	pool.AppendCertsFromPEM(ca)

	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{RootCAs: pool, MinVersion: tls.VersionTLS12},
		},
	}

	resp, err := client.Get("https://prometheus.example.com:9090/api/v1/query?query=up")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	println(string(body))
}

7. Node.js#

import fs from "node:fs";
import https from "node:https";

const options = {
  hostname: "prometheus.example.com",
  port: 9090,
  path: "/api/v1/query?query=up",
  method: "GET",
  ca: fs.readFileSync("/etc/ssl/company-ca.pem"),
  minVersion: "TLSv1.2",
  rejectUnauthorized: true
};

const req = https.request(options, (res) => {
  let body = "";
  res.on("data", (chunk) => {
    body += chunk;
  });
  res.on("end", () => {
    console.log(JSON.parse(body));
  });
});

req.on("error", (err) => {
  throw err;
});
req.end();

8. Production Checklist#

server:
    web.yml managed as secret/config
    key file readable only by prometheus user
    cert hostname matches URL
    min_version TLS12 or higher

client:
    tls_config.ca_file configured
    insecure_skip_verify=false
    server_name set when needed

operations:
    cert reload tested
    expiry alert exists
    Prometheus targets page checked for TLS errors