Commit 8d599bd

Antonio Mika  ·  2026-10-25 16:35:27 -0400 EDT
parent bd8701e
feat(caddy): require a token for metrics routes
5 files changed,  +90, -0
+20, -0
......@@ -8,8 +8,24 @@
88 }
99 }
1010
11+# Metrics routes need ?x-authorization={$METRICS_TOKEN}. An unset token matches
12+# nothing.
13+(metrics_token) {
14+ expression `{http.request.uri.query.x-authorization} == "{$METRICS_TOKEN}" && "{$METRICS_TOKEN}" != ""`
15+}
16+
17+# Apps serve metrics on /_metrics, which only the token-checked routes reach.
18+# Scrapes stay out of the access logs so the token does too.
19+(block_app_metrics) {
20+ @appmetrics path /_metrics /_metrics/*
21+ respond @appmetrics 404
22+ @metricsroutes path /_caddy/metrics /_ssh/metrics /_web/metrics /_imgproxy/metrics /_app/metrics
23+ log_skip @metricsroutes
24+}
25+
1126 # custom domains
1227 :443 {
28+ import block_app_metrics
1329 reverse_proxy web:3000
1430 log {
1531 format append {
......@@ -24,6 +40,7 @@
2440
2541 # subdomains and root app domain
2642 *.{$APP_DOMAIN}, {$APP_DOMAIN} {
43+ import block_app_metrics
2744 reverse_proxy web:3000
2845 log {
2946 format append {
......@@ -61,6 +78,7 @@
6178 @caddymetrics {
6279 host {$APP_DOMAIN}
6380 path /_caddy/metrics
81+ import metrics_token
6482 }
6583
6684 metrics @caddymetrics {
......@@ -70,6 +88,7 @@
7088 @sshmetrics {
7189 host {$APP_DOMAIN}
7290 path /_ssh/metrics
91+ import metrics_token
7392 }
7493
7594 handle @sshmetrics {
......@@ -80,6 +99,7 @@
8099 @webmetrics {
81100 host {$APP_DOMAIN}
82101 path /_web/metrics
102+ import metrics_token
83103 }
84104
85105 handle @webmetrics {
+19, -0
......@@ -4,7 +4,23 @@
44 }
55 }
66
7+# Metrics routes need ?x-authorization={$METRICS_TOKEN}. An unset token matches
8+# nothing.
9+(metrics_token) {
10+ expression `{http.request.uri.query.x-authorization} == "{$METRICS_TOKEN}" && "{$METRICS_TOKEN}" != ""`
11+}
12+
13+# Apps serve metrics on /_metrics, which only the token-checked routes reach.
14+# Scrapes stay out of the access logs so the token does too.
15+(block_app_metrics) {
16+ @appmetrics path /_metrics /_metrics/*
17+ respond @appmetrics 404
18+ @metricsroutes path /_caddy/metrics /_ssh/metrics /_web/metrics /_imgproxy/metrics /_app/metrics
19+ log_skip @metricsroutes
20+}
21+
722 *.pico.sh, pico.sh {
23+ import block_app_metrics
824 @auth {
925 host auth.pico.sh
1026 }
......@@ -16,6 +32,7 @@
1632 @ircmetrics {
1733 host irc.pico.sh
1834 path /_app/metrics
35+ import metrics_token
1936 }
2037
2138 @options {
......@@ -26,6 +43,7 @@
2643 @caddymetrics {
2744 host auth.pico.sh
2845 path /_caddy/metrics
46+ import metrics_token
2947 }
3048
3149 metrics @caddymetrics {
......@@ -35,6 +53,7 @@
3553 @webmetrics {
3654 host auth.pico.sh
3755 path /_web/metrics
56+ import metrics_token
3857 }
3958
4059 handle @webmetrics {
+21, -0
......@@ -14,8 +14,24 @@
1414 }
1515 }
1616
17+# Metrics routes need ?x-authorization={$METRICS_TOKEN}. An unset token matches
18+# nothing.
19+(metrics_token) {
20+ expression `{http.request.uri.query.x-authorization} == "{$METRICS_TOKEN}" && "{$METRICS_TOKEN}" != ""`
21+}
22+
23+# Apps serve metrics on /_metrics, which only the token-checked routes reach.
24+# Scrapes stay out of the access logs so the token does too.
25+(block_app_metrics) {
26+ @appmetrics path /_metrics /_metrics/*
27+ respond @appmetrics 404
28+ @metricsroutes path /_caddy/metrics /_ssh/metrics /_web/metrics /_imgproxy/metrics /_app/metrics
29+ log_skip @metricsroutes
30+}
31+
1732 # custom domains
1833 :443 {
34+ import block_app_metrics
1935 reverse_proxy web:3000
2036 log {
2137 format append {
......@@ -30,6 +46,7 @@
3046
3147 # subdomains and root pgs domain
3248 *.{$APP_DOMAIN}, {$APP_DOMAIN} {
49+ import block_app_metrics
3350 reverse_proxy web:3000
3451 log {
3552 format append {
......@@ -65,6 +82,7 @@
6582 @caddymetrics {
6683 host {$APP_DOMAIN} *.{$APP_DOMAIN}
6784 path /_caddy/metrics
85+ import metrics_token
6886 }
6987
7088 metrics @caddymetrics {
......@@ -74,6 +92,7 @@
7492 @sshmetrics {
7593 host {$APP_DOMAIN} *.{$APP_DOMAIN}
7694 path /_ssh/metrics
95+ import metrics_token
7796 }
7897
7998 handle @sshmetrics {
......@@ -84,6 +103,7 @@
84103 @webmetrics {
85104 host {$APP_DOMAIN} *.{$APP_DOMAIN}
86105 path /_web/metrics
106+ import metrics_token
87107 }
88108
89109 handle @webmetrics {
......@@ -96,6 +116,7 @@
96116 @imgproxymetrics {
97117 host {$APP_DOMAIN} *.{$APP_DOMAIN}
98118 path /_imgproxy/metrics
119+ import metrics_token
99120 }
100121
101122 handle @imgproxymetrics {
+8, -0
......@@ -4,6 +4,12 @@
44 }
55 }
66
7+# Metrics routes need ?x-authorization={$METRICS_TOKEN}. An unset token matches
8+# nothing.
9+(metrics_token) {
10+ expression `{http.request.uri.query.x-authorization} == "{$METRICS_TOKEN}" && "{$METRICS_TOKEN}" != ""`
11+}
12+
713 {$APP_DOMAIN} {
814 reverse_proxy https://pico-docs-prod.pgs.sh {
915 header_up Host pico.sh
......@@ -17,6 +23,7 @@
1723 @caddymetrics {
1824 host {$APP_DOMAIN}
1925 path /_caddy/metrics
26+ import metrics_token
2027 }
2128
2229 metrics @caddymetrics {
......@@ -26,6 +33,7 @@
2633 @sshmetrics {
2734 host {$APP_DOMAIN}
2835 path /_ssh/metrics
36+ import metrics_token
2937 }
3038
3139 handle @sshmetrics {
+22, -0
......@@ -8,8 +8,24 @@
88 }
99 }
1010
11+# Metrics routes need ?x-authorization={$METRICS_TOKEN}. An unset token matches
12+# nothing.
13+(metrics_token) {
14+ expression `{http.request.uri.query.x-authorization} == "{$METRICS_TOKEN}" && "{$METRICS_TOKEN}" != ""`
15+}
16+
17+# Apps serve metrics on /_metrics, which only the token-checked routes reach.
18+# Scrapes stay out of the access logs so the token does too.
19+(block_app_metrics) {
20+ @appmetrics path /_metrics /_metrics/*
21+ respond @appmetrics 404
22+ @metricsroutes path /_caddy/metrics /_ssh/metrics /_web/metrics /_imgproxy/metrics /_app/metrics
23+ log_skip @metricsroutes
24+}
25+
1126 # custom domains
1227 :443 {
28+ import block_app_metrics
1329 reverse_proxy web:3000
1430 log {
1531 format append {
......@@ -24,6 +40,7 @@
2440
2541 # subdomains and root app domain
2642 *.{$APP_DOMAIN}, {$APP_DOMAIN} {
43+ import block_app_metrics
2744 reverse_proxy web:3000
2845 log {
2946 format append {
......@@ -61,6 +78,7 @@
6178 @caddymetrics {
6279 host {$APP_DOMAIN}
6380 path /_caddy/metrics
81+ import metrics_token
6482 }
6583
6684 metrics @caddymetrics {
......@@ -70,6 +88,7 @@
7088 @sshmetrics {
7189 host {$APP_DOMAIN}
7290 path /_ssh/metrics
91+ import metrics_token
7392 }
7493
7594 handle @sshmetrics {
......@@ -80,6 +99,7 @@
8099 @webmetrics {
81100 host {$APP_DOMAIN}
82101 path /_web/metrics
102+ import metrics_token
83103 }
84104
85105 handle @webmetrics {
......@@ -90,6 +110,7 @@
90110 @imgproxymetrics {
91111 host {$APP_DOMAIN}
92112 path /_imgproxy/metrics
113+ import metrics_token
93114 }
94115
95116 handle @imgproxymetrics {
......@@ -126,6 +147,7 @@ monitoring.{$MONITORING_APP_DOMAIN}, prometheus.{$MONITORING_APP_DOMAIN}, grafan
126147 @caddymetrics {
127148 host monitoring.{$MONITORING_APP_DOMAIN}
128149 path /_caddy/metrics
150+ import metrics_token
129151 }
130152
131153 metrics @caddymetrics {