Skip to content

Security & Access Control

Identity Provider: Authelia (auth.tskn.org) · Domain: tskn.org
Ingress & TLS: Caddy (Cloudflare DNS-01 Challenge) · Mesh: Tailscale (WireGuard)


Architecture Overview

The homelab employs a multi-tiered Zero Trust / Defense-in-Depth model to protect self-hosted services from unauthorized access, automated attacks, and data leakage.

flowchart TD
    Client["Client Request"] --> Cloudflare["Cloudflare DNS"]
    Cloudflare --> Caddy["Caddy Ingress Ports 80 and 443"]

    Caddy -->|"Security Headers"| Headers["nosniff, SAMEORIGIN, -Server"]

    Caddy --> CheckAuth{"Auth Required?"}

    CheckAuth -->|"Forward-Auth"| Authelia["Authelia Gate localhost:9091"]
    Authelia -->|"Pass"| ProtectedApp["Protected Apps (Dozzle, Kopia, etc.)"]
    Authelia -->|"Fail"| Login["Login Portal auth.tskn.org"]

    CheckAuth -->|"Direct Proxy"| OIDCApp["Native Auth and OIDC Apps"]
    OIDCApp -.->|"OIDC SSO"| Authelia

    CheckAuth -->|"Public Access"| PublicApp["Public Apps (IT-Tools, Startpage)"]

1. Authentication & Single Sign-On (Authelia)

Authelia acts as both an in-line forward-auth gateway and an OpenID Connect (OIDC) identity provider.

Forward-Auth Gateway

For applications that lack native multi-user authentication, Caddy intercepts incoming HTTP requests and queries Authelia's /api/authz/forward-auth endpoint before passing traffic to the container.

Guarded by Forward-Auth: * Glance Dashboard & Editor: tskn.org/dashboard/*, tskn.org/api/editor/* * Container Log Viewer: dozzle.tskn.org * Backup UI: kopia.tskn.org * Downloader: megadown.tskn.org * Snapcap & Internal Webapps: snapcap.tskn.org, webapps.tskn.org

OpenID Connect (OIDC) Provider

For modern applications with native SSO support, Authelia issues signed JWT tokens and validates user profiles over standard OIDC workflows.

Client ID Application Supported Redirect Flows
immich Immich Photos https://immich.tskn.org/auth/login, app.immich:///oauth-callback
paperless Paperless-ngx https://paperless.tskn.org/accounts/oidc/authelia/login/callback/
jellyfin Jellyfin Media https://jellyfin.tskn.org/sso/OID/redirect/authelia (PKCE S256)
homebox Homebox Inventory https://homebox.tskn.org/api/v1/users/login/oidc/callback (PKCE S256)
adventurelog AdventureLog Trips https://adventurelog.tskn.org/accounts/oidc/authelia/login/callback/
vikunja Vikunja Tasks https://vikunja.tskn.org/auth/openid/authelia
dawarich Dawarich GPS https://dawarich.tskn.org/users/auth/openid_connect/callback
beszel Beszel Metrics https://beszel.tskn.org/api/oauth2-redirect
yamtrack Yamtrack Games https://yamtrack.tskn.org/accounts/oidc/authelia/login/callback/
sparkyfitness SparkyFitness https://sparkyfitness.tskn.org/api/auth/sso/callback/authelia
wud What's Up Docker https://wud.tskn.org/auth/oidc/authelia/cb (PKCE S256, Admins only)

Brute-Force Regulation & Sessions

  • Rate Limiting: Maximum 3 failed attempts in a 2-minute window triggers an automatic 5-minute IP ban.
  • Persistent Sessions: Wildcard domain cookies (*.tskn.org) with 1-year expiration and remember_me persistence.

2. Ingress & Reverse Proxy Hardening (Caddy)

Automated TLS & Cloudflare DNS-01 Challenge

Caddy requests wildcard certificates (*.tskn.org, tskn.org) using Cloudflare DNS-01 API validation:

tskn.org, *.tskn.org {
    tls {
        dns cloudflare <CLOUDFLARE_API_TOKEN>
    }
}
* Security Benefit: Certificate generation and renewal occur without exposing port 80 to the public internet for HTTP-01 challenges.

Global Security Headers

Injected into every response: * X-Content-Type-Options: nosniff: Prevents MIME-type sniffing exploits. * X-Frame-Options: SAMEORIGIN: Prevents clickjacking from external iframes. * Referrer-Policy: strict-origin-when-cross-origin: Minimizes referrer leakage. * -Server: Strips the Server: Caddy response header to prevent fingerprinting.

Cross-Origin Resource Sharing (CORS) Policy

Restricted explicitly on sensitive backends (e.g. Immich API):

@cors header_regexp Origin ^https://(webapps|snapcap)\.tskn\.org$
header @cors Access-Control-Allow-Origin "{header.Origin}"
header @cors Vary Origin
header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE"
header Access-Control-Allow-Headers "Authorization, Content-Type, x-api-key"


3. Network Isolation & Port Binding

Host Port Binding Strategy (127.0.0.1)

Most containers publish ports bound exclusively to localhost rather than 0.0.0.0: * Example: "127.0.0.1:8000:8000" (Paperless), "127.0.0.1:2283:2283" (Immich) * Security Benefit: Other devices on the local LAN cannot bypass Caddy, HTTPS, or Authelia by navigating directly to http://10.0.0.172:8000. All web access is forced through Caddy.

Unexposed Backend Containers

Internal databases and caches operate on isolated Docker bridge networks without published host ports: * PostgreSQL instances (immich-postgres, paperless-db, adventurelog-db, sure-db) * Redis brokers (paperless-broker, yamtrack-redis, immich-redis)


4. Secrets & Credentials Management

  1. Git Isolation:
  2. Stack environment files (.env) are globally ignored by Git (/home/tforkan/docker/.gitignore).
  3. Only sanitized compose templates and configuration YAMLs are tracked in version control.
  4. Authelia File-Based Secrets:
  5. Cryptographic keys (JWT_SECRET, SESSION_SECRET, STORAGE_ENCRYPTION_KEY) are stored in authelia/secrets/ as individual files, protected by filesystem permissions and mapped as read-only volumes.
  6. Offsite Backup Encryption:
  7. Kopia encrypts all file backups locally using AES256-GCM-HMAC-SHA256 before syncing to Cloudflare R2. Even in the event of an R2 cloud compromise, data remains cryptographically inaccessible without the master passphrase.