>FFmpegLab
Self-Hosting & Storage

Setting Up Supabase Storage with FFmpegLab – Auth, Buckets, TUS Uploads & Per-User RLS

Configure user authentication with magic link login, create a storage bucket with per-user RLS policies, and set up the SUPABASE_STORAGE_BUCKET environment variable for FFmpegLab. Plus, learn how TUS resumable uploads handle files of any size.

FFmpegLab is a powerful browser-based video editing environment that processes video entirely on your device using WebAssembly. But when you're working with a team, you need more than local storage — you need secure, multi‑user cloud storage where each user has their own private space, and large files can be uploaded reliably.

That's where Supabase Storage with per‑user Row Level Security (RLS) and TUS resumable uploads come together.

This guide walks you through the complete setup — from creating your Supabase project and configuring authentication (magic link or password) to creating a storage bucket, configuring per-user RLS policies, setting the SUPABASE_STORAGE_BUCKET environment variable, and understanding how TUS uploads make large file sharing seamless.

Key takeaways

The Gap: Secure, Multi‑User Cloud Storage

FFmpegLab's core editing engine runs entirely in the browser. Your footage never leaves your device — it's processed locally using WebAssembly. This is perfect for privacy and speed.

But when you're working with a team, local storage isn't enough. You need a central place to store:

And critically, you need:

As the Supabase Storage documentation explains: "Storage is designed to work perfectly with Postgres Row Level Security (RLS). You can use RLS to create Security Access Policies that are incredibly powerful and flexible".

User logs in Supabase Auth JWT with user ID RLS Policy User's private folder
Large file upload TUS Protocol Resumable, reliable upload

Why Supabase Storage?

Supabase Storage is an ideal cloud storage solution for FFmpegLab for several reasons:

TUS Resumable Uploads – Large Files Made Easy

One of the most powerful features of FFmpegLab's storage integration is its use of the TUS protocol for file uploads.

What is TUS?

TUS is an open protocol for resumable file uploads built on HTTP. It was created to solve a fundamental problem: uploading large files over unreliable networks is fragile. With TUS, uploads can be paused, resumed, and retried if interrupted.

As the TUS protocol website explains: "TUS is a protocol for resumable file uploads. It provides a mechanism for clients to upload files to a server in a resumable way".

Video files are large by nature. A 4K video can be tens of gigabytes. Traditional HTTP uploads treat the entire file as a single chunk — if the connection drops at 95%, the whole upload fails. This is unacceptable for teams working with high‑resolution video.

How TUS Works

When you upload a file using TUS:

  1. The client initiates an upload with the server, receiving a unique upload ID.
  2. The file is split into chunks, and each chunk is uploaded independently.
  3. If an upload is interrupted, the client can resume from the last successfully uploaded byte.
  4. Progress is tracked persistently, so uploads can survive browser refreshes or network changes.
  5. When all chunks are uploaded, the server assembles the file and makes it available.
File split into chunks TUS Server Client (resume if interrupted)
(Network interruption → resume from last byte → upload completes)

Why This Matters for Teams

For teams collaborating on video projects, TUS uploads are transformative:

📁
Any File Size
Upload 4K, 8K, or even RAW footage without size limits
⏸️
Pause & Resume
Stop an upload and resume later — no starting over
🔄
Automatic Retry
Network drops? TUS retries from the last byte
📊
Progress Tracking
See exactly how much of the file has been uploaded
👥
Team Efficiency
No more wasted time re-uploading large files
🔒
Secure & Authenticated
TUS uploads use JWT authentication from Supabase

As one video team lead described: "TUS has been a game-changer. Our editors used to dread uploading 4K proxies over hotel Wi-Fi. Now they can pause and resume, and the upload always completes".

FFmpegLab's TUS Implementation

FFmpegLab integrates TUS uploads directly into its Supabase Storage workflow:

As the Supabase Storage documentation explains: "TUS allows clients to resume an upload after an interruption". This is essential for video production where internet connections are often variable and file sizes are large.

Core Concepts: Auth, Buckets, RLS, and Variables

