Source: https://cliparr.dev/docs/access-control/

Documentation

# Access control

Protect Cliparr with a trusted network or an authenticated reverse proxy.

Cliparr can remember provider connections, but it does not have a full user system with app-level accounts, roles, or permissions. Treat access to the Cliparr web app as access to the connected sources and active media sessions.

Provider login is not Cliparr access control

Plex and Jellyfin authentication lets Cliparr connect to those sources. It does not limit who can open the Cliparr app once they can reach it.

## Recommended deployment

Keep Cliparr on `localhost`, a trusted private network, a VPN, or behind an authenticated reverse proxy. If you expose Cliparr outside a trusted network, put authentication in front of it with the proxy or access gateway you already trust.

```
flowchart LR
browser[Browser]

subgraph trusted[Trusted network]
gateway[Auth proxy or VPN]
cliparr[Cliparr app]
plex[Plex]
jellyfin[Jellyfin]
end

browser -->|HTTPS + login| gateway
gateway -->|authenticated request| cliparr
cliparr -->|provider API + media| plex
cliparr -->|provider API + media| jellyfin
```

Put the auth or VPN boundary before Cliparr. Plex and Jellyfin login only lets Cliparr connect to those sources; it does not protect the Cliparr web app.

## Choose an access pattern

| Pattern                                                   | Best for                                                                                               | Public endpoint                     | Notes                                                                                               |
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------- | --------------------------------------------------------------------------------------------------- |
| Auth proxy with Authelia, Authentik, or a similar service | Browser access through a normal domain with reusable users, sessions, and multi-factor authentication. | Yes, protected by the auth gateway. | Works well when you already run Caddy, Nginx, or Traefik and want a login page in front of Cliparr. |
| Tailscale                                                 | Personal or small-team access from trusted devices without opening Cliparr to the public internet.     | No.                                 | Tailscale Serve can give Cliparr a tailnet-only HTTPS URL.                                          |
| WireGuard                                                 | Traditional VPN access with explicit network and firewall control.                                     | No.                                 | Bind Cliparr to the VPN interface or restrict the proxy to VPN clients.                             |
| Hosted access gateway                                     | Installations already fronted by Cloudflare Access or another hosted identity-aware proxy.             | Yes, protected by that provider.    | Useful when the provider is already your public edge and identity layer.                            |

## Reverse proxy basics

When Cliparr is behind a reverse proxy, preserve the `Host` header and pass `X-Forwarded-Proto`. See [Configuration](https://cliparr.dev/docs/configuration) for the core reverse proxy and HTTPS requirements.

Use HTTPS for remote access. The editor relies on browser WebCodecs, and supporting browsers require a secure context outside `localhost` or `127.0.0.1`.

## Authelia with Caddy

Authelia is a common self-hosted choice when you want real login sessions, multi-factor authentication, per-domain policies, and reusable users in front of apps that do not have their own user system. With Caddy, use `forward_auth` to ask Authelia whether each request should continue to Cliparr.

This example assumes:

* `auth.example.com` points to Authelia.
* `cliparr.example.com` points to Cliparr through Caddy.
* Caddy, Authelia, and Cliparr share a Docker network.
* Authelia is already configured with users, session cookies, storage, and an authz endpoint named `forward-auth`.

Authelia needs a forward-auth authorization endpoint in its configuration:

```yaml
server:
  endpoints:
    authz:
      forward-auth:
        implementation: ForwardAuth
```

Then protect Cliparr from Caddy:

```plaintext
auth.example.com {
    reverse_proxy authelia:9091
}

cliparr.example.com {
    forward_auth authelia:9091 {
        uri /api/authz/forward-auth
        copy_headers Remote-User Remote-Groups Remote-Email Remote-Name
    }

    reverse_proxy cliparr:7171 {
        header_up Host {host}
        header_up X-Forwarded-Proto {scheme}
    }
}
```

Expose Cliparr only to the Compose network and publish ports from Caddy:

```yaml
services:
  cliparr:
    image: ghcr.io/techsquidtv/cliparr:latest
    environment:
      - APP_KEY=replace-this-with-a-32-character-secure-random-string
    expose:
      - "7171"
    volumes:
      - cliparr-data:/data
    restart: unless-stopped

  caddy:
    image: caddy:2
    depends_on:
      - authelia
      - cliparr
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy-data:/data
      - caddy-config:/config
    restart: unless-stopped

  authelia:
    image: authelia/authelia:latest
    expose:
      - "9091"
    volumes:
      - ./authelia:/config
    restart: unless-stopped

volumes:
  cliparr-data:
  caddy-data:
  caddy-config:
```

Authelia configuration has more moving parts than a Caddyfile. Follow Authelia’s Caddy integration guide and keep the `auth.example.com`, cookie domain, storage, notifier, and access-control policy aligned with your real domain.

## Tailscale or WireGuard

For many home setups, the safest access control is no public Cliparr endpoint at all. Put Cliparr on a private VPN and let only trusted devices reach it.

With Tailscale, bind Cliparr to localhost and share it only inside your tailnet:

Bind Cliparr to localhost

macOS / Linux

```bash
docker run -d \
  --name cliparr \
  -p 127.0.0.1:7171:7171 \
  -e APP_KEY="your-32-char-stable-random-secret" \
  -v cliparr-data:/data \
  ghcr.io/techsquidtv/cliparr:latest
```

PowerShell

```powershell
docker run -d `
  --name cliparr `
  -p 127.0.0.1:7171:7171 `
  -e APP_KEY="your-32-char-stable-random-secret" `
  -v cliparr-data:/data `
  ghcr.io/techsquidtv/cliparr:latest
```

Then run Tailscale Serve on the same host:

```bash
tailscale serve --bg localhost:7171
```

Tailscale will give the service a tailnet-only HTTPS URL on the machine’s MagicDNS name. Do not use Tailscale Funnel for Cliparr unless you intentionally want to expose it to the public internet.

With WireGuard, keep the same idea: do not publish Cliparr to the public interface. Bind it to a WireGuard-only address or place Caddy on the host and allow the Caddy port only from the WireGuard interface or VPN subnet.

For example, if the Cliparr host has WireGuard address `10.8.0.1`, bind Docker to that address instead of every interface:

Bind Cliparr to WireGuard

macOS / Linux

```bash
docker run -d \
  --name cliparr \
  -p 10.8.0.1:7171:7171 \
  -e APP_KEY="your-32-char-stable-random-secret" \
  -v cliparr-data:/data \
  ghcr.io/techsquidtv/cliparr:latest
```

PowerShell

```powershell
docker run -d `
  --name cliparr `
  -p 10.8.0.1:7171:7171 `
  -e APP_KEY="your-32-char-stable-random-secret" `
  -v cliparr-data:/data `
  ghcr.io/techsquidtv/cliparr:latest
```

If you use Caddy inside the VPN, serve Cliparr on an internal name and restrict firewall access to VPN clients:

```plaintext
cliparr.home.arpa {
    reverse_proxy 127.0.0.1:7171 {
        header_up Host {host}
        header_up X-Forwarded-Proto {scheme}
    }
}
```

## What to protect

Protect every Cliparr route with the same access policy, including:

* The web app.
* `/api/*` routes.
* Provider connection and callback routes.
* Media proxy routes used while previewing and exporting clips.

## Credential storage

Provider credentials and remembered provider sessions are stored under the Cliparr data directory and encrypted or signed with `APP_KEY`. Keep `APP_KEY` stable, private, and backed up with the matching data directory.
