Security - Creating Policies

In order to secure your Filestack urls, you will need two things. First, you will need a policy that says what the user is allowed to do. Second, you will need you to create a signature for the policy which only you can generate. The reason for the signature is to prevent a user from modifying their policy and giving themselves additional privileges. Since only you can generate a valid policy (using your secret key), no one will be able to tamper with the designated policy.

Hash Message Authentication Code (HMAC)

HMAC generates a signature from a message. Only those who have the secret key can generate the correct signature for the message. Those who have the message and the signature cannot figure out what the secret is nor can they modify the message so that the signature is still valid. Filestack and you have the shared secret key that can be found in the security section of the developer portal. By signing your policy with this secret, Filestack can verify your identify. There are no known security flaws or attacks on HMAC.

This secret is how we can verify you are who you say you are. Do not share this secret key. Do not store this in the client.

Policies define what the user can and cannot do. Since these are time based and not single use, you can do interesting things with them, like allow all users to read but prevent writes. Since these signatures are meant to be reused, you should be careful with them. Setting short expirations will reduce the likelyhood of replay attacks.

Filestack file policies are URL safe Base64 JSON parseable strings. To generate a policy, create a json object with the appropriate key value pairs. Then base64 encode it. URL safe is done by replacing '+' with '-' and '/' with '_'.

Base64 also include trailing '=' as padding. You will need to leave these in.

Note that the ordering doesn't matter on the underlying JSON object. Since you will stringify it, we will verify the signature against the string you've provided. You may find that your ordering might be slightly different and thus vary from the example below.

Syntax

{"expiry":epoch_timestamp,"optional_permission":[values]}

Generating a policy using Python

import base64
import json
import time

handle = 'KW9EJhYtS6y48Whm2S6D'
expiry = str(int(time.time() + 60*60))
json_policy = '{"handle":"%s","expiry":%s}' % (handle, expiry)
# example json_policy: '{"handle":"KW9EJhYtS6y48Whm2S6D","expiry":1508141504}'

policy = base64.urlsafe_b64encode(json_policy)
# example policy: eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=
print policy
              

Output:

eyJoYW5kbGUiOiJLVzlFSmhZdFM2eTQ4V2htMlM2RCIsImV4cGlyeSI6MTUwODE0MTUwNH0=

Parameters

Required Policy Input
The only required field is an expiration time
"expiry":epoch_timestamp
Integer

Policy inputs cannot be abbreviated

The expiration date for the policy. After this time, the policy will no longer be valid. The type should be an integer and it is expressed in seconds since the Epoch (1970), a standard computer science concept. All major languages have a way of calculating this easily.

Calculating Epoch Timestamp Examples:

# For 1 hour expirations
# Javascript:   Math.floor(new Date()
        .getTime() / 1000 + 60*60)
# Python:       int(time.time() + 60*60)
Expiry:         1350465080
            

Optional Policy Inputs
Set additional permissions or restrictions
"call":["permission_name"]
Array

Policy inputs cannot be abbreviated

The calls that you allow this policy to make. This can be one or many of the following strings in an array:
  • pick - (allows users to upload files)
  • read - (allows files to be viewed/accessed)
  • stat - (allows metadata about files to be retrieved)
  • write - (allows use of the write function)
  • writeUrl - (allows use of the writeUrl function)
  • store - (allows files to be written to custom storage)
  • convert - (allows transformation (crop, resize, rotate) of files, also needed for the viewer)
  • remove - (allows removal of Filestack files)
  • exif - (allows exif metadata to be accessed)

A policy without the the call permission specified is permitted to make all calls except for exif, which needs to be explicitly included in a policy in order to be allowed.

"handle":"Filestack_handle"
String

Policy inputs cannot be abbreviated

The unique file handle that you would like to access. A Filestack file URL like https://www.filestackapi.com/api/file/KW9EJhYtS6y48Whm2S6D has a handle of KW9EJhYtS6y48Whm2S6D. This is for all calls that act on a specific handle. Pick is not affected by this input as no handle exists yet for the file.
"url":"regular_expression"
String

Policy inputs cannot be abbreviated

It is possible to create a subset of external URL domains that are allowed to be image/document sources for processing.filestackapi.com transformations. The url parameter only applies to processing engine transformations and cannot be used to restrict uploads via the picker to specific domains for example. The filter is a regular expression that must match the input URL. The following is an example of a policy that restricts conversion requests to urls from wikimedia.

{"expiry":1577836800,"call":["convert"],"url":"https://upload\\.wikimedia\\.org/wikipedia/.*"}

"maxSize":1024
Integer

Policy inputs cannot be abbreviated

The maximum file size in bytes that can be stored by your request. This only applies to the store command. Default is no limit.
"minSize":128
Integer

Policy inputs cannot be abbreviated

The minimum file size that can be stored by your request. This only applies to the store command. Together with maxSize, this forms a range. The value of minSize should be smaller then maxSize. Defaults to 0.
"path":"regular_expression"
String

Policy inputs cannot be abbreviated

For policies that store files, a perl-like regular expression that must match the path that the files will be stored under. The path parameter in regards to the policy only prevents a user from storing files to paths that are different than what is set in the policy. For instance, you could set the path to "path":"/something/else/" and the user would then not be able to write files to "/something/" by itself, they would have to write into "/something/else/". The path parameter in Filestack policies does not prevent a person from reading content from different paths. If you need to prevent people from accessing files from outside a specific path, you should restrict them on a handle by handle basis by using policies that are handle specific. When not set, the path defaults to allowing any path ('.*')
"container":"regular_expression"
String

Policy inputs cannot be abbreviated

For policies that store files, a perl-like regular expression that must match the container/bucket that the files will be stored under. The container parameter in regards to the policy only prevents a user from storing files to containers that are different than what is set in the policy. It does not prevent a person from reading content from different containers. If you need to prevent people from accessing files from outside a specific bucket, you should restrict them on a handle by handle basis by using policies that are handle specific. When not set, the container defaults to allowing any container ('.*').