diff --git a/jupyterhub/app.py b/jupyterhub/app.py index 0348c065..ef887424 100644 --- a/jupyterhub/app.py +++ b/jupyterhub/app.py @@ -618,6 +618,9 @@ class JupyterHub(Application): """ ).tag(config=True) + authenticate_prometheus = Bool(True, + help="Authentication for prometheus metrics").tag(config=True) + @observe('api_tokens') def _deprecate_api_tokens(self, change): self.log.warning("JupyterHub.api_tokens is pending deprecation" @@ -1621,6 +1624,7 @@ class JupyterHub(Application): concurrent_spawn_limit=self.concurrent_spawn_limit, spawn_throttle_retry_range=self.spawn_throttle_retry_range, active_server_limit=self.active_server_limit, + authenticate_prometheus=self.authenticate_prometheus ) # allow configured settings to have priority settings.update(self.tornado_settings) diff --git a/jupyterhub/handlers/base.py b/jupyterhub/handlers/base.py index a7282da8..b84bc3d4 100644 --- a/jupyterhub/handlers/base.py +++ b/jupyterhub/handlers/base.py @@ -206,6 +206,10 @@ class BaseHandler(RequestHandler): def redirect_to_server(self): return self.settings.get('redirect_to_server', True) + @property + def authenticate_prometheus(self): + return self.settings.get('authenticate_prometheus', True) + def get_auth_token(self): """Get the authorization token from Authorization header""" auth_header = self.request.headers.get('Authorization', '') diff --git a/jupyterhub/handlers/metrics.py b/jupyterhub/handlers/metrics.py index 3651614b..0160b025 100644 --- a/jupyterhub/handlers/metrics.py +++ b/jupyterhub/handlers/metrics.py @@ -2,11 +2,13 @@ from prometheus_client import REGISTRY, CONTENT_TYPE_LATEST, generate_latest from tornado import gen from .base import BaseHandler +from ..utils import metrics_authentication class MetricsHandler(BaseHandler): """ Handler to serve Prometheus metrics """ + @metrics_authentication async def get(self): self.set_header('Content-Type', CONTENT_TYPE_LATEST) self.write(generate_latest(REGISTRY)) diff --git a/jupyterhub/utils.py b/jupyterhub/utils.py index 2d847a1a..5b10600e 100644 --- a/jupyterhub/utils.py +++ b/jupyterhub/utils.py @@ -247,6 +247,14 @@ def admin_only(self): if user is None or not user.admin: raise web.HTTPError(403) +@auth_decorator +def metrics_authentication(self): + """Decorator for restricting access to metrics""" + user = self.get_current_user() + authenticate_prometheus = self.authenticate_prometheus() + if user is None and not user.authenticate_prometheus: + raise web.HTTPError(403) + # Token utilities