question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to use authentication for django-prometheus when deployed to production?

See original GitHub issue

Every path in our urls go through a LoginMiddleware that requires login authentication and redirects the user to /admin/login if not authenticated. The exceptions are the API enpoints which use a token authentication.

This project is deployed in Kubernetes and when the requests are made to /metrics they are redirected to the login page. Since we don’t want to make the /metrics without authentication how can I use an authentication method for django-prometheus in production?

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:2
  • Comments:6

github_iconTop GitHub Comments

2reactions
everspadercommented, Apr 26, 2022

Found a final solution. I added a custom handle for the /metrics in my middleware’s process_request() method like this:

def process_request(self, request):
    path = request.path_info.lstrip('/')

    # Handle '/metrics' endpoint to use a separate authentication backend
    # rather than JWT token or admin login
    if 'metrics' in path:
        if 'Authorization' in request.headers:
            auth = request.headers['Authorization']
            if auth.startswith('Basic '):
                auth = auth.split('Basic ')[1]
                auth = base64.b64decode(auth).decode('utf-8')
                username, password = auth.split(':')
                user = authenticate(request=request, username=username, password=password)

                if user:
                    return self.get_response(request)

        return redirect(settings.LOGIN_URL)

This will force the request to /metrics to authenticate so the first method attempted will be my custom authentication backend, that needs to be placed as first on the list in settings.py. The final backends.py looks like this:

from django.conf import settings
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User


class MetricsAuthBackend(BaseBackend):
    """
    Custom authentication backend for the /metrics endpoint only.

    This backend will allow prometheus to authenticate with a
    username and password in the headers rather than with a
    JWT token.
    """

    def authenticate(self, request, username=None, password=None):
        """
        Authenticate a user based on the username and password.
        """

        if '/metrics' in request.path:
            if username == settings.PROMETHEUS_USERNAME:
                try:
                    user = User.objects.get(username=username)

                    if user:
                        pwd_valid = check_password(password, user.password)
                        if pwd_valid:
                            return user
                        raise Exception('Invalid password')

                except User.DoesNotExist:
                    return None

        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
0reactions
cristianratcommented, Sep 12, 2022

I also came across this issue, looked at various options and in the end my solution is this: In the ingress, instead of allowing /metrics, I forward it to a “blackhole” nginx service with nothing in it so /metrics is a 404 via ingress But prometheus hits the pod directly (and not via ingress), so can parse the metrics correctly I don’t want the world to know I have /metrics, and also wanted to avoid all the extra setup of passwords and so on My ingress looks like so

...
...
      - path: /metrics 
        pathType: Prefix
        backend:
          service:
            name: nginx-blackhole-service
            port:
              number: 80         
...
...

Where the blackhole service is a basic service with nginx and nothing else (ie: /metrics would be a 404, since it has nothing)

Read more comments on GitHub >

github_iconTop Results From Across the Web

Using Prometheus for monitoring Django applications in ...
Enable Django monitoring ... This is the most important while monitoring our Django application. For that purpose, we will use django-prometheus.
Read more >
Prometheus + Grafana in Django - Karan Churi - Medium
Once things are deployed in production environment, in-spite of rigorous ... In this tutorial we'll be using Prometheus & Grafana for our ...
Read more >
Creating Custom Metrics with Prometheus - Monterail
For that purpose, we can use a default Django User model and also use the TokenAuthentication provided by the Django REST Frameworks library....
Read more >
Instrumenting Django with Prometheus and StatsD
Here statsd_exporter comes into play. It uses the same UDP protocol as StatsD server and exports StatsD-style metrics as Prometheus metrics, so ...
Read more >
python - How to setup prometheus on a Django project with an ...
I don't want to make the /metrics without authentication so how can I properly set up prometheus with Django using an authentication method?...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found