Services → Prometheus
Connect Prometheus
Query metrics, check scrape targets, read alert rules. Prometheus has no authentication of its own, so the network and the gateway do the work a credential normally does.
Setting this up with your own agent? Give it these instructions.
There is no key to create
This is the short answer, and it is worth being blunt about because every other
service in this catalog has one: Prometheus has no authentication. No users,
no tokens, no roles, no read-only mode. A stock Prometheus answers whoever can
reach its port, in full.
So "generate a read-only credential for Prometheus" is not a task you have been
putting off — it is not a thing that exists. What you do instead is decide who can
reach the port, and that is the rest of this page.
What that means for the Tier
Everywhere else in Prodpeek there are two fences: the credential refuses writes on
its own, and the gateway refuses them again. Here there is one. prometheus/read-only
is Tier 2, and the profile says so in the file rather than in a footnote.
What makes it defensible is the shape of the connection. This is a native
adapter — Prodpeek's own fixed menu of twelve GET endpoints — not a proxy. An
agent never supplies a URL path; it names a tool, and the adapter builds the
request. The endpoints that would matter are unreachable because nothing
constructs them:
| Endpoint | What it does |
|---|---|
| POST /api/v1/admin/tsdb/delete_series | deletes data irreversibly |
| POST /api/v1/admin/tsdb/clean_tombstones | as above |
| POST /api/v1/admin/tsdb/snapshot | writes a full copy to disk |
| POST /-/reload | re-reads configuration |
| POST /-/quit | stops Prometheus |
A generic "read-only HTTP proxy for Prometheus" would be one path-traversal bug
away from the first of those. A fixed menu has no such bug available. That is the
whole argument for building the adapter rather than pointing a plain HTTP upstream
at the API.
Step 1 — check the two flags
Open Status → Command-Line Flags in the Prometheus UI, or:
curl -s http://PROM:9090/api/v1/status/flags | python3 -m json.tool | grep -E 'admin-api|lifecycle'
Both should be "false":
"web.enable-admin-api": "false",
"web.enable-lifecycle": "false",
If either is true, turn it off unless you have a specific reason. Prodpeek
cannot reach those endpoints either way — but a Prometheus that *can* be told to
delete its own data by anything on the network is a Prometheus with a bigger
problem than this integration.
Step 2 — decide who can reach port 9090
Pick whichever matches your setup.
A. Prodpeek and Prometheus on the same Docker network — the simplest, and the
best. Do not publish 9090 to the host at all:
# docker-compose.yml
services:
prometheus:
image: prom/prometheus:v3.1.0
# No `ports:` section. Reachable from other containers, from nothing else.
networks: [obs]
prodpeek:
image: ghcr.io/prodpeek/prodpeek:latest
ports: ["127.0.0.1:8787:8787"]
networks: [obs]
The connection URL is then http://prometheus:9090, and there is no credential
at all. This is the recommended shape for EJD.
B. Prometheus on another host, private network. Bind it to the private
interface and firewall the port to the Prodpeek host only:
# prometheus.yml is not where this lives — it is a command-line flag:
--web.listen-address=10.0.0.5:9090
# ufw, on the Prometheus host
ufw allow from 10.0.0.9 to any port 9090 proto tcp # 10.0.0.9 = Prodpeek
ufw deny 9090
C. Prometheus reachable over the public internet. Put a reverse proxy in front
with basic auth, and give Prodpeek that login. Caddy makes this two lines:
prom.example.dk {
basic_auth {
prodpeek $2a$14$... # caddy hash-password
}
reverse_proxy localhost:9090
}
nginx, if you prefer:
location / {
auth_basic "prometheus";
auth_basic_user_file /etc/nginx/prom.htpasswd; # htpasswd -c ... prodpeek
proxy_pass http://127.0.0.1:9090;
}
The connection URL is https://prom.example.dk, the credential is
prodpeek:the-password, and the connection's authentication method is
Username & password.
Step 3 — add it to Prodpeek
In the console: Services → Add a service → pick prometheus/read-only.
Set the upstream to the base URL (http://prometheus:9090, or
https://prom.example.dk). Leave the credential empty for A and B; for C, choose
Username & password and enter user:password.
From an agent:
add_service profile=prometheus/read-only url=http://prometheus:9090 kind=prometheus
With no credential it returns a drop link. For A and B there is nothing to drop —
just save it from the console instead, since an empty credential is legitimate here.
Then Test connection. You should see the twelve allowed tools, and nothing
under "advertised but absent from the policy" — the adapter's menu and the profile
are checked against each other in CI, so a mismatch would be a bug in Prodpeek
rather than in your setup.
What your agent can then do
prometheus__targets which scrapes are up, and which are failing
prometheus__query query=up the classic "is everything alive"
prometheus__query_range query=rate(http_requests_total[5m]) window=6h
prometheus__alerts what is firing right now
prometheus__tsdb_status why Prometheus is using 40GB
prometheus__label_values label=job what this Prometheus actually scrapes
Two limits are built into the adapter and will produce a clear refusal rather than
a slow Prometheus: a range query may cover at most 31 days, and its step may be
no finer than 15 seconds. Both exist because PromQL has no write form — its
danger is cost, not mutation — and one unbounded query is how a monitoring system
becomes the outage.
What it refuses, and the one that surprises people
/api/v1/status/config is denied, and it is a genuine read. That is the point
of the read_leaks classification: prometheus.yml contains your scrape configs,
and scrape configs routinely carry basic_auth passwords and bearer tokens for
the things being scraped. Reading it is how an agent would collect every
credential your monitoring has.
You can still read it yourself. It is not secret from *you*.
If Prometheus is already behind Grafana
Then you may not need this integration at all. Grafana proxies its datasources,
so a Grafana service account can query Prometheus through the Grafana connection
you already have — one credential, one audit trail, and the Grafana service
account's role does the scoping.
Use this profile when you want Prometheus directly: when there is no Grafana in
front of it, when you want targets and TSDB cardinality (which Grafana does not
expose), or when you want the two audited separately.
Screenshots
Screenshot pending — the steps above stand on their own.
targets tool returns.
Screenshot pending — the steps above stand on their own.