How the Example Works
- Turn on security for your app
In the Developer Portal, open your application and enable Security. Until you do, uploads and delivery are open to anyone who has your API key. - Sign the policy on your server
Create a JSON policy with a short expiry (minutes, not days), only the calls this client needs (for example pick and store) and limits such as maxSize. Encode it as Base64URL and sign it with HMAC-SHA256 using your app secret. The secret stays on your server. - Fetch the policy before opening the picker
Your frontend requests the policy and signature from your backend (in this example, /get-filestack-credentials) and passes them to filestack.init as security options. - Filestack checks every request
Filestack decodes the policy, recomputes the signature and compares the two. If they match and the policy has not expired, the upload runs. If the policy has expired, was altered or does not include the call, the request is rejected.
Read the full walkthrough: How to Secure File Uploads With Signed Policies →
Try It Yourself
The frontend code below assumes your backend returns the policy and signature from /get-filestack-credentials. The server code under it shows that endpoint.
See the Pen File Picker security policy example by Filestack Marketing (@ffkocvzk-the-encoder) on CodePen.
HTML
CSS
#picker{
height: 100vh
}
JavaScript
async function getFilestackCredentials() {
const response = await fetch("/get-filestack-credentials");
return response.json();
}
async function initFilePicker() {
const credentials = await getFilestackCredentials();
const clientOptions = {
security: {
policy: credentials.policy,
signature: credentials.signature
}
};
const apiKey = "YOUR_API_KEY";
const client = filestack.init(apiKey, clientOptions);
let pickerOptions = {
displayMode: "inline",
container: "#picker"
};
const picker = client.picker(pickerOptions).open();
}
initFilePicker();
Server (Node.js)
const crypto = require('crypto');
const express = require('express');
const app = express();
// Returns a short-lived, scoped policy and its signature
app.get('/get-filestack-credentials', (req, res) => {
const policy = {
expiry: Math.floor(Date.now() / 1000) + 300, // 5 minutes
call: ['pick', 'store'],
maxSize: 10 * 1024 * 1024 // 10 MB
};
const encoded = Buffer.from(JSON.stringify(policy)).toString('base64url');
const signature = crypto
.createHmac('sha256', process.env.FILESTACK_APP_SECRET)
.update(encoded)
.digest('hex');
res.json({ policy: encoded, signature });
});
app.listen(3000);
Add signed uploads to your app today.
File Picker Features
SHORT-LIVED POLICIES
Set an expiry in minutes so a leaked policy stops working on its own.
SCOPED CALLS
Allow only the calls a client needs, such as pick and store, and nothing else.
SIZE AND PATH LIMITS
maxSize and path in the policy are enforced by the API, not the browser.
MALWARE SCANNING
Run virus detection in a workflow on every upload. Virus Detection API →
SIGNED DELIVERY
Serve files through signed, expiring URLs instead of public links.
DOMAIN WHITELISTS
Limit which sites can embed your picker by Origin and Referer. Domain whitelists →
“Being smart here, in my opinion, is seriously looking at Filestack to give you a fantastic uploading experience, while you spend your time on your product vision, not already-solved problems.”
— CHRIS COYIER, FOUNDER OF CSS-TRICKS & CODEPEN