Securing subdomains in Caddy with Google Auth

In a previous post I described how to setup a simple blog running Ghost behind Caddy. In this post I will cover adding subdomains to Caddy and securing them behind Google authentication (other authentication methods are possible, but out of scope for this post).

To do this, we'll use the excellent caddy-security module.

First, we'll get a custom build of caddy with the help of xcaddy:

$ go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest
$ xcaddy build --with github.com/greenpau/caddy-security

Next, we'll update our Caddyfile as follow (based on this). Here I'm using example.com as the base domain.

{
        order authenticate before respond
        order authorize before reverse_proxy
        security {
                oauth identity provider google {
                        realm google
                        driver google
                        client_id <CLIENT_ID>
                        client_secret <CLIENT_SECRET>
                        scopes openid email profile
                }
                authentication portal myportal {
                        enable identity provider google
                        cookie domain example.com
                        ui {
                                links {
                                        "My Identity" "/whoami" icon "las la-user"
                                }
                        }

                        transform user {
                                match realm google
                                action add role authp/user
                        }

                        transform user {
                                match realm google
                                // Give this account admin role in the auth portal
                                match email me@example.com
                                action add role authp/admin
                        }
                }
                authorization policy mypolicy {
                        set auth url https://auth.example.com/oauth2/google
                        allow roles authp/admin authp/user
                        validate bearer header
                        inject headers with claims
                }
        }
}

Follow the instructions here to obtain CLIENT_ID and CLIENT_SECRET

Now, to secure any subdomain behind this Google oauth login, you can just add an authorize with clause, like so:

secure.example.com {
        authorize with mypolicy
        // other details
}

That's it! You should now get a Google login flow when you try to access secure.example.com

If you are using Plausible with Caddy and wish to secure it behind Google auth, you'll want to exclude the endpoints / assets that it requires client-side for capturing analytics. Something like this worked for me:

analytics.example.com {
        handle /js/* {
                reverse_proxy <pass through to plausible>
        }
        handle /api/* {
                reverse_proxy <pass through to plausible>
        }
        authorize with mypolicy
        reverse_proxy <pass through to plausible>
}