Skip to content

Access-Controlled Files

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

Prerequisites

Limitations

  • Only one mode can be enabled on a single WordPress environment 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.
  • The Access-Controlled Files feature is incompatible with WPVIP’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.
  • The Access-Controlled Files feature will not work as expected if IP geolocation is used to determine which requests should be allowed access.
  • A VIP Local Development Environment will be unable to proxy media files from a WordPress multisite environment that has the Access-Controlled Files feature activated.

Default settings

By default, activating the Access-Controlled Files feature on a production environment will cause the feature to also be activated on all non-production environments in that application.

  • Until a mode has been enabled on the production environment, the Restrict access to all files mode will be enabled on all non-production environments by default.
  • When a mode is enabled on the production environment, that same mode will automatically be enabled on all non-production environments.
  • The mode enabled on any single environment can be overridden by enabling a different mode via code or VIP-CLI.

Note

Enabling a mode on a single environment that differs from an application’s other environments is discouraged. Inconsistent settings between environments can negatively affect the ability to troubleshoot unexpected behavior during development and testing.

Caution

If Access-Controlled Files is active on a production environment, it is not recommended to deactivate the feature on any of its associated non-production environments. The VIP File System’s shared media files feature automatically provides a non-production environment with access to media associated with the production environment. It is possible for requests for the production media files through the non-production environment to be successful if Access-Controlled Files is disabled on the non-production environment.

Considerations

Cached responses for file URLs might already exist on the edge cache prior to the activation of the Access-Controlled Files feature and mode enablement. Cached content for file URLs must be purged from the edge cache in order for those requests to receive the expected 404 response.

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.

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.

Enable “Restrict access to unpublished files” mode

When the Restrict access to unpublished files 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. All other requests for those files will be served a 404 Not Found HTTP status response.

Restrict access to unpublished files 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.

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.

/client-mu-plugins/example-file.php
// Restrict access to unpublished files mode
add_filter( 'pre_option_vip_files_acl_restrict_unpublished_enabled', function( $value ) {
    return 1;
} );

To code-enable Restrict access to unpublished files mode per-network site on a WordPress multisite, include conditional logic to selectively enable the mode for one or more specific sites using get_current_blog_id().

Note

The VIP-CLI examples below include a @<app-name>.<env> placeholder that must be updated with the relevant application name and environment type values before running the commands.

To enable Restrict access to unpublished files mode with VIP-CLI, the vip_files_acl_restrict_unpublished_enabled option must be added and set to a value of 1. For example:

vip @<app-name>.<env> -- wp option add vip_files_acl_restrict_unpublished_enabled 1

Once the vip_files_acl_restrict_unpublished_enabled option exists, Restrict access to unpublished files mode can be disabled by updating the value to 0 and re-enabled by updating the value to 1. For example, to disable:

vip @<app-name>.<env> -- wp option update vip_files_acl_restrict_unpublished_enabled 0

Enable for a network site

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-name>.<env> -- wp option add vip_files_acl_restrict_unpublished_enabled 1 --url=<url>

Enable “Restrict access to all files” mode

When Restrict access to all files 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. All other requests for those files will be served a 404 Not Found HTTP status response. This mode is useful for intranets and private sites.

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.

/client-mu-plugins/example-file.php
// Restrict access to all files mode
add_filter( 'pre_option_vip_files_acl_restrict_all_enabled', function( $value ) {
    return 1;
} );

To code-enable Restrict access to all files mode per-network site on a WordPress multisite, include conditional logic to selectively enable the mode for one or more specific sites using get_current_blog_id().

Note

The VIP-CLI examples below include a @<app-name>.<env> placeholder that must be updated with the relevant application name and environment type values before running the commands.

To enable Restrict access to all files mode with VIP-CLI, the vip_files_acl_restrict_all_enabled option must be added and set to a value of 1. For example:

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

Once the vip_files_acl_restrict_all_enabled option exists, Restrict access to all files mode can be disabled by updating the value to 0 and re-enabled by updating the value to 1. For example, to disable:

vip @<app-name>.<env> -- wp option update vip_files_acl_restrict_all_enabled 0

Enable for a network site

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-name>.<env> -- wp option add vip_files_acl_restrict_all_enabled 1 --url=<url>

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 , Automattic\VIP\Files\Acl\FILE_IS_PRIVATE_AND_ALLOWED , and Automattic\VIP\Files\Acl\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 Automattic\VIP\Files\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 );

Last updated: November 14, 2024

Relevant to

  • WordPress