Module with background task

I want Caddy to verify incoming request with jwt authorization header and passing verified claims to backends. Verification process needs to fetch JWKS with scheduled rotation so it’s best to cache and refresh it periodically (i use JWX). I assume this jwt-verification will be an http module.

CMIIW caddy runs http module’s Provision() on every route (backend? ) which has that module enabled.

What is the best way to run refresh task so that there is only one such task? I assume i can create different kind of module and works together with that verification http module but i don’t know where to start. I am new to Go and Caddy, so please be gentle :-). TIA.

What do you mean by route/backend here? If your module is an HTTP handler, then a new instance will be provisioned at every point it’s included in the configuration during configuration load-time. For instance, the module custom_module will be provisioned once:

example.com {
    route {
        custom_module
        respond "Hello, world!"
    }
}

But here it’ll be provisioned twice:

example-1.com {
    route {
        custom_module
        respond "Hello, world!"
    }
}

example-2.com {
    route {
        custom_module
        respond "Hello, world!"
    }
}

Here it will also be provisioned twice:

example-1.com {
    route /route-1* {
        custom_module
        respond "Hello, world!"
    }
    route /route-2* {
        custom_module
        respond "Hello, world!"
    }
}

If you need 1 globally instantiated/provisioned module, there are 2 ways to do it:

  • Develop a Caddy app module to represent the global instance, which you can load in your handler at provision-time using either context#App or context#AppIfConfigured to retrieve and use the global instance. Using an app module allows you to utilize the Start and Stop methods for instantiation and finalization of the periodic call.
  • Create a global variable in your package that is checked and utilized by the module during provisioning. Your modules can have a Cleanup method. This is more complex, in my opinion, because you don’t benefit from the module lifecycle management function of Caddy.

Also refer to this page:

2 Likes

And another way is to use a named route which only provisions once and can be invoked from anywhere multiple times Caddyfile Concepts — Caddy Documentation

But it’s probably better to design the module in a way such that it keeps its data stored in a UsagePool instead, so the cache survives past config reloads, otherwise it would get wiped on each reload.

3 Likes

I have something like @Mohammed90 last snippet:

example-1.com {
    route /prefix-1* {
         my_custom_auth 0 1
         reverse_proxy backend2:80
    }

    route /prefix-2* {
         my_custom_auth 1 
         reverse_proxy backend2:80
    }
}

looks like it can’t use named-route like francislavoie suggested.

Thanks for the heads up for UsagePool and app module. Will start diggin’.

Right, if your config inputs are different between each usage of the module, then yeah you can’t use named routes.

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