Nginx + tinyauth: A Lightweight Solution for Application Authentication


Nginx + tinyauth: A Lightweight Solution for Application Authentication

steveiliop56/tinyauth

2025-08-10

tinyauth is a simple, lightweight authentication middleware designed to protect your web applications with a basic login screen. The project leverages Nginx and Go to act as a reverse proxy, sitting in front of your applications. Its main purpose is to handle the authentication layer, allowing your main application to focus on its core business logic.

This is particularly useful in scenarios like

Protecting internal dashboards or admin panels
You can place tinyauth in front of a dashboard that doesn't have its own authentication, like a Grafana or Kibana instance.

Securing development or staging environments
Quickly add a login screen to your pre-production sites without changing the application's code.

Simple, single-user access
It's perfect for situations where you just need a single username and password to grant access to a small team or yourself.

The key benefit here is separation of concerns. By outsourcing authentication to tinyauth, your application becomes simpler and more secure, as it no longer needs to handle login forms, password hashing, or session management.

The implementation involves two main parts
configuring tinyauth itself and then configuring Nginx to use it.

First, you need to set up the tinyauth service. The easiest way is to use a configuration file, typically named config.yaml. Here, you'll define the port it listens on and the credentials for the login screen.

Here’s a basic config.yaml example

listen: ":8081"
user: "admin"
pass: "securepassword"

listen
This is the address tinyauth will listen on. You'll point Nginx to this address.

user
The username for the login screen.

pass
The password for the login screen. You should use a strong, unique password.

Next, you need to tell Nginx to act as a reverse proxy. When a user tries to access your application, Nginx will first forward the request to tinyauth. If tinyauth authenticates the user, it will then pass the request back to Nginx, which will send it to your application. If authentication fails, tinyauth will handle the login screen.

Here is a sample Nginx configuration snippet. You would place this inside your server block.

location / {
    # Forward the request to the tinyauth service
    auth_request /auth;
    error_page 401 = @login;

    # If authenticated, pass the request to your application
    proxy_pass http://your_application_service;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

location = /auth {
    # This location handles the authentication check
    internal;
    proxy_pass http://127.0.0.1:8081; # This should be the tinyauth service address
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
    proxy_set_header X-Original-URI $request_uri;
}

location @login {
    # This location redirects to the tinyauth login page
    return 302 http://127.0.0.1:8081;
}

auth_request /auth;
This is the key directive. It tells Nginx to make a subrequest to the /auth location. Nginx will only proceed with the main request if the subrequest returns a 200 OK status code.

proxy_pass http://127.0.0.1:8081;
This forwards the authentication subrequest to the tinyauth service running on port 8081.

error_page 401 = @login;
If tinyauth returns a 401 Unauthorized status code, Nginx redirects the user to the @login location.

return 302 http://127.0.0.1:8081;
This location handles the redirect to the tinyauth login page, which will serve the login form.

Let's imagine you have a simple web application running on http://localhost:3000. We want to protect it using tinyauth.

First, let's create the config.yaml for our tinyauth service.

config.yaml

listen: ":8081"
user: "dev-user"
pass: "supersecretpass"

Next, you'd run the tinyauth application. If you have the Go code, you would compile and run it. You can also run it in a Docker container.

go run main.go --config config.yaml

Now, tinyauth is running and listening for requests on http://localhost:8081.

Now, let's configure our Nginx server block to use tinyauth to protect our application.

nginx.conf

server {
    listen 80;
    server_name my-protected-app.com;

    # This is the main application that we are protecting
    upstream my_app_backend {
        server localhost:3000;
    }

    location / {
        auth_request /auth;
        error_page 401 = @login;

        proxy_pass http://my_app_backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # This location is for the authentication check
    location = /auth {
        internal;
        proxy_pass http://localhost:8081; # tinyauth service
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Original-URI $request_uri;
    }

    # This location handles the redirect to the login page
    location @login {
        return 302 http://localhost:8081;
    }
}

With this setup, if a user tries to access http://my-protected-app.com, Nginx will first check with tinyauth on port 8081. If the user isn't logged in, they will be redirected to the login page served by tinyauth. After a successful login, tinyauth will return a 200 OK, and Nginx will then proxy the request to your application running on port 3000.


steveiliop56/tinyauth




The Future of Cybersecurity: A Deep Dive into the Pentagi AI Framework

Think of Pentagi as a "Digital Red Team" colleague. Instead of just running a static script, it uses AI to "think, " pivot


Mastering Redis with the Go-Redis Library

As a software engineer, you'll often encounter situations where you need a fast, reliable, and scalable way to handle data


NetBird Unpacked: Implementing High-Performance Mesh VPNs for Distributed Teams

As a software engineer, you've probably dealt with the headache of VPNs, firewall rules, and the "it works on my machine but not the staging server" connectivity issues


Automate SSL and Reverse Proxies with Nginx Proxy Manager: A Docker-Compose Walkthrough

Nginx Proxy Manager is a powerful tool built on Nginx that drastically simplifies the management of reverse proxies. From a software engineer's perspective


Infisical: Secure Secret Management for Developers

Imagine you're building an application. Your code needs to talk to databases, external APIs, and various services. Each of these interactions often requires sensitive credentials like API keys


Go-WhatsApp-Web-Multidevice: Efficient WhatsApp Integration for Software Engineers

go-whatsapp-web-multidevice (GOWA) is essentially a WhatsApp REST API client built with Golang. In simpler terms, it allows your applications to programmatically interact with WhatsApp


LiveKit: Simplifying WebRTC for Humans and AI

Hey there! Let's talk about livekit/livekit, a cool open-source project that's super useful for building real-time communication apps


From Manual to Automated: Leveraging autobrr/qui for Multi-Instance Torrent Orchestration

autobrr/qui is exactly that kind of tool. If you’re managing multiple torrent instances or trying to maintain a healthy seeding ratio across different trackers


Milvus: A Vector Database for Scalable ANN Search

A vector database, like Milvus, is a specialized database designed to store, index, and manage massive collections of vectors


Moby Project: Your Gateway to Custom Containerization

Here's how Moby can be incredibly useful from a software engineer's perspective, along with how to get started and some conceptual code examples