We've been making changes to how we organize and display our docs. Our work isn't done but we'd love your feedback.
Getting started
Basics
Domains & Origins
Performance

Configuration
Basics
Conditions
Dictionaries
Domains & Origins
Request settings
Cache settings
Headers
Responses
Performance
Custom VCL
Image optimization
Video

Security
Access Control Lists
Monitoring and testing
Securing communications
TLS
Web Application Firewall

Integrations
Logging endpoints
Non-Fastly services

Diagnostics
Streaming logs
Debugging techniques
Common errors

Account info
Account management
Billing
User access and control

Reference

    Enabling URL token validation

      Last updated January 08, 2019

    Token validation allows you to create URLs that expire. Tokens are generated within your web application and appended to URLs in a query string. Requests are authenticated at Fastly's edge instead of your origin server. When Fastly receives a request for the URL, the token is validated before serving the content. After a configurable period of time, the token expires.

    Adding custom VCL

    To enable token validation, you'll need to create a Varnish configuration named vcl_recv and add the following example code to it.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    # only do this once per request
    if (req.restarts == 0) {
      declare local var.token STRING;
      declare local var.token_expiration STRING;
      declare local var.token_signature STRING;
    
      # extract the token
      set var.token = subfield(req.url.qs, "token", "&");
    
      # make sure there is a token
      if (var.token == "") {
        error 403;
      }
    
      # make sure there is a valid expiration and signature
      if (var.token !~ "^(\d{10,11})_([a-f0-9]{40})$") {
        error 403;
      }
    
      # extract token expiration and signature
      set var.token_expiration = re.group.1;
      set var.token_signature = re.group.2;
    
      # make sure the signature is valid
      if (!digest.secure_is_equal(var.token_signature, regsub(digest.hmac_sha1(digest.base64_decode("YOUR%SECRET%KEY%IN%BASE64%HERE"), req.url.path + var.token_expiration), "^0x", ""))) {
        error 403;
      }
    
      # make sure the expiration time has not elapsed
      if (time.is_after(now, std.integer2time(std.atoi(var.token_expiration)))) {
        error 410;
      }
    }
    

    The custom VCL code above checks for two things:

    If the signature is invalid, Varnish returns a 403 response. If the signature is valid but the expiration time has elapsed, Varnish returns a 410 response. The different response codes are helpful for debugging.

    The token information

    A token is expected in the ?token= GET parameter. Tokens take the format [expiration]_[signature] and look like this:

    1
    
    1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
    

    The full request URL with the token looks like this:

    1
    
    http://www.example.com/foo/bar.html?token=1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
    

    The signature validation

    The key found in digest.hmac_sha1 can be any string. The one in this example was generated with the command openssl rand -base64 32. The example key YOUR%SECRET%KEY%IN%BASE64%HERE will intentionally cause an error if you use it. You must replace it with your own randomly generated secret key.

    Configuring your application

    You'll need to write custom code in your application to generate tokens and authenticate with Varnish. We provide examples in our token functions repository on GitHub. Review the examples in the repository to learn how to generate custom tokens within your application.

    Testing

    To test your configuration, append a token generated by your application to a URL in a query string. For example:

    http://www.example.com/foo/bar.html?token=1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615

    If the token is valid, you will receive a normal response. If it is invalid, you will receive a 403 response.

    Troubleshooting NUL bytes

    You should verify that your secret key is devoid of NUL bytes. If the Base64-decoded string contains a NUL byte (0x00), then that byte and any bytes following it will not be included in the response. See Base64 decoding for more information.

    Excluding the token query string from the cache key

    If all tokens are dynamic and different, you may want to exclude the token query string from the cache key to avoid potentially affecting the cache hit ratio. To do this, you'll need to add the following code in custom VCL in addition to the example code above:

    1
    2
    
    /* strip out the token querystring so Fastly does not vary the cache. */
    set req.url = querystring.filter(req.url, "token");
    
    Back to Top