Basicauth exception (for a health check URL), or rewrite *exactly* "/"?

I’m serving a static site from a Caddy-based Docker container (in Kubernetes)

The Caddyfile isn’t included in the image, I provide it to Caddy using “-conf” pointing to a Docker-mounted path from the host, because the config varies slightly between prod/staging/dev (trying to follow good 12 Factor best practices here :slight_smile: )

Actually the only difference between the prod/staging Caddyfile is that the staging one has “basicauth” enabled and prod doesn’t.
Here’s my problem : I still need to health check the Caddy container from Kubernetes on some path WITHOUT basic auth.

The ideal way to do that would be if this suggestion was implemented : Basic auth path exception?.
Something like that would be perfect :

basicauth user pass {
not /healthcheck.json

But it doesn’t exist… so the way I achieved this was by explicitly listing all paths that need to be protected (ugly!)

basicauth {$AUTH_USER} {$AUTH_PASSWORD} {

The trouble is : I also want basicauth to apply to index.html, **including when the original request is “/” **
And unfortunately :

basicauth /

matches everything, not just “/” which serves index.html
So, my solution so far was to do this just before basicauth : explicitly rewrite “/” to “index.html”, then catch it in the basicauth section :

# Explicitly rewrite / to index.html so we can limit basicauth to it.
# Otherwise “basicauth /” catches everything
rewrite / /index.html
basicauth {$AUTH_USER} {$AUTH_PASSWORD} {

This worked fine in 0.9, unfortunately this now causes a redirect loop in 0.10 because “/” is no longer an exact match in the rewrite directive

My clever workaround is no longer working :frowning:
Any ideas to solve this ? Basically I tried to use “rewrite” to work around a “basicauth” limitation, but now even rewrite doesn’t let me do what I need :confused:


This sounds like a bug. It certainly doesn’t match the documentation for the form rewrite [from] [to], which currently states:

from is the exact path to match

You can workaround this by using an if conditional to ensure an exact match, though:

rewrite {
  if {path} is /
  to /index.html


Unfortunately your workaround makes no difference :frowning: Still getting a redirection loop in 0.10.3 which didn’t happen in 0.9.5.
I think it may be related to this bug which has been fixed with 0.10.4 as a milestone, so I guess I’ll have to stick to 0.9 in the meantime :

But again, the only reason I’m rewriting “/” to “/index.html” in the first place, is because “basicauth” seems to have completely different semantics than rewrite : within basicauth, “/” does NOT match exactly “/” (like I would need it to), it acts as a prefix and matches everything. That’s why, as a first step, I’m explicitly rewriting “/” to “/index.html”. Then in basicauth I can just use /index.html, not /, and that will work both when “/” and “/index.html” are requested by the client. Well, at least in 0.9 it did.

At the end of day, all I’m trying to achieve is to have all of my site under basicauth, EXCEPT for some health checking path (any path !) that should return 200 even when queried without authentication if Caddy is alive, that’s it ! Ideally, that path should be a real static file, but if not I’d better have an empty 200 than nothing. Is there an easy way to achieve that maybe ?

Hmm. Maybe a redirect instead, then? Might as well make it permanent, too.

redir {
  if {path} is /
  to /index.html 301
basicauth /index.html user pass

The idea behind basicauth is to be able to protect a subdirectory or the whole site with a single line. With no except-like functionality, the only way to secure everything but a single URI would be to have some script generate a full list of files and paths to secure for you, or do it by hand.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.