What is ProtectServe?

ProtectServe is what we call our primary URL signing feature here at CacheFly. It can be used to secure URLs so only authorized requests can make successful requests.

More information about our ProtectServe feature can be found in our in depth documentation here.

This guide is meant to provide a quick overview of our ProtectServe feature.

ProtectServe Options

ProtectServe provides a few different options that allow you to choose what URLs should be signed: Optional, Required, and Mandatory.

  • Optional

    • The optional ProtectServe option, allows for secured content to be within a /Protected directory.

    • Requests not within the /Protected directory are served as normal and do not require a signature.

    • For example, the following URL would require a signature:

      • https://example.com/Protected/path/to/file

  • Required

    • Similar to the Optional ProtectServe option, requests for secured files much be in a /Protected directory. However, requests not within the /Protected directory are forbidden and will result in a 403.

  • Mandatory

    • ProtectServe is mandatory for all requests and do not require files to be in the /Protected directory. Any unsigned requests will result in a 403.

ProtectServe Rules

In our documentation for Setting Up a ProtectServe URL, you will see that we have a component for ProtectServe rules. These rules are a set of key/value pairs that help control URL access.

Below is an example of a ProtectServe signed URL using either the Optional or Required option and signing up to the /path/to/file/ directory. This example shows the usage of all of our available rules:

https://example.cachefly.net/Protected/expiretime=1754396361;ip=1.2.3.4;badurl=aHR0cHM6Ly9leGFtcGxlLmNhY2hlZmx5Lm5ldC91bmF1dGhvcml6ZWQ=;dirmatch=true;sp=1/{hash}/path/to/file/

Available rules:

  • expiretime - Required

    • This is the unix epoch time for when the object signature expires and becomes in invalid.

  • ip - Optional

    • Restricts requests to only allow successful requests from the authorized IP address.

  • badurl - Optional

    • Base64 encoded URL to redirect to if the ProtectServe conditions are not met or if the hash is tampered with.

  • dirmatch (true/false) - Optional

    • When set to true ProtectServe will sign up to a set directory. The signature will apply to anything within that directory.

      • For example, the following would sign up to /secure/directory/. Anything after that can be served with the same signature.

        • https://example.com/secure/directory/

    • When set to false, the full file path including the file must be signed.

  • sp=1 - Optional

    • This key/value pair allows you to use Optional/Required without having to place files in a /Protected folder on the origin, but a request to your CDN service must still contain that folder

ProtectServe Example Code

Below is a PHP code example for ProtectServe using both dirmatch=true and dirmatch=false:

Using dirmatch=true:

<?php

// Example URL https://servicename.cachefly.net/Protected/$rules/$hash/some/directory/{index.m3u8|playlist.m3u8|chunk1.ts}

// GENERATE PROTECTSERVE URL
$protocol = 'https'; // MODIFY AS NEEDED
$hostname = 'example.cachefly.net'; // MODIFY AS NEEDED
$protected = '/Protected'; // LEAVE BLANK IF USING MANDATORY PROTECTSERVE
$secret = '<secret_from_portal>'; // REPLACE WITH SECRET SET IN PORTAL
$path_to_hash = 'path/to/file/'; // WHAT WE WANT TO HASH (FULL FILE PATH OR DIRECTORY IF USING "dirmatch=true", NO FILENAME)
$filename = 'file.txt?foo=bar'; // SET THE REST OF PATH OUTSIDE OF THE WHAT WE ARE HASHING WHEN USING "dirmatch=true"
#$path_to_hash = 'path/to/file.txt?foo=bar'; // ENTIRE FILE PATH INCLUDING FILE WHEN USING "dirmatch=false"
$expiretime = time() + 86400; // SET TO 1 DAY IN THIS EXAMPLE, ADJUST AS NEEDED
$rules = 'expiretime=' . $expiretime . ';' . 'dirmatch=true'; // THE DIRMATCH RULE IS WHAT ENABLES DIRECTORY HASHING

