Partially applying auth to a reverse proxy / re-using an upstream

1. The problem I’m having:

I want to require authentication for only a part of reverse proxy url space.

nodered.foo.com/public/* -> without auth
nodered.foo.com -> with auth
(auth) {
        forward_auth nforwardauth:9999 {
                uri /
        }
}

nodered.foo.com {
        import auth
        reverse_proxy http://nodered:1880
}

What I have tried is:

nodered.foo.com {
        handle /public/* {
                reverse_proxy http://nodered:1880
        }

        import auth
        reverse_proxy http://nodered:1880
}

What I am unclear here is whether specifying the upstream twice is a bad idea.

And for some reason auth seems to required also for /public

curl -k -I https://nodered.foo.com/public/foo
HTTP/2 307 
alt-svc: h3=":443"; ma=2592000
date: Thu, 02 May 2024 13:09:28 GMT
location: https://auth.foo.com/login?r=https://nodered.foo.com/public/foo

2. Error messages and/or full log output:

NA

3. Caddy version:

v2.7.6 h1:w0NymbG2m9PcvKWsrXO6EEkY9Ru4FJK8uQbYcev1p3A=

4. How I installed and ran Caddy:

NA

a. System environment:

Docker on x86

b. Command:

NA

c. Service/unit/compose file:

NA

d. My complete Caddy config:

NA

5. Links to relevant resources:

NA

Just apply a matcher to forward_auth:

@auth not path /public/*
forward_auth @auth nforwardauth:9999
2 Likes

Fair point. That’s even easier.

But just for the learning: What’s wrong with my approach?

It would cause two reverse_proxy handlers to be loaded and in memory, so they would not share state (like health check status etc). In practice it doesn’t really matter. But it’s certainly cleaner to not repeat yourself in config.

2 Likes

Makes sense.

And why would /public/foo still be affected by the import auth outside the handle match?

I would have have expected this to only fall through for non /public/* and give a 404 when testing /public/foo but instead got a 307.

I don’t follow. Please share your config as it is now.

1 Like

I have it working now - but I was wondering why this here:

would give me a 307 (requiring auth) for /public/foo.

Because forward_auth is higher on the directive order than handle, so it always runs first:

2 Likes

Thanks for the help! That cleared things up!