Before diving into the setup, let's understand the key concepts:

Authentication (Supabase Auth)

Supabase Auth provides email/password and magic link authentication. When a user logs in, they receive a JWT (JSON Web Token) that contains their user ID (sub claim). This JWT is used to authenticate all storage requests.

As one developer explains: "The JWT is passed with every request to Supabase, and the RLS policies use it to determine what data the user can access".

Storage Buckets

Buckets are "distinct containers for files and folders". You can think of them as "super folders". For FFmpegLab, we'll use a bucket named prod (the default) or a custom name.

Buckets can be either public or private. Public buckets are accessible to anyone with the URL, while private buckets require authentication or signed URLs. For per‑user storage, we'll use a private bucket with RLS policies.

Per‑User RLS Policies

RLS policies are security rules that control access to your files. "By default Storage does not allow any uploads to buckets without RLS policies". You selectively allow certain operations — downloads (SELECT), uploads (INSERT), updates (UPDATE), or deletes (DELETE) — by creating RLS policies on the storage.objects table.

Per‑user policies use the auth.jwt() function to get the current user's ID and ensure they can only access files in their own folder:

-- Check that the user owns the folder they're accessing
storage.foldername(name)
-- returns the folder path as an array

The SUPABASE_STORAGE_BUCKET Environment Variable

FFmpegLab uses the SUPABASE_STORAGE_BUCKET environment variable to know which bucket to use for storage operations. The default value is prod.

If you create a bucket with a different name (e.g., ffmpeglab-assets), you must set this variable accordingly.

Prerequisites

Before you begin, make sure you have:

Step 1: Create a Supabase Project

The first step is to create a Supabase project that will host your storage.

Step 1.1
Sign up or log in
Go to supabase.com and sign up for an account. You can use GitHub login for a quick start.
Step 1.2
Create a new project
Click New Project and fill in the details: Name (e.g., "ffmpeglab"), Database Password (use a strong password), Region (choose the closest to your users), and Pricing Plan (select Free).
Step 1.3
Wait for creation
Click Create new project and wait for the project to be created. This typically takes 1-2 minutes.

Step 2: Configure Authentication

Users must be authenticated before they can access storage. Supabase Auth supports both email/password and magic link authentication.

Step 2.1
Navigate to Authentication
In the Supabase project dashboard, click Authentication in the left sidebar.
Step 2.2
Configure email provider
In the Providers tab, enable the Email provider. You can choose between Password (traditional sign‑up with email and password) or Magic Link (passwordless login).
Step 2.3
Customise email templates (optional)
You can customise the email templates for magic link or password reset emails in the Email Templates section.

As the Supabase Auth guide explains: "Magic links are a passwordless authentication method where users receive a one-time login link via email. This is simpler and more secure than passwords".

Step 3: Create the Storage Bucket

Once your project is ready and authentication is configured, you need to create a storage bucket. The default bucket name used by FFmpegLab is prod, but you can use any name.

Step 3.1
Navigate to Storage
In the Supabase project dashboard, click Storage in the left sidebar.
Step 3.2
Create a new bucket
Click New Bucket and enter a name — for example, prod (the default) or ffmpeglab-assets. If you use a custom name, you'll need to set the SUPABASE_STORAGE_BUCKET environment variable accordingly.
Step 3.3
Choose public or private
Select Private for the bucket type. This ensures that files are not publicly accessible by default and must be accessed via RLS policies.
Step 3.4
Click Create bucket
Finalise the bucket creation.

As noted in the Supabase documentation: "Buckets are distinct containers for files and folders. You can think of them like 'super folders'".

Step 4: Configure Per-User RLS Policies

This is the most critical step. Without RLS policies, your bucket will not allow any uploads. You need to create policies that grant the necessary permissions per user.

