0up is a zero-knowledge, open-source, encrypted file sharing service.
From Wikipedia: Zero-knowledge refers to an online service that stores, transfers or manipulates data in a way that maintains a high level of confidentiality, where the data is only accessible to the data's owner (the client), and not to the service provider.
- Files are encrypted browser-side before being uploaded to an S3 compatible storage service.
- A shareable link is generated with the decryption key as part of the anchor component (
#
) of the URL. (Anchor components are never sent to the server and therefore the decryption key always remains with the client.) - Using the generated link, files can be downloaded and decrypted browser-side.
In addition to the hosted version of 0up (https://0up.io), you're free to clone, customize, and host 0up in your own environment.
- An account with an S3-compatible storage service. We recommend Backblaze B2
- A PostgreSQL database
- Node.JS 18+
Using the S3-compatible provider of your choice, create a new bucket. For our examples below, we'll be using Backblaze B2
Create a public bucket. Adding encryption is optional, and arguably redundant, but it doesn't hurt.
We want files to automatically be deleted after 24 hours. To do that, we'll create a custom lifecycle policy.
Click on Lifecycle Settings
and select Use custom lifecycle rules
We'll create a prefix of 1/
and apply a 1-day lifecycle policy to it.
CORS must be enabled on your S3 bucket to allow uploads and downloads. For B2, this requires installing the B2 CLI (the CORS Rules
option in the B2 web interface will not suffice for our purposes).
Once you've installed and configured the B2 CLI, we can set the CORS rules with the following command. Make sure to set your particular values for allowedOrigins
, and your-bucket-name
:
b2 update-bucket \
--corsRules '[{"corsRuleName": "downloadFromAnyOriginWithUpload","allowedOrigins": ["http://localhost:5173","https://your-site.example"],"allowedHeaders": ["*"],"allowedOperations": ["s3_head","s3_get","s3_put"],"exposeHeaders": ["ETag"],"maxAgeSeconds": 3600}]' \
your-bucket-name allPrivate
Create a PostgreSQL database, making note of the credentials (user, password, host, database name) as we'll need those during configuration.
To get started hosting your own instance of 0up, clone (or fork and clone) this repo.
git clone https://github.com/0sumcode/0up.git
cd 0up
npm i
Copy .env.example
to .env
. Then open and edit the .env
file and configure the database and S3 parameters accordingly.
cp .env.example .env
Next, deploy the database schema:
npx prisma migrate deploy
Now that all your configuration parameters have been set, you should be able to test your instance locally. The dev instance makes it easy to test and make customizations.
npm run dev
Your 0up instance can easily be deployed to virtually any hosting platform so long as it can run Node.JS and talk to a PostgreSQL database - including frontend hosting platforms like Vercel.
Once you've setup your production environment, ensure you've enabled CORS as noted above for your production domain and set your .env
variables to your production values. To build for production, run:
npm run build
There is an example configuration for running 0up in a Docker Compose-based setup in the the docker
subdirectory.
A database cleanup cronjob (GET https://your.host.here/api/cron/cleanup
) can be called at regular intervals to purge expired data from the database. The request requires an Authorization
header with the value you've set in your .env file under PRIVATE_CRON_SECRET
. You may use a service like Pipedream for this, or simply create a cronjob to run a command like:
curl -H "Authorization: YOUR_CRON_SECRET" "https://your.host.here/api/cron/cleanup"