Tinyauth
Overview
This guide covers the deployment and configuration of Tinyauth 5.2.0 on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images. Tinyauth is a lightweight, open-source authentication gateway that puts a login screen in front of the self-hosted apps you run behind a reverse proxy. Instead of every app needing its own accounts, you place Tinyauth in front of them. A protected route asks Tinyauth whether the visitor is signed in, and if not, the visitor is sent to a single login portal. After signing in, the visitor is allowed through, and the same session covers every app that Tinyauth protects.
The image installs the official Tinyauth v5.2.0 release binary (a single, statically linked Go binary), verified by SHA-256 at install time, and ships the AGPL-3.0 license text alongside it. Local users are stored as username and bcrypt-hash pairs. Tinyauth also supports OAuth and OIDC providers, LDAP, TOTP two-factor authentication and per-app access-control rules. Sessions are held in a local SQLite database, so there is no external database, no Redis and no database port to secure.
Security model. Because Tinyauth guards your other apps, the image ships with no usable credential at all. It contains zero configured users, and the tinyauth service is held back until first boot. At first boot, the image generates a fresh admin password unique to your instance, hashes it with bcrypt, and writes the credential to a root-only file. Tinyauth binds to 127.0.0.1:3000 only and is fronted by nginx on port 443 with a per-instance self-signed TLS certificate. Plain HTTP on port 80 permanently redirects to HTTPS. Session cookies are marked Secure. The image includes a protected demo route (/demo/), so you can see the auth gate working the moment the VM boots. The only ports exposed are SSH (22) and the web portal (80 and 443).
What you get:
- Tinyauth 5.2.0 official release binary at
/usr/local/bin/tinyauth(SHA-256-verified) tinyauth.servicesystemd unit running the server bound to127.0.0.1:3000nginxreverse proxy on port 443 (self-signed TLS; port 80 redirects to 443), serving the login portal, the Tinyauth API and the forward-auth endpoint, plus a demo route protected by Tinyauthtinyauth-firstboot.servicesystemd oneshot unit that creates the per-VM admin user and TLS certificate on first boot- A local SQLite session database at
/var/lib/tinyauth/tinyauth.db - A credential self-test at
/usr/local/sbin/tinyauth-credcheck.sh - The AGPL-3.0 license text at
/usr/local/share/tinyauth/LICENSE - Ubuntu 24.04 LTS base with the latest security patches applied at build time
- 24/7 SecureAnyCloud support with a guaranteed 24-hour response SLA
Prerequisites
Before you deploy, make sure you have the following:
- An active Azure subscription
- A subscription to the Tinyauth on Ubuntu 24.04 listing on Azure Marketplace
- An SSH public key for VM authentication
- A virtual network and subnet in the target region
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM). Tinyauth is extremely lightweight, so scale up only if you protect many applications with very high request volumes.
Deploy from the Azure Portal
In the Azure portal, open Marketplace, search for Tinyauth, select the SecureAnyCloud publisher entry, and click Create.
On the Networking tab, attach a network security group. Allow inbound TCP 22 from your management IP range, and allow TCP 443 (and 80, which redirects to 443) from the client networks that reach the login portal and protected apps.
Click Review + create, wait for validation, then click Create. Deployment takes around two minutes.
Deploy from the Azure CLI
Create a resource group, accept the Marketplace terms once per subscription, create the VM, and open the ports:
RG="tinyauth-prod" LOCATION="eastus" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:tinyauth-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" \
--name tinyauth-01 \
--image sac1647283583153:tinyauth-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku Standard
# Allow SSH (22) and the login portal / protected apps (80 redirects to 443)
az vm open-port --resource-group "$RG" --name tinyauth-01 --port 22 --priority 1001
az vm open-port --resource-group "$RG" --name tinyauth-01 --port 80 --priority 1002
az vm open-port --resource-group "$RG" --name tinyauth-01 --port 443 --priority 1003Replace <publisher>:<offer>:<sku> with the URN shown on the Marketplace listing's Usage Information tab.
Connect via SSH
Connect with the private key that matches the public key you supplied at deploy time. The login user for this image is azureuser.
ssh azureuser@<vm-public-ip>Verify the Tinyauth Service
Confirm that the Tinyauth server and the nginx proxy are running, and check the listening sockets. Tinyauth binds to 127.0.0.1:3000 only, so it is reachable from outside the VM solely through nginx on port 443. The AGPL-3.0 license ships with the image.
tinyauth version systemctl is-active tinyauth nginx
sudo ss -ltn | grep -E ':443 |:3000 ' head -2 /usr/local/share/tinyauth/LICENSEExpected output:
Version: v5.2.0 Commit Hash: 653b747829cc72b5ad5232db63b075fb66f81796 Build Timestamp: 2026-09-07T17:15:08 active active LISTEN 0 4096 127.0.0.1:3000 0.0.0.0:* LISTEN 0 511 0.0.0.0:443 0.0.0.0:* LISTEN 0 511 [::]:443 [::]:* GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007Retrieve Your Per-VM Admin Credential
On the first boot of your virtual machine, tinyauth-firstboot.service generated an admin password unique to your instance, hashed it with bcrypt into Tinyauth's configuration, and wrote the plaintext to a root-only file. Retrieve the password:
sudo cat /root/tinyauth-credentials.txtThe file reports the login URL and the admin credential:
tinyauth.url=https://<vm-public-ip>.sslip.io/ tinyauth.apphost=<vm-public-ip>.sslip.io tinyauth.admin.user=admin tinyauth.admin.pass=<generated-per-vm>The URL uses sslip.io wildcard DNS. The name <vm-public-ip>.sslip.io resolves to your VM's public IP and matches the TLS certificate, so the login portal has a real host name out of the box.
A shipped self-test confirms the whole auth-gate model without printing any secret. It checks that the login portal renders over TLS, that the per-VM admin credential authenticates, that a wrong password is refused, that the forward-auth endpoint returns 401 for an anonymous request and 200 for an authenticated one, and that the protected demo route is gated:
sudo bash /usr/local/sbin/tinyauth-credcheck.shExpected output:
OKSee the Auth Gate Working
Tinyauth allows authenticated requests through and redirects anonymous ones to the login portal. The image includes a demo route at /demo/, protected by Tinyauth through nginx auth_request. You can see both behaviors with curl. Log in to get a session cookie, then request the forward-auth endpoint and the protected route with and without the cookie:
HOST=$(sudo grep '^tinyauth.apphost=' /root/tinyauth-credentials.txt | cut -d= -f2-)
AP=$(sudo grep '^tinyauth.admin.pass=' /root/tinyauth-credentials.txt | cut -d= -f2-) C="curl -s -k --resolve ${HOST}:443:127.0.0.1" $C -c /tmp/cj -H 'Content-Type: application/json' \
--data "{\"username\":\"admin\",\"password\":\"$AP\"}" \
-o /dev/null -w 'login -> HTTP %{http_code}\n' https://${HOST}/api/user/login FWD="-H X-Forwarded-Proto:https -H X-Forwarded-Host:${HOST} -H X-Forwarded-Uri:/demo/" $C $FWD -o /dev/null -w 'forward-auth anon -> HTTP %{http_code}\n' https://${HOST}/api/auth/nginx $C $FWD -b /tmp/cj -o /dev/null -w 'forward-auth authed-> HTTP %{http_code}\n' https://${HOST}/api/auth/nginx $C -o /dev/null -w '/demo/ anon -> HTTP %{http_code}\n' https://${HOST}/demo/ $C -b /tmp/cj -o /dev/null -w '/demo/ authed -> HTTP %{http_code}\n' https://${HOST}/demo/ rm -f /tmp/cjExpected output:
login -> HTTP 200 forward-auth anon -> HTTP 401 forward-auth authed-> HTTP 200 /demo/ anon -> HTTP 302 /demo/ authed -> HTTP 200The anonymous request to /demo/ returns 302, because nginx redirects it to the Tinyauth login portal. With a valid session, it returns 200 and the protected page renders.
Sign In to the Login Portal
In a browser, go to https://<vm-public-ip>.sslip.io/. Because the certificate is self-signed, your browser warns you once. Accept the exception, or install a real certificate (see Step 11). Sign in with user admin and the tinyauth.admin.pass value from Step 5.
After you sign in, you land on the Tinyauth account page, which shows your signed-in user and a logout control. Tinyauth uses this session to authorize every app you place behind it.
Watch the Gate Protect the Demo App
Open https://<vm-public-ip>.sslip.io/demo/. While you are signed in, the protected demo page renders. nginx asked Tinyauth to authorize the request, and Tinyauth let it through because you have a valid session.
If you open the same URL in a private window (no session), Tinyauth redirects you straight to the login portal. This is the purpose of the gateway. Any app you place behind Tinyauth is protected the same way.
Protect Your Own Apps
To protect an app that runs on the VM, front it with nginx and defer the authorization decision to Tinyauth. The demo route uses this pattern:
# In your app's nginx server block: location / { auth_request /tinyauth-verify; auth_request_set $tinyauth_login $upstream_http_x_tinyauth_location; error_page 401 = @tinyauth_login; proxy_pass http://127.0.0.1:<your-app-port>; } location = /tinyauth-verify { internal; proxy_pass http://127.0.0.1:3000/api/auth/nginx; proxy_pass_request_body off; proxy_set_header Content-Length ""; proxy_set_header X-Original-URL ""; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Uri $request_uri; } location @tinyauth_login { return 302 $tinyauth_login; }Keep the proxy_set_header X-Original-URL ""; line in every verify location you write. nginx forwards every header of the visitor's request to the auth_request subrequest, and Tinyauth's nginx endpoint reads X-Original-URL first. Without that line, a visitor can send their own X-Original-URL that names another app's public path and walk past the login (Tinyauth advisory GHSA-vx8c-f5hh-c8pf, fixed in Tinyauth 5.2.0, which this image ships). Always set X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-Uri from nginx's own variables as shown, and never pass the visitor's values through.
The shipped vhost at /etc/nginx/sites-available/tinyauth is a complete working example. Tinyauth also supports fine-grained per-app access-control rules (allow or block specific users or OAuth/LDAP groups per app). See the Tinyauth access-controls guide.
Add More Users, OAuth, OIDC and LDAP
Tinyauth's configuration is in /etc/tinyauth/config.yaml. To add another local user, generate a bcrypt entry and add it under auth.users:
sudo tinyauth user create --interactive
# copy the printed "username:hash" value, then add it under auth.users in the config: sudoedit /etc/tinyauth/config.yaml
sudo systemctl restart tinyauthFor single sign-on with Google, GitHub or any generic OIDC provider, add an oauth.providers block. For directory logins, add an ldap block. For two-factor authentication, add a TOTP secret to a user. The Tinyauth configuration reference documents each option.
Install a Real TLS Certificate (Production)
The image ships a per-VM self-signed certificate, so the portal serves HTTPS out of the box. To use a trusted certificate, point a DNS name at the VM's public IP, open port 443 in the network security group, and install a Let's Encrypt certificate into the bundled nginx:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comThen update appUrl in /etc/tinyauth/config.yaml to https://your-domain.example.com/ and restart Tinyauth, so that redirects and cookies use the real domain:
sudoedit /etc/tinyauth/config.yaml
sudo systemctl restart tinyauthManaging the Tinyauth Service
Use these commands to check the service, read its logs, apply configuration changes and reload nginx:
# Status and logs systemctl status tinyauth --no-pager sudo journalctl -u tinyauth -n 100 --no-pager
# Restart after changing /etc/tinyauth/config.yaml
sudo systemctl restart tinyauth
# nginx (the reverse proxy)
sudo nginx -t && sudo systemctl reload nginxArchitecture Summary
- Tinyauth 5.2.0: a single statically linked Go binary at
/usr/local/bin/tinyauth, run as the non-roottinyauthservice account under systemd, bound to127.0.0.1:3000. - nginx: terminates TLS on port 443 (self-signed per-VM certificate; port 80 redirects to 443) and serves the login portal, the Tinyauth API, the forward-auth endpoint and the protected
/demo/route. - Configuration:
/etc/tinyauth/config.yaml. The shipped image contains no users. First boot writes the per-VMappUrland a bcrypt admin user. - Sessions: a local SQLite database at
/var/lib/tinyauth/tinyauth.db, with no external database and no database port. - First boot:
tinyauth-firstboot.servicecreates the per-VM admin password and TLS certificate, writes the root-only credentials file, then starts the stack. - Ports: SSH (22) and the web portal (80 redirecting to 443). Tinyauth on 3000 is bound to loopback and never exposed directly.
SecureAnyCloud maintains this image and provides 24/7 support (sales@secureanycloud.com, 24-hour response SLA).
Deploy on Azure
Launch Tinyauth on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com