Step 4.1
Navigate to Policies
In the Storage section, click on your bucket, then click the Policies tab.
Step 4.2
Add policies for each operation
Click Add Policies in the OBJECTS table to add policies for files. You need to create policies for SELECT (downloads), INSERT (uploads), UPDATE (updates), and DELETE (deletes).
Step 4.3
Choose the policy type
Select For full customization to write the policy manually.
Step 4.4
Write per‑user INSERT policy (uploads)
Create a policy that allows authenticated users to upload files to their own folder:
-- Allow authenticated users to upload to their own folder
create policy "Allow authenticated uploads"
on storage.objects
for insert
to authenticated
with check (
  bucket_id = 'prod' and
  (storage.foldername(name))[1] = (select auth.jwt()->>'sub')
);
Step 4.5
Write per‑user SELECT policy (downloads)
Create a policy that allows authenticated users to download files from their own folder:
-- Allow authenticated users to download files from their own folder
create policy "Allow authenticated downloads"
on storage.objects
for select
to authenticated
using (
  bucket_id = 'prod' and
  (storage.foldername(name))[1] = (select auth.jwt()->>'sub')
);
Step 4.6
Write per‑user UPDATE policy (updates)
Create a policy that allows authenticated users to update files in their own folder:
-- Allow authenticated users to update files in their own folder
create policy "Allow authenticated updates"
on storage.objects
for update
to authenticated
using (
  bucket_id = 'prod' and
  (storage.foldername(name))[1] = (select auth.jwt()->>'sub')
);
Step 4.7
Write per‑user DELETE policy (deletes)
Create a policy that allows authenticated users to delete files in their own folder:
-- Allow authenticated users to delete files in their own folder
create policy "Allow authenticated deletes"
on storage.objects
for delete
to authenticated
using (
  bucket_id = 'prod' and
  (storage.foldername(name))[1] = (select auth.jwt()->>'sub')
);

As the Supabase documentation explains: "An easy way to get started would be to create RLS policies for SELECT, INSERT, UPDATE, DELETE operations and restrict the policies to meet your security requirements".

Important: If you're using a custom bucket name, replace 'prod' with your bucket name in all policies.

Step 5: Get Your Credentials

To connect FFmpegLab to Supabase Storage, you need two pieces of information.

