In your controller, you can have a method which will download the file. For a more complicated example, let's say that you have a download action in your UsersController controller. From within here, you can use pundit as you normally would. This download action grabs the image of the user.

Disclaimer: This is a horrible example of production practice as you are going to be hammering the server if this action is called a lot. You are essentially resizing the image every single time this action is called. However, as a proof of concept to go outside of how refile file download normally works and adds in the authorization you're seeking.

We create a processor variable which initializes the ImageProcessor fill option. We then create a temporary file and set it to binary mode. We take the file from our user model and read it into the temporary file. Rewind the temporary file to the beginning of the file and read it into MiniMagick . We then call on our processor to convert the temporary file (leaving the original intact). We then send the file to the user.

def download @user = User.find(params[:id]) authorize @user processor = Refile.processor(:fill, Refile::ImageProcessor.new(:fill)) temp_file = Tempfile.new('profile_image') temp_file.binmode temp_file.write @user.profile_image.read temp_file.rewind image_file = MiniMagick::Image.new(temp_file.path) file = processor.fill(image_file, 150, 150) temp_file.close send_file file.path end

Here is the example of it rendering the file as an image_tag

Along with the code that calls the image to be resized and downloaded.

<%= image_tag user_download_path(@user), class: 'img-circle img-thumbnail' %>

You can set your action to accept various other processing options and dimensions. For this example, I'm showing how to fill a size of 150x150 pixels.

Edit to add more clarity:

The function of the temp_file is to leave the original image alone. If you are looking to simply provide an unprocessed download of the original file, you could do something like this below. You should also read on send_file and send_data as they provide other things like filename , disposition , content_type , etc. options for customizing the download and how it should be handled.

def download @user = User.find(params[:id]) authorize @user send_file @user.profile_image.download end

Edit: I looked further into the Refile source and found that the creation of the file links is caused by the mounting of the engine within the routes. Create an initializer file and place the code below in there. This will allow you to keep the existing functionality described above while removing the public links to the files uploaded.