Thanks! DensityDist does appear to be a good way to go.
The Stan implementation is here, but not very readable on its own. There, we did the equivalent of subclassing the Model class and implemented our own Model.log_prob, which then could be passed to the Stan samplers.
If you’re willing to take a deeper dive into this, scheduling a call would probably be a lot faster than trying to go from the paper / Stan code. But we will try out DensityDist in the meantime.