Skip to content

Access-controlled files

The Access-controlled files feature restricts access to files and media uploaded to the WordPress Media Library. Two modes of Access-controlled files are supported: Restrict access to unpublished files or Restrict access to all files.

  • Only one mode can be enabled on a single WordPress site at a single time.
  • The Access-controlled files feature has no effect on static files (e.g., CSS, JS) committed to an application’s GitHub repository.

Activate Access-controlled files

Before an Access-controlled files mode can be enabled, the Access-controlled files feature must be activated.

  1. Create a request with VIP Support and indicate in the request which environment(s) should have the Access-controlled files feature activated.
  2. After VIP Support has confirmed that Access-controlled files feature has been activated on the environment, add the following code to /vip-config/vip-config.php:
/vip-config/vip-config.php
define( 'VIP_FILES_ACL_ENABLED', true );

Prerequisites

Enable restrict access to unpublished files mode

When this mode is enabled, files attached to draft content can only be downloaded or viewed if the request comes from a logged in WordPress user who is authorized to view the content the file is attached to.
This mode is useful if sensitive content is regularly posted and limited access to the media attached to that content is desired.

  • This mode will only apply to files uploaded directly via the post editor. That creates a parent-child relationship between the post and file, which is then used to determine access and permissions.
  • This mode will not apply to files uploaded directly to the WordPress Media Library, even if the file is later inserted into the post from the Media Library or a link to the file is copy-pasted directly into the post.

VIP-CLI

To enable Restrict access to unpublished files mode with VIP-CLI, set the vip_files_acl_restrict_unpublished_enabled option to a value of 1 (to disable set to 0). For example:

vip @<app-alias>.<env> -- wp option update vip_files_acl_restrict_unpublished_enabled 1

Selectively enable Restrict access to unpublished files mode for a network site on a WordPress multisite by running the command with the --url=<url> flag and replacing <url> with the site’s URL.

vip @<app-alias>.<env> -- wp option update vip_files_acl_restrict_unpublished_enabled 1 --url=<url>

Code

To code enable Restrict access to unpublished files mode on a WordPress single site—or for all sites on a WordPress multisite—add the code shown in the example below to a file in the /client-mu-plugins directory.

To code enable Restrict access to unpublished files mode per-network site on a WordPress multisite:

  • Add the code example below to a file in /client-mu-plugins. Include conditional logic in the code to selectively enable the mode for one or more specific sites using get_current_blog_id().
  • Or, add the code example below to functions.php of a network site’s theme, or any other loaded path in the theme or a plugin enabled for a specific site.
// Restrict access to unpublished files mode
add_filter( 'pre_option_vip_files_acl_restrict_unpublished_enabled', function( $value ) {
    return 1;
} );

Enable restrict access to all files mode

When this mode is enabled, all files in the site can only be downloaded or viewed by logged in WordPress users with capability to “read” the published content on the site. This mode is useful for intranets and private sites.

VIP-CLI

To enable Restrict access to all files mode with VIP-CLI, set the vip_files_acl_restrict_all_enabled option to a value of 1 to enable (to disable set to 0). For example:

vip @<app-alias>.<env> -- wp option update vip_files_acl_restrict_all_enabled 1

Selectively enable Restrict access to all files mode for a network site on a WordPress multisite by running the command with the --url=<url> flag and replacing <url> with the site’s URL.

vip @<app-alias>.<env> -- wp option update vip_files_acl_restrict_all_enabled 1 --url=<url>

Code

To code enable Restrict access to all files mode on a WordPress single site—or for all sites on a WordPress multisite—add the code shown in the example below to a file in the /client-mu-plugins directory.

To code enable Restrict access to all files mode per-network site on a WordPress multisite:

  • Add the code example below to a file in /client-mu-plugins. Include conditional logic in the code to selectively enable the mode for one or more specific sites using get_current_blog_id().
  • Or, add the code example below to functions.php of a network site’s theme, or any other loaded path in the theme or a plugin enabled for a specific site.
// Restrict access to all files mode
add_filter( 'pre_option_vip_files_acl_restrict_all_enabled', function( $value ) {
    return 1;
} );

Allow access to Access-controlled files for specific requests

The vip_files_acl_file_visibility filter is useful for mobile applications or plugins that require access to Access-controlled files.

The vip_files_acl_file_visibility filter validates if a request for an Access-controlled file is legitimate. The filter accepts the parameters $file_visibility and $file_path, and returns one of the filter value constants (i.e., Automattic\VIP\Files\Acl\FILE_IS_PUBLIC || FILE_IS_PRIVATE_AND_ALLOWED || FILE_IS_PRIVATE_AND_DENIED) to indicate what level of access to a file can be granted for a request.

Requests for Access-controlled files can be sent with HTTP Authorization header X-Original-Authorization and User Agent X-Original-User-Agent. One or both of these headers can be included in a vip_files_acl_file_visibility filter for additional validation of a request.

The HTTP Authorization header can be sent with credentials for authenticating a request. If the token value assigned to the Authorization header in a request can be matched and validated by the environment receiving the request, the request is identified as legitimate. A matching value on the receiving environment can be stored as an environment variable.

In this code example, requests from a mobile application are granted access to Access-controlled files if the token passed by X-Original-Authorization matches the environment variable APP_FILE_ACCESS_TOKEN, and the filter value constant returned is FILE_IS_PRIVATE_AND_ALLOWED:

/**
 * Allow mobile app requests to have access to Access-controlled files
 */
function vip_check_file_visibility_for_mobile_request( $file_visibility, $file_path ) {
    /**
     * Allow mobile requests with a token
     */
    $token_header = isset( $_SERVER['HTTP_X_ORIGINAL_AUTHORIZATION'] ) ? sanitize_text_field( $_SERVER['HTTP_X_ORIGINAL_AUTHORIZATION'] ) : false;

    // Get token from environment variable.
    $token = vip_get_env_var( 'APP_FILE_ACCESS_TOKEN', '' );
    if ( $token === $token_header ) {
        return Acl\FILE_IS_PRIVATE_AND_ALLOWED;
    }

    return $file_visibility;
}
add_filter( 'vip_files_acl_file_visibility', 'vip_check_file_visibility_for_mobile_request', 11, 2 );

Considerations

Performance Impact

Enabling this feature can increase response times for files uploaded to the WordPress Media Library. Serving a file while this feature is active may involve a request to the WordPress application to determine per-user permissions, adding to the overall response time.

  • For Access-controlled files and media, all requests can be around 10-15% slower.
  • For public files and media, the first (uncached) request is expected to be around 10-15% slower. All future requests are cached and should not be impacted.

Incompatible with Basic Authentication

This feature is incompatible with VIP’s Basic Authentication. Environments with Basic Authentication enabled cannot activate the Access-controlled files feature.

To restrict access to the front end of a site while the Access-controlled files feature is active, using a different access restriction method is recommended, such as the maintenance mode plugin.

Potential conflict for self-referencing files

It might be necessary to import a WordPress XML file to an environment that has the same domain as the site from which the XML file was exported. This will result in an import that is “self-referencing”, meaning that it both exports from and imports into the same domain. An import of this kind can happen when adding media library references to a site’s media library following a media import.

If Access-controlled files is enabled, the WordPress importer will be unable to access the media path for a given media asset. The WordPress importer is only able to add media references to a media library if the media path is publicly accessible.

To prevent this issue, set VIP_FILES_ACL_ENABLED to false in /vip-config/vip-config.php for the duration of the XML import. The constant can be set back to true after the import has been completed.

Last updated: November 22, 2022