Bunny CDN provides a powerful token authentication system to strictly control who, where and for how long can access your content.
This guide contains the documentation on how to enable, configure and generate the tokens to securely access your content. If you are looking for our older, but much more simple token authentication system, please check older token authentication guide instead. Both can be used interchangeably and our system will automatically detect and validate both token types.
What is token authentication?
First of all, what is token authentication? In short, if enabled, token authentication will block all requests to your URLs unless a valid token is passed with the request. The token is then compared on our server and we check if both values match. If the hash we generate matches the one sent by the request, then the request is accepted, otherwise, a 403 page is returned.
The token can then either be put in as a query parameter or used as part of the URL path. The path version is useful for situations such as video delivery. Here are two examples of signed URLs:
This section contains instructions on how to generate and format the unique tokens and use those to sign an URL. We also provide code examples and helper functions for popular programming languages that allow you to sign an URL with a simple function call.
The signing process consists of the following parameters that need to be added to the URL:
- token (required)
- expires (required)
- token_path (optional)
- token_countries (optional)
- token_countries_blocked (optional)
- limit (optional)
The token parameter is the main key in signing the URL. It represents a Base64 encoded SHA256 hash based on the URL, expiration time and other parameters. We will show how to generate the token in the next section.
The expires parameter is the second main parameter that must always be included. It allows you to control exactly for how long the signed URL is valid. It is a UNIX timestamp based time representation. Any request after this timestamp will be rejected.
For example, a token expiring on 08/21/2020 @ 3:43 pm (UTC) would use:
By default, the full request URL is used for signing a request. The token_path parameter allows you to specify a partial path that will be used instead of the full URL.
Let's use this URL for an example:
By default, the full path would need to be used when generating the token, and only this specific path would be allowed to be accessed with the specific token:
However, by passing the token_path for the following parameter:
That would create a token that has access to any file within that path, for example:
https://test.b-cdn.net/my-partial/url/playlist.m3u8 https://test.b-cdn.net/my-partial/url/file1.ts https://test.b-cdn.net/my-partial/url/file2.ts https://test.b-cdn.net/my-partial/url/file3.ts
Would all be covered by the token. This is useful for video delivery.
The token_countries allows you to specify a list of countries that will have access to the URL. Any request outside of these countries will be rejected. It is a comma-separated list, for example:
The token_countries_blocked is similar to token_countries. It allows you to specify a list of countries that will not have access to the URL. Any request from one of the listed countries will be rejected. It is a comma-separated list, for example:
If set, this header will configure the download speed limit of the request in kilobytes per second (kB/s). It allows you to dynamically control the delivery speed using signed token requests (for example slow downloads for unpaid users, or faster downloads for paid users)
Now that we understand all the parameters, we can proceed to actually generate the token. The token is a Base64 encoded raw SHA256 hash based on the signed URL, expiration time, and any extra parameters. To generate the token, you can use the following algorithm:
Base64Encode( SHA256_RAW(token_security_key + signed_url + expiration + (optional)remote_ip + (optional)encoded_query_parameters) )
When generating the token, all of the URL query parameters must also be appended at the end of the hashable string in an ascending order except for the "token" and "expires" parameter which should not be included. These must NOT be URL encoded, but they need to be in the form-encoded POST format without the starting "?" character, for example:
An example hashable base for a SHA256 token would then be:
To properly format the token you have to then replace the following characters in the resulting Base64 string: '\n' with '', '+' with '-', '/' with '_' and '=' with ''.
Once we have the token and all the parameters, it's time to put it all together. There are currently two ways of signing the URL.
The easiest way is to append the token to the request using query parameters, for example:
The second option are the URL path based tokens that are useful for video delivery because any sub-request to the same directory of the URL will already have the token included.
Note that when generating the token, the token_path parameter does not need to include the signature path.
If it all went well, you should now have secure URLs that are only accessible through the signed URLs. If you experience any difficulties generating the tokens, please feel free to get in touch and we'll be happy to help with the implementation.
Updated 2 months ago