How to Restrict Access to Offloaded Media

WP Offload Media has the ability to set offloaded Media Library items as being “private”. When a media item is private, access to it is restricted to signed URLs that can be generated by WP Offload Media. The signed URLs expire after a short period of time.

You typically want to restrict access to offloaded Media Library items that are downloadable product files for WooCommerce or Easy Digital Downloads, or perhaps to ensure media available on members-only pages can not be used by non-members. We generally call these kinds of files “private” to distinguish them from public media such as images that you usually want to be freely seen on the site.

Media Library Actions

WP Offload Media has both “Make Private in Bucket” and “Make Public in Bucket” bulk and individual item actions available in the Media Library.

Media Actions

The individual item actions change depending on whether the Media Library item is already public or private, i.e. “Make Private in Bucket” is available only if the item is public.

When viewing the details of a Media Library item you can see its “Access” status in the Offload meta box.

The Access status is a link that toggles the status. If it says “Access: Public” and you click “Public”, WP Offload Media will make the Media Library item private and “Access: Private” will be shown. You can click “Private” to make the Media Library item public again.

When WP Offload Media sets a Media Library item as private it updates the object in the bucket to have a “private” ACL (Access Control List). This means the object can no longer be accessed directly. The storage provider will reject any URLs that try to access the object unless it is properly signed.

If you are using Amazon S3 and Amazon CloudFront for storage and delivery respectively, and have taken our recommendation to turn on Block All Public Access to bucket, then WP Offload Media does not need to update the object’s ACL to private as all objects in the bucket are private by default. With Block All Public Access turned on, only CloudFront URLs can be used to serve any S3 objects. To ensure Amazon CloudFront restricts access to private media you must therefore follow our guide on How to Serve Private Media via Signed Amazon CloudFront URLs.

When WP Offload Media generates a signed URL for a site visitor, the URL expires after 900 seconds (15 minutes) by default. This makes it relatively useless for someone to share the URL publicly, but gives someone reading a page enough time to notice the link and click it.

WooCommerce & Easy Digital Downloads

WP Offload Media also generates signed URLs for offloaded Media Library items that have been added as product files to either a WooCommerce or Easy Digital Downloads product. These URLs expire in just 5 seconds as they are only needed when the download has been authorized and WP Offload Media has taken over delivery duties. Once the download starts it will continue past the 5 seconds expiry time, but any new attempts to use the expired URL will be rejected.

Custom Filters

If you have a need for making new offloads private by default, you can implement a custom filter to conditionally change whether the item is private or not.

The change to private also applies when using Block All Public Access with an S3 bucket even though no ACLs are actually changed, and the CloudFront Private Media settings are being used. In this case WP Offload Media changes the bucket path as appropriate so that it either includes the private prefix or not.

The primary filter for controlling whether the offloaded object is private is called as3cf_upload_object_key_as_private. To make an offload private return true instead of the default of false.

The following could be added to your child theme’s functions.php file to make all new offloads private by default…

 * This filter allows you to change the public/private status of an individual file associated
 * with an uploaded item before it's uploaded to the provider.
 * This example makes every newly offloaded object private in the bucket.
 * @param bool $is_private Should the object be private?
 * @return bool
function my_as3cf_upload_every_object_key_as_private( $is_private ) {
    return true;
add_filter( 'as3cf_upload_object_key_as_private', 'my_as3cf_upload_every_object_key_as_private' );

You can also see examples in our WP Offload Media Tweaks plugin, including how to only make the primary Media Library item private in the bucket. The example in the Tweaks plugin includes all the parameters the filter supplies.