Step 5.1
Navigate to API settings
In the Supabase dashboard, click SettingsAPI in the left sidebar.
Step 5.2
Copy your Project URL
In the Configuration section, copy your Project URL (e.g., https://your-project.supabase.co).
Step 5.3
Copy your Anon Key
In the Project API keys section, copy your anon / public key.

As one guide notes: "Copy your project URL and anon key". These are the credentials FFmpegLab will use to authenticate with Supabase Storage.

Step 6: Configure FFmpegLab

With your Supabase credentials ready, you can now configure FFmpegLab to use Supabase Storage.

FFmpegLab requires the following environment variables:

SUPABASE_HOST=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-supabase-anon-key
SUPABASE_STORAGE_BUCKET=prod

As documented in the FFmpegLab README, these variables tell the client where to connect, how to authenticate, and which bucket to use. The SUPABASE_STORAGE_BUCKET variable defaults to prod if not set.

Example Docker Compose configuration:

# docker-compose.yml
services:
  ffmpeglab:
    image: ffmpeglab/ide:main
    ports: - "8080:8080"
    environment:
      - FFMPEGLAB_HOST="http://localhost:8080/webapp/?"
      - PUBLIC_HOST="https://localhost:8080/"
      - SUPABASE_HOST="https://your-project.supabase.co"
      - SUPABASE_ANON_KEY="your-supabase-anon-key"
      - SUPABASE_STORAGE_BUCKET="prod"

Important: The SUPABASE_ANON_KEY is a client-side key and can be safely exposed in the client. The service role key should never be exposed to the client — it is used only for server-side operations.

As the Supabase documentation emphasises: "The service role key should be kept secret and never exposed to the client".

If you're using a custom bucket name (e.g., ffmpeglab-assets), set SUPABASE_STORAGE_BUCKET accordingly:

SUPABASE_STORAGE_BUCKET=ffmpeglab-assets

Step 7: Verify the Connection

Once FFmpegLab is configured, verify that the connection to Supabase Storage is working:

  1. Open FFmpegLab in your browser at http://localhost:8080/webapp/
  2. Sign up or log in using email/password or magic link authentication
  3. Create a new project or open an existing one
  4. Export a video — the rendered video should be uploaded to Supabase Storage via TUS
  5. Check your Supabase Storage bucket to confirm the file appears in the user's folder
  6. Test resumable uploads by interrupting the upload and resuming it

If you encounter issues, check the browser's developer console for errors related to SUPABASE_HOST, SUPABASE_ANON_KEY, or SUPABASE_STORAGE_BUCKET.

Troubleshooting

IssueLikely CauseFix
"403 Forbidden" on upload Missing or incorrect RLS policies Create INSERT policy on storage.objects with proper per-user conditions
TUS upload fails or hangs CORS configuration missing Ensure CORS allows the TUS endpoints. Add your domain to Supabase's allowed origins.
"Supabase connection failed" Invalid SUPABASE_HOST or SUPABASE_ANON_KEY Verify credentials in Supabase project settings
Can't download files No SELECT policy Create SELECT policy on storage.objects for the user's folder
Wrong bucket used SUPABASE_STORAGE_BUCKET not set or incorrect Set SUPABASE_STORAGE_BUCKET to the correct bucket name
RLS policy not working Policy syntax error or wrong target roles Verify policy definition and set to authenticated
Authentication fails Supabase Auth not configured Enable Auth in your Supabase project settings

As one guide notes: "Important: must correctly configure RLS policies, otherwise you will get 403 errors and cannot upload".

Frequently Asked Questions (FAQ)

What is Supabase Storage?

Supabase Storage is a cloud storage service that integrates with Supabase's PostgreSQL database. It allows you to store and serve files like images, GIFs, and videos, with built-in security controls through Row Level Security (RLS) policies.

What is the TUS upload protocol and why does FFmpegLab use it?

TUS is a protocol for resumable file uploads. FFmpegLab uses it because video files are large. TUS allows uploads to be paused, resumed, and retried if interrupted. This is essential for teams working with high-resolution video where network failures are common. As the TUS protocol explains: "TUS provides a mechanism for clients to upload files to a server in a resumable way".

How does FFmpegLab authenticate users for Supabase Storage?

FFmpegLab uses Supabase Auth with email/password or magic link authentication. When a user logs in, they receive a JWT that is used to authenticate all storage requests. The JWT contains the user's ID, which is used by RLS policies to enforce per-user access control.

What is the SUPABASE_STORAGE_BUCKET environment variable?

SUPABASE_STORAGE_BUCKET is an environment variable that tells FFmpegLab which storage bucket to use for storing assets. The default value is 'prod'. You can change this to any bucket name you've created in your Supabase project.

How do per-user RLS policies work in Supabase Storage?

Per-user RLS policies ensure that users can only access files in their own folder. When a user uploads a file, it's stored in a folder with their user ID. RLS policies check the JWT to verify that the user owns the folder they're trying to access, preventing them from seeing or modifying other users' files.

Is Supabase Storage free?

Yes. Supabase offers a generous free tier that includes 1 GB of database storage and 1 GB of file storage, which is sufficient for personal use and small team projects.

Final Word

Setting up Supabase Storage with FFmpegLab transforms it from a local editor into a collaborative team platform with secure, per‑user cloud storage. With magic link authentication, per‑user RLS policies, and TUS resumable uploads, your team can upload, share, and manage video assets of any size — reliably and securely.

The setup is straightforward: create a Supabase project, configure authentication, create your bucket and RLS policies, set your environment variables, and deploy. Whether you use the default prod bucket or a custom name, FFmpegLab gives you full control over your team's data.

Key takeaways for your deployment:

Next time you're setting up FFmpegLab for your team, you'll know exactly how to connect it to Supabase Storage for secure, scalable, and reliable cloud storage.

✦  Fresh from the render queue

Better FFmpeg workflows, delivered.

Get practical commands, new templates, and deep-dive guides for the edits that are usually hardest to get right.

✓  Copy-pasteable commands    ✓  Editor templates    ✓  No noise
One useful email at a time.