Matcher exclude path not working?

So I switched to Caddy recently from nginx and I love it. However I have one concern I cannot figure out.

I want to basicauth for a specific area UNLESS it is within the /api/ path. However, I can’t seem to get caddy to accept this.

One section that works no problem is this…

  import tlscf
  basicauth /abc/UI* {
    {$XAUTH}
  }  
  reverse_proxy abc:9117 {
    import proxyheaders
  }

To adapt this to my first mentioned question, I tried this…

https://abcd.dulanic.com {
  import tlscf
  basicauth not path /api/* {
    {$XAUTH}
  }    
  reverse_proxy demo:8088 {
    header_up X-Forwarded-Host {host}:8088
    header_up -Origin
    header_up -Referer
  }  
}

However, this errors out /w Wrong argument count or unexpected line ending after ‘/api/*’

It looks like this should work as that is a direct example at https://caddyserver.com/docs/caddyfile/matchers#not but I am sure I am misunderstanding how not works for this. Since /api/ is a subfolder of / I can’t define what I want to have basicauth, I need to define what I do not want.

I also tried without path as the first method worked without path, and that didn’t help.

We figured this out, basically. basicauth supports @ NamedMatchers, so we used those. Learned from: File_server basics

1 Like

Matchers are a generalized concept. Anywhere you see [<matcher>] in the docs, the things allowed are either * for “match anything”, something starting with / for a path matcher, or starting with @ for a named matcher:

@francislavoie I think the point was, we had to put the not in a named matcher as it would not work otherwise.

We used:

  @NoAccess {
    not path /api*
  }
  basicauth @NoAccess {
    {$XAUTH}
  } 

But this would not work:

  basicauth not path /api* {
    {$XAUTH}
  }

Yes of course, as I said, because the parser only allows for *, something starting with /, or something starting with @. It’s well documented in the syntax doc I linked above.

You can also shorten it like this, using the single-line named matcher syntax:

@NoAccess not path /api*
basicauth @noAccess {
    ...
}

Thank you I get it now. So it’s because it was the not AND the matcher. Thanks.