/**
* Other rules examples:
* Include users IP:
* 	$rules = 'expiretime=' . $expiretime . ';' . 'ip=1.2.3.4' . 'dirmatch=true' . ';';
*
* Include a URL for invalid requests and user IP (this example uses URL http://www.website.com/protected.php):
* 	$rules = 'expiretime=' . $expiretime . ';' . 'ip=1.2.3.4' . 'badurl=aHR0cDovL3d3dy53ZWJzaXRlLmNvbS9wcm90ZWN0ZWQucGhw' . 'dirmatch=true' . ';';
*
* Include the option to strip the "/Protected" directory from origin requests when using OPTIONAL or REQUIRED (do not change query value)
* 	$rules = 'expiretime=' . $expiretime . ';' . 'dirmatch=true' . ';' . 'sp=1';
*/

$hash = hash_hmac('sha256',$rules . $path_to_hash, $secret, FALSE);
$request = "$protocol://$hostname$protected/$rules/$hash/" . $path_to_hash;
if ($filename != '') {
$request = $request . $filename;
}
echo "Piece to encode: " . $rules . $path_to_hash . "\r\n\n";
echo "Hash: " . $hash . "\r\n\n";
echo "Signed URL: " . $request . "\r\n";

?>

Using dirmatch=false:

<?php

// Example URL https://servicename.cachefly.net/Protected/$rules/$hash/some/directory/{index.m3u8|playlist.m3u8|chunk1.ts}

// GENERATE PROTECTSERVE URL
$protocol = 'https'; // MODIFY AS NEEDED
$hostname = 'example.cachefly.net'; // MODIFY AS NEEDED
$protected = '/Protected'; // LEAVE BLANK IF USING MANDATORY PROTECTSERVE
$secret = '<secret_from_portal>'; // REPLACE WITH SECRET SET IN PORTAL
#$path_to_hash = 'path/to/file/'; // WHAT WE WANT TO HASH (FULL FILE PATH OR DIRECTORY IF USING "dirmatch=true", NO FILENAME)
#$filename = 'file.txt?foo=bar'; // SET THE REST OF PATH OUTSIDE OF THE WHAT WE ARE HASHING WHEN USING "dirmatch=true"
$path_to_hash = 'path/to/file/file.txt?foo=bar'; // ENTIRE FILE PATH INCLUDING FILE WHEN USING "dirmatch=false"
$expiretime = time() + 86400; // SET TO 1 DAY IN THIS EXAMPLE, ADJUST AS NEEDED
$rules = 'expiretime=' . $expiretime . ';' . 'dirmatch=false'; // THE DIRMATCH RULE IS WHAT ENABLES DIRECTORY HASHING

/**
* Other rules examples:
* Include users IP:
* 	$rules = 'expiretime=' . $expiretime . ';' . 'ip=1.2.3.4' . 'dirmatch=true' . ';';
*
* Include a URL for invalid requests and user IP (this example uses URL http://www.website.com/protected.php):
* 	$rules = 'expiretime=' . $expiretime . ';' . 'ip=1.2.3.4' . 'badurl=aHR0cDovL3d3dy53ZWJzaXRlLmNvbS9wcm90ZWN0ZWQucGhw' . 'dirmatch=true' . ';';
*
* Include the option to strip the "/Protected" directory from origin requests when using OPTIONAL or REQUIRED (do not change query value)
* 	$rules = 'expiretime=' . $expiretime . ';' . 'dirmatch=true' . ';' . 'sp=1';
*/

$hash = hash_hmac('sha256',$rules . $path_to_hash, $secret, FALSE);
$request = "$protocol://$hostname$protected/$rules/$hash/" . $path_to_hash;
if ($filename != '') {
$request = $request . $filename;
}
echo "Piece to encode: " . $rules . $path_to_hash . "\r\n\n";
echo "Hash: " . $hash . "\r\n\n";
echo "Signed URL: " . $request . "\r\n";

?>

