Basicauth by default (but exclude certain routes)

1. Caddy version (caddy version):


2. How I run Caddy:

I use it as a reverse proxy to enable HTTPS in the development environment for a web app.

a. System environment:

Docker on Mac.

b. Command:

c. Service/unit/compose file:

version: '3.7'


    image: caddy
      - 443:443
      - ./caddy/dev-key.pem:/root/certs/dev-key.pem
      - ./caddy/dev.pem:/root/certs/dev.pem
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
    image: listmonk/listmonk
      - ./listmonk/config.toml:/listmonk/config.toml
      - "8086:8086"

d. My complete Caddyfile or JSON config: {
  log stdout
  tls /root/certs/dev.pem /root/certs/dev-key.pem

  @auth {
    not path /lists

  basicauth @auth {

  handle {
    reverse_proxy newsletter:8086

3. The problem I’m having:

I’m using a third-party tool (listmonk) to manage a newsletter. listmonk does not provide any authentication.
The tool has public endpoints (where user can (un-)subscribe to a newsletter) and private endpoint (managing/sending the newsletter).
The author of the tool recommends to use basic auth and provides a nginx config as an example.

My issue is that I’m not able to transfer this config to caddy. The basic idea is that by default all routes require basicauth. Routes that are public should be explicitly configured (to avoid forgetting to secure a route).

From this and this posts I believe this can be achieved by using a matcher to exclude the routes (path) that do not require authentication.
But with the given Caddyfile even the path defined in the matcher require authentication.

4. Error messages and/or full log output:

No error is given.

5. What I already tried:

Searched this community and tried to adapt the Caddyfiles of the other two posts I mentioned to my needs.

6. Links to relevant resources:

1 Like

Path matching is exact-match in Caddy v2, so /lists will only match /lists. Instead, use /lists/* or /lists* (but the later will also match /liststststs, so you could do not path /lists /lists/* to be stricter if needed)

1 Like

That put me on the right track.

I added /lists/* and also realized that some static data was loaded from /public/*. Adding these both it now works as expected. Thanks for your help!


This topic was automatically closed after 30 days. New replies are no longer allowed.