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




Ollama: Your Local LLM Companion

Ollama is a command-line tool that makes it incredibly easy to run large language models (LLMs) locally on your own machine


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


Unlock Rapid Prototyping with PocketBase: An All-in-One Go Backend

[golang, authentication, backend] Open Source realtime backend in 1 fileImagine you're building an application – maybe a web app


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


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


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


An Introduction to Charmbracelet/Bubble Tea

Here's a breakdown of its benefits for software engineers, how to get started, and a simple code example.From a software engineer's perspective


Chainlink for Software Engineers: Bridging On- and Off-Chain Computation

Here's how it's useful, along with how you can get started.Think of a Chainlink node as the "middleware" connecting smart contracts to the outside world


How to Use tulir/whatsmeow for Custom WhatsApp Alerts in Go

tulir/whatsmeow is a Go (Golang) library that implements the communication protocol for WhatsApp's multi-device feature


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