End-to-end encrypted file sharing
Server app for blindsend, an open source tool for private, end-to-end encrypted file exchange. It provides the REST API for managing file exchange workflow.
blindsend server is built using Scala 3 and various typelevel libraries:
- cats-effect for flow control
- http4s for http server
- circe for JSON
- doobie for database connection
Other libraries include:
- logback-classic and janino for logging
- google-cloud-storage for Google Storage link signing
- pureconfig to load configuration files
Link information is stored in the PostgreSQL database. The server connects to it using the doobie library and HikariCP.
Database consist of a single table defined as:
CREATE TABLE public.links (
id varchar NOT NULL,
workflow varchar NOT NULL,
stage int2 NOT NULL,
salt varchar NULL,
passwordless bool NULL,
enc_metadata varchar NULL,
seed_hash varchar NULL,
"date" timestamp NOT NULL,
finished bool NOT NULL,
num_files int2 NULL,
sender_pk varchar NULL,
file_ids _varchar NULL,
wrapped_requester_sk varchar NULL,
requester_pk varchar NULL,
life_expectancy int4 NULL DEFAULT 7,
CONSTRAINT links_pkey PRIMARY KEY (id)
)
blindsend stores the encrypted files in the Cloud Storage on the Google Cloud platform.
Files are uploaded from the blindsend web client directly to a Google Storage bucket. For that purpose, the server creates the signed links for provided file ids and sends them to the web client. Links are generated for both uploading and downloading files.
To access a GCP bucket from the web client, we need to configure the CORS on the bucket.
cors.json
[
{
"origin": [ "*" ],
"method": [ "GET", "POST", "PUT" ],
"responseHeader": [ "content-type", "content-length", "x-goog-resumable", "x-upload-content-length", "x-goog-content-length-range", "x-goog-custom-time" ],
"maxAgeSeconds": 3600
}
]
CORS setting can be set by the gsutil tool:
gsutil cors set cors.json gs://bucket-name
The bucket can be configured to delete files after a certain condition is met.
We set the Delete action when the file's custom time is reached. Custom time is set by a header x-goog-custom-time sent when uploading a file.
Currently, custom time is current time + 168 hours (7 days).
lifecycle.json
{
"lifecycle": {
"rule": [
{
"action": { "type": "Delete" },
"condition": { "daysSinceCustomTime": 0 }
}
]
}
}
Lifecycle setting can be set by the gsutil tool:
gsutil lifecycle set lifecycle.json gs://bucket-name
To successfully connect to the database and generate valid signed links for Google Storage, a configuration file must be created.
The following is the example configuration:
storage = { # Google Storage configuration
project = "blindsend", # GCP project where bucket is set
bucket = "blindsend-files" # Google Storage bucket for uploading files.
}
db = { # PostgreSQL database configuration
host = "127.0.0.1", # host IP
port = 5432, # port, default value is 5432
user = "postgres", # database user, default value is postgres
database = "postgres", # name of the database containing links table, default value is postgres
password = "secret" # database password
}
To build an executable file:
- Install sbt and run:
This command will create a blindsend.jar executable file in target/scala-3.1.0 folder.
sbt assembly
- Create a configuration file application.json.
- Create a GCP service account (with permission for Cloud Storage) and download the keys.
- Set GOOGLE_APPLICATION_CREDENTIALS environment variable to point to the keys file.
export GOOGLE_APPLICATION_CREDENTIALS="/account.json"
To run the server, make sure the application.json configuration file is in the secrets directory (secrets and blindsend.jar are in the same directory) and run:
java -jar ./blindsend.jar
This command will start the server on http://0.0.0.0:9000.
blindsend is under development by a team of software engineers at blindnet.io and several independent cryptography experts.
All community participation is subject to blindnet’s Code of Conduct.
Stay up to date with new releases and projects, learn more about how to protect your privacy and that of our users, and share projects and feedback with our team.
- Join our Slack Workspace to chat with the blindnet community and team
- Follow us on Twitter to stay up to date with the latest news
- Check out our Openness Framework and Product Management on Github to see how we operate and give us feedback.
The blindsend-server is available under MIT (and here is why).