Files
docudjeex/content/en/3.serveex/3.security/4.tinyauth.md
T

287 lines
9.1 KiB
Markdown

---
title: TinyAuth
description: Install TinyAuth, a lightweight forward-auth proxy, and pair it with Pocket ID to add SSO login in front of your self-hosted apps.
---
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
# TinyAuth
::note
🎯 __Objectives:__
- Install TinyAuth
- Log in via [Pocket ID](/serveex/security/pocket-id) (OIDC)
- Protect an app behind Swag with forward-auth
::
[TinyAuth](https://tinyauth.app) is a small forward-auth proxy: a single login page that Swag can insert in front of any app before letting a request through, similar in spirit to [Authentik](/serveex/advanced/authentik)'s reverse-proxy mode, but without the rest of Authentik's identity-provider machinery.
It supports a simple local username/password login out of the box, and can also delegate login to an external OIDC provider. Here we'll use [Pocket ID](/serveex/security/pocket-id), so anyone visiting a protected app first authenticates with a passkey via Pocket ID, then gets forwarded through.
- [TinyAuth documentation](https://tinyauth.app/docs)
- [TinyAuth on GitHub](https://github.com/tinyauthapp/tinyauth)
::note
This guide assumes you've already installed [Pocket ID](/serveex/security/pocket-id). You can skip the Pocket ID sections below and use TinyAuth with just a local username/password instead.
::
## Installation
Folder structure:
```text [Directory tree]
root
└── docker
└── tinyauth
├── compose.yaml
├── .env
└── data
```
Create the data folder:
```bash [Terminal]
sudo mkdir -p /docker/tinyauth/data
```
Generate a password hash for your local account:
```bash [Terminal]
sudo docker run -i -t --rm ghcr.io/tinyauthapp/tinyauth:v5 user create --interactive
```
::note
Enable "Format for Docker" when prompted, so the generated hash is already escaped for use in a `.env` file.
::
Open Dockge, click `compose`, name the stack `tinyauth`, and add the following config:
```yaml [compose.yaml]
---
services:
tinyauth:
image: ghcr.io/tinyauthapp/tinyauth:v5
container_name: tinyauth
restart: unless-stopped
env_file:
- .env
volumes:
- /docker/tinyauth/data:/data
ports:
- 3000:3000
```
::tip
✨ Add the Watchtower label to automate updates:
```yaml [compose.yaml]
services:
tinyauth:
#...
labels:
- com.centurylinklabs.watchtower.enable=true
```
::
Fill in the `.env` file:
```properties [.env]
TINYAUTH_APPURL=https://tinyauth.mydomain.com
TINYAUTH_AUTH_USERS=
```
| Variable | Value | Example |
|----------|-------|---------|
| `TINYAUTH_APPURL`{lang=properties} | The public URL you'll use to reach TinyAuth (see exposure below) | `https://tinyauth.mydomain.com` |
| `TINYAUTH_AUTH_USERS`{lang=properties} | The hash generated above | `user:$$2a$$10$$UdLYoJ5lgPsC0RKq...` |
Deploy the stack. The local interface is available at `http://yourserverip:3000`.
## Exposing TinyAuth with Swag
TinyAuth needs its own subdomain: it's the page users land on before being forwarded to the app they actually want.
::note
We assume you have the subdomain `tinyauth.mydomain.com` with a `CNAME` pointing to `mydomain.com` in your [DNS zone](/general/networking/dns). And of course, [unless you use Cloudflare Zero Trust](/serveex/security/cloudflare), your box's port `443` must be forwarded to your server's port `443` in [NAT rules](/general/networking/nat).
::
Go to Dockge and edit SWAG's compose file by adding TinyAuth's network:
```yaml [compose.yaml]
services:
swag:
container_name: # ...
# ...
networks: # Attach container to custom network
# ...
- tinyauth # Name of the declared network
networks: # Define the custom network
# ...
tinyauth: # Declared network name
name: tinyauth_default # Actual external network name
external: true # Marks it as externally defined
```
Redeploy the stack and wait for SWAG to be fully operational.
::note
Here we assume the TinyAuth network name is `tinyauth_default`. You can check the connection by visiting SWAG's dashboard at `http://yourserverip:81`.
::
In the Swag folders, create the file `tinyauth.subdomain.conf`:
::tip{icon=""}
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
::
```bash [Terminal]
sudo nano /docker/swag/config/nginx/proxy-confs/tinyauth.subdomain.conf
```
Paste the following configuration:
```nginx [tinyauth.subdomain.conf]
## Version 2023/12/19
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name tinyauth.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app tinyauth;
set $upstream_port 3000;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
Wait a few minutes, then open `https://tinyauth.mydomain.com` in your browser and log in with the username/password you created above.
::caution
__If it fails:__ check your firewall rules.
::
## Connecting TinyAuth to Pocket ID
First, [register TinyAuth as an OIDC client in Pocket ID](/serveex/security/pocket-id#registering-an-oidc-client), using this callback URL:
```text
https://tinyauth.mydomain.com/api/oauth/callback/pocketid
```
Copy the __Client ID__ and __Client Secret__ Pocket ID gives you, then edit TinyAuth's `.env` file:
```bash [Terminal]
sudo nano /docker/tinyauth/.env
```
Add the following:
```properties [.env]
TINYAUTH_OAUTH_PROVIDERS_POCKETID_NAME=Pocket ID
TINYAUTH_OAUTH_PROVIDERS_POCKETID_CLIENTID=
TINYAUTH_OAUTH_PROVIDERS_POCKETID_CLIENTSECRET=
TINYAUTH_OAUTH_PROVIDERS_POCKETID_AUTHURL=https://id.mydomain.com/authorize
TINYAUTH_OAUTH_PROVIDERS_POCKETID_TOKENURL=https://id.mydomain.com/api/oidc/token
TINYAUTH_OAUTH_PROVIDERS_POCKETID_USERINFOURL=https://id.mydomain.com/api/oidc/userinfo
TINYAUTH_OAUTH_PROVIDERS_POCKETID_REDIRECTURL=https://tinyauth.mydomain.com/api/oauth/callback/pocketid
TINYAUTH_OAUTH_PROVIDERS_POCKETID_SCOPES=openid email profile
```
| Variable | Value |
|----------|-------|
| `CLIENTID`{lang=properties} | The client ID copied from Pocket ID |
| `CLIENTSECRET`{lang=properties} | The client secret copied from Pocket ID |
| `AUTHURL` / `TOKENURL` / `USERINFOURL`{lang=properties} | Pocket ID's public URL, with the paths shown above |
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
Redeploy the TinyAuth stack. On your next visit to `https://tinyauth.mydomain.com`, you'll see a "Login with Pocket ID" option alongside the local login form.
::tip
✨ To skip straight to Pocket ID and hide the local login form, add `TINYAUTH_OAUTH_AUTOREDIRECT=pocketid` to the same `.env` file.
::
## Protecting an app via reverse proxy
Unlike Authentik, Swag doesn't ship a ready-made include file for TinyAuth, so we'll add the forward-auth check directly to the app's own `*.subdomain.conf`. We'll use Dockge as an example.
Open the file:
```bash [Terminal]
sudo nano /docker/swag/config/nginx/proxy-confs/dockge.subdomain.conf
```
Add an internal `/tinyauth` location, and reference it from the app's `location /` block with `auth_request`:
```nginx [dockge.subdomain.conf]{9-11,25}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name dockge.*;
include /config/nginx/ssl.conf;
client_max_body_size 0;
location /tinyauth {
internal;
proxy_pass http://tinyauth:3000/api/auth/nginx;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
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 https://tinyauth.mydomain.com/login?redirect_uri=$scheme://$http_host$request_uri;
}
location / {
auth_request /tinyauth;
error_page 401 = @tinyauth_login;
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app dockge;
set $upstream_port 5001;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
```
::note
The `location /tinyauth` block must be able to reach the TinyAuth container by its Docker name (`tinyauth` here). Add TinyAuth's network to this stack's compose file the same way you did [for Swag](/serveex/security/tinyauth#exposing-tinyauth-with-swag) if it isn't already attached.
::
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
That's it! Visiting `https://dockge.mydomain.com` now redirects to TinyAuth first. Repeat this `location /tinyauth` / `auth_request` pattern in any other app's `*.subdomain.conf` to protect it the same way.
::note
Repeat this process for each app you want to protect (unless it has native OIDC support, in which case you can point it directly at Pocket ID instead).
::