I built caddy with xcaddy build --with github.com/corazawaf/coraza-caddy/v2, and then loaded the custom rule:
SecAction phase:1,id:109,initcol:ip=%{REMOTE_ADDR},nolog
SecRule ARGS:login "!^$" "nolog,phase:1,id:110,setvar:ip.auth_attempt=+1,expirevar:ip.auth_attempt=120"
SecRule IP:AUTH_ATTEMPT "@gt 25" "log,drop,phase:1,id:111,msg:'Possible Brute Force Attack'"
running caddy reports an error
Error: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 0: loading handler modules: position 0: loading module 'waf': provision http.handlers.waf: invalid WAF config from string: failed to parse string: failed to compile the directive "secrule": invalid arguments, expected collection TX