Skip to content

feat: support METRICS_JWT_JWKS for metrics endpoint auth - #2172

Open
Larslllllll wants to merge 1 commit into
supabase:mainfrom
Larslllllll:feat/metrics-jwt-jwks
Open

Larslllllll wants to merge 1 commit into
supabase:mainfrom
Larslllllll:feat/metrics-jwt-jwks

Conversation

@Larslllllll

Copy link
Copy Markdown

Summary

Allow the metrics endpoint (/metrics) to authenticate using JWKS (ES256/RS256/EdDSA asymmetric keys) as an alternative to METRICS_JWT_SECRET (HS256 symmetric key).

Problem

Currently the metrics endpoint in realtime hard-requires METRICS_JWT_SECRET (HS256 symmetric) and crashes at boot if it is missing:

# config/runtime.exs (PR #1729, v2.103+)
metrics_jwt_secret =
  if config_env() == :test do
    System.get_env("METRICS_JWT_SECRET")
  else
    System.fetch_env!("METRICS_JWT_SECRET")  # crashes on missing
  end

Meanwhile, the WebSocket/API endpoint already supports API_JWT_JWKS for both ES256 and HS256 verification. This creates an inconsistency:

endpoint auth variable formats
API API_JWT_JWKS ES256 + HS256
metrics METRICS_JWT_SECRET HS256 only

In self-hosted setups migrating to asymmetric signing (ES256 via GOTRUE_JWT_KEYS), operators still have to maintain a separate HS256 symmetric key just for realtime metrics — even though JWT_JWKS already contains the same HS256 key material plus the ES256 public keys.

Solution

  1. config/runtime.exs: The METRICS_JWT_SECRET now falls back to API_JWT_JWKS when not set, enabling asymmetric key support for metrics.

  2. lib/realtime_web/router.ex: New check_auth_metrics plug that reads both metrics_jwt_secret and metrics_jwt_jwks, passing the JWKS to the JWT verification layer.

  3. ENVS.md: Document the new METRICS_JWT_JWKS environment variable.

  4. Tests: Added JWKS authentication tests for the metrics endpoint.

Benefit

  • One less env var for self-hosted operators to configure
  • Consistent auth across all realtime endpoints
  • Reduced surface area of symmetric key references (better security posture when migrating to asymmetric signing)

Testing

Three new tests added to metrics_controller_test.exs:

  • GET /metrics accepts ES256 JWT from JWKS
  • GET /metrics/:region accepts ES256 JWT from JWKS
  • GET /metrics rejects JWT with wrong signature

Closes #1951

Allow the metrics endpoint to authenticate using JWKS (ES256/RS256/EdDSA)
as an alternative to METRICS_JWT_SECRET. This enables self-hosted setups
to use asymmetric JWT verification for metrics without maintaining a
separate HS256 symmetric key.

The metrics pipeline now falls back to API_JWT_JWKS when METRICS_JWT_SECRET
is not set, and supports both symmetric and asymmetric key verification.

Closes supabase#1951
@mandar1045

Copy link
Copy Markdown
Contributor

Looking at it from the architecture side, I don’t think adding JWKS auth to /metrics is the right approach.

Prometheus usually uses a static secret or network-level protection. Using API_JWT_JWKS for an internal /metrics endpoint also feels like mixing user auth with internal stuff.

If the goal is just to avoid extra env vars in self-hosted setups, I think making METRICS_JWT_SECRET optional in config/runtime.exs would be much simpler. For example, we could just disable /metrics when it’s not set instead of crashing on boot. That solves the problem without adding the extra JWKS complexity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: support JWT_JWKS for metrics endpoint auth (as alternative to METRICS_JWT_SECRET)

2 participants