Common Use-Cases with ProtectServe

ProtectServe can be used with a number of use-cases, with the most common being for static files and VODs without pre-existing query strings. Here, we'll quickly cover how to use ProtectServe with a few different common use-cases.

Using ProtectServe with static files and VODs without query strings:

  • This is the most straightforward and common application with ProtectServe.

  • The code examples in our Using ProtectServe article and the prior example code should provide enough details to get you started with using this feature.

Using ProtectServe with static files and VODs with query strings:

  • ProtectServe was designed to also handle requests that use pre-existing query strings.

  • When using dirmatch=true, the query string can be added to the end of the filename before or after signing since the signature is only up to the specified path.

  • When using dirmatch=false, the query string will need to be added to the end of the filename before signing, otherwise the the signature check will fail and return a 403.

Using Protect Serve with HLS live/VOD streams:

  • It is recommended to use dirmatch=true and sign up the last most common folder so one signature can handle all requests from the user during the steam.

  • When generating the master and chunk playlists, ensure that the signature is applied to those results to ensure smooth playback.

    • For example: Use the following signed request for a master playlist using the Optional or Required ProtectServe option (assume this is signed up to /path/to/file/):

      • https://example.cachefly.net/Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/master.m3u8

    • This should return something similar to the following when signed properly:

      • #EXTM3U
        #EXT-X-VERSION:3
        #EXT-X-STREAM-INF:BANDWIDTH=1500000,RESOLUTION=1280x720
        /Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/chunklist/high_quality.m3u8
        #EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=854x480
        /Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/chunklist/medium_quality.m3u8
        #EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=640x360
        /Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/chunklist/low_quality.m3u8
    • Subsequently, the chunklist should return signed chunks:

      • #EXTM3U
        #EXT-X-VERSION:3
        #EXT-X-TARGETDURATION:6
        #EXTINF:5.01,
        /Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/high_quality/chunk1.ts
        #EXTINF:5.22,
        /Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/high_quality/chunk2.ts
        #EXTINF:5.15,
        /Protected/expiretime=1754396361;dirmatch=true/{hash}/path/to/file/high_quality/chunk3.ts

ProtectServe FAQ

  • Can I configure ProtectServe to skip specific files or extensions?

    • Yes, we offer the ProtectServe Skip by Extension feature for this use-case.

    • To enable or disable ProtectServe Skip by Extension for a service, first navigate to that service (Configuration > Services > [SERVICE NAME]).
      On the left of the screen, click on OPTIONS to expand the list of options available.
      Click on ProtectServe Skip by Extension in the list of OPTIONS for the service or scroll down to display the ProtectServe Skip by Extension section.

    • If the ProtectServe Skip by Extension button/toggle is gray and shows Disabled, click the button/toggle to enable ProtectServe Skip by Extension (the button/toggle then turns blue and shows Enabled).

    • You can then enter all of the comma delimited extensions, with the leading period, you wish to skip ProtectServe.

  • I want to use the Optional/Required method, do I have to move files on my origin to a /Protected folder?

    • No, we have a rule that allows you to use these methods without having to move any files on your origin to a /Protected folder.

    • During your signing process, add the sp=1 flag in the rules so we ignore the /Protected folder during an origin pull request.

  • Does ProtectServe create unique cache keys for each request and cause multiple origin pulls for the same file?

    • No, although ProtectServe will use unique signatures for requests, we will use the same cache key for same files.

  • Can the ProtectServe signature be added as a query string, cookie, or header?

    • No, but you can use our Signed URLs script config to use a query string base signature.

      • This script config can be configured to emulate CDN77s and Cloudflares URL Signer, which allows for signing using query parameters.

      • More information information about Singed URLs script config can be found in our knowledge base here and in our API documentation here.

    • Unfortunately, we do not currently offer a feature to allow secured URLs by cookies or headers at this time

  • Does ProtectServe allow signing with IPv6 addresses?

    • No, the ip rule currently only supports IPv4 addresses.