Privacy Tools Guide

Share sensitive documents using client-side encryption tools (Tresorit, Sync.com), self-hosted solutions (Nextcloud with encryption), or command-line approaches (encrypted tar archives with age). Choose based on your requirements: hosted solutions provide convenience and automatic expiration, self-hosted solutions offer control but require infrastructure maintenance, while command-line tools provide maximum security at the cost of usability. For API credentials and authentication tokens, use temporary access grants with time limits instead of static credentials wherever possible.

Understanding the Threat Model

Before implementing any file sharing solution, identify what you’re protecting against. Common threats include:

Each protection mechanism addresses different threats. End-to-end encryption protects against interception but doesn’t hide metadata. Self-hosted solutions give you control over data retention but require proper hardening.

Encrypt Before You Share

The foundation of secure file sharing is encrypting files before transmission. This ensures that even if the transport layer is compromised, your data remains unreadable.

Using GPG for Command-Line Encryption

GPG provides industry-standard encryption without relying on cloud services:

# Generate a key (do this once)
gpg --full-generate-key

# Encrypt a file for a recipient
gpg --encrypt --recipient developer@example.com sensitive-document.pdf

# Encrypt with a passphrase instead
gpg --symmetric --cipher-algo AES256 business-plan.ods

The encrypted file (.gpg extension) can be sent through any channel—email, cloud storage, or messaging apps. The recipient decrypts it with:

gpg --decrypt sensitive-document.pdf.gpg > sensitive-document.pdf

For teams, establish a shared GPG key or use a key management system. Store private keys securely, preferably on hardware tokens or encrypted storage with strong passphrases.

When you need to share files with non-technical users, self-destructing encrypted links provide a balance between security and convenience. Services like PrivateBin offer self-hosted options:

# Example: Using PrivateBin API via curl
curl -X POST https://your-privatebin-instance.com/api/v1/paste \
  -H "Content-Type: application/json" \
  -d '{
    "data": "BASE64_ENCODED_FILE_CONTENT",
    "expire": "1day",
    "burnafterreading": true,
    "password": "ENCRYPTION_PASSWORD"
  }'

This approach ensures the server never sees plaintext data—all encryption happens client-side.

Self-Hosted File Sharing Solutions

Self-hosted solutions give you complete control over data, compliance, and retention policies.

Syncthing for Continuous Sync

Syncthing is an open-source continuous file synchronization program that operates peer-to-peer:

# Install on Linux
sudo apt install syncthing

# Start the service
syncthing serve

# Access the web UI at http://localhost:8384

Configure device IDs and shared folders through the web interface. All transfers use TLS and are end-to-end encrypted. The service runs locally—no cloud storage involved.

Key advantages for developers:

Nextcloud provides a full collaborative platform with file sharing, calendar, and contacts:

# Deploy with Docker
docker run -d \
  --name nextcloud \
  -p 8080:80 \
  -v nextcloud_data:/var/www/html \
  -e NEXTCLOUD_ADMIN_USER=admin \
  -e NEXTCLOUD_ADMIN_PASSWORD=strong_password_here \
  nextcloud:latest

Enable end-to-end encryption in the admin settings for sensitive documents. This encrypts files on the client side before upload—the server stores only encrypted data.

For production deployments, use reverse proxies with HTTPS (Let’s Encrypt), proper database backends (PostgreSQL), and regular backups.

Secure Transfer Utilities

curl with SFTP/SCP

For single-file transfers between servers, use secure protocols:

# Upload via SCP
scp -P 22 -r ./sensitive-folder user@remote-server:/secure/path/

# Upload via SFTP with key authentication
sftp -i ~/.ssh/id_ed25519 -P 22 user@remote-server
put -r ./documents/*

Always use key-based authentication and disable password authentication on your SSH servers.

Rclone for Cloud Storage Encryption

If you must use cloud storage, encrypt files before upload using rclone:

# Configure an encrypted remote
rclone config

# Follow prompts to create a crypt backend:
# Choose "n" for New remote
# Name: encrypted-backup
# Storage: crypt
# Remote: your-backup-bucket:/encrypted
# Password: generate strong random password
# Salt: generate random salt

# Copy files with automatic encryption
rclone copy ./local-folder encrypted-backup:documents/

Files are encrypted client-side with AES-256 before storage. The cloud provider sees only opaque blobs.

File Sharing Checklist

Before sharing sensitive documents, verify these items:

  1. Encryption verified: Confirm files are encrypted with strong algorithms (AES-256, RSA-4096)
  2. Key management: Ensure recipients have secure methods to obtain decryption keys
  3. Link expiration: Set time limits on any shared links
  4. Access logging: Enable audit logs to track who accessed what and when
  5. Secure deletion: Use tools that overwrite file data before deletion
  6. Metadata removal: Strip EXIF data, author information, and revision history before sharing
# Remove metadata from images before sharing
exiftool -all= document-scan.jpg

# Securely delete files (overwrite before removal)
shred -u sensitive-file.pdf

Ephemeral vs Persistent File Sharing

Different scenarios require different retention models. Understanding when to use each approach is crucial:

Ephemeral File Sharing (Self-Destructing)

Use when sharing temporary credentials, access tokens, or confidential documents that should not exist after viewing:

PrivateBin Setup:

# Docker deployment of PrivateBin (ephemeral encrypted paste service)
docker run -d \
  --name privatebin \
  -p 8080:80 \
  -v privatebin_data:/srv/data \
  privatebin/nginx:latest

# Access at http://localhost:8080
# Upload file, set expiration (5 minutes to 1 month), enable burn-after-reading

Jami (previously Ring) for P2P Transfer:

# CLI tool for peer-to-peer encrypted file transfer
# No server, files never stored
jami account create --archive=/tmp/account.gz --password yourpass

# Share file (link appears in terminal)
jami file send <contact-id> /path/to/file.pdf

# Recipient receives notification and can accept/reject

Persistent File Sharing with Access Control

When documents need to remain accessible but with strict controls:

Nextcloud with Per-Share Expiration:

# Share a file with automatic expiration
curl -X POST "https://your-nextcloud.com/ocs/v2.php/apps/files_sharing/api/v2/shares" \
  -u admin:password \
  -H "OCS-APIRequest: true" \
  -d "path=/documents/contract.pdf&shareType=3&expireDate=2026-03-31&permissions=1"

SeaDrive for Encrypted Cloud Storage:

# Encrypted personal cloud storage accessible from multiple devices
# All files encrypted before upload; only you hold keys
seafile-cli init -s https://your-seafile.com -u your@email.com -p password
seafile-cli create-repo Documents
seafile-cli share-repo Documents your-team@company.com rw

Managing Encryption Keys Operationally

For team environments, key management becomes critical. Here are tested patterns:

Group Key Management

When multiple team members need to decrypt files:

# Example: Rotating shared encryption key
import hashlib
from datetime import datetime, timedelta

class SharedKeyRotation:
    def __init__(self, base_secret, rotation_period_days=90):
        self.base_secret = base_secret
        self.rotation_period = rotation_period_days

    def get_current_key(self):
        """Generate key based on current time period"""
        today = datetime.utcnow().date()
        period = today.toordinal() // self.rotation_period

        key_material = f"{self.base_secret}:{period}".encode()
        return hashlib.sha256(key_material).hexdigest()

    def list_valid_keys(self, periods_back=2):
        """List keys valid for decrypting recent files"""
        today = datetime.utcnow().date()
        current_period = today.toordinal() // self.rotation_period

        valid_keys = []
        for i in range(periods_back + 1):
            period = current_period - i
            key_material = f"{self.base_secret}:{period}".encode()
            key = hashlib.sha256(key_material).hexdigest()
            valid_keys.append({
                'key': key,
                'period': period,
                'valid_until': today - timedelta(days=(current_period - period) * self.rotation_period)
            })

        return valid_keys

# Usage
rotator = SharedKeyRotation("your-team-secret-base", rotation_period_days=30)
print(f"Current key: {rotator.get_current_key()}")
print(f"Valid decryption keys: {rotator.list_valid_keys()}")

Hardware Key Distribution

For maximum security, distribute encryption keys via hardware:

# Create encrypted USB drives for key distribution
# 1. Create encrypted partition
diskutil partitionDisk /dev/diskX GPTFormat JHFS+ "EncryptedKeys" 0b

# 2. Generate and encrypt key
gpg --symmetric --cipher-algo AES256 team-master-key.txt

# 3. Copy encrypted key to USB drive
cp team-master-key.txt.gpg /Volumes/EncryptedKeys/

# 4. Distribute USB drives via secure courier
# 5. Recipients decrypt with long passphrase
gpg --decrypt team-master-key.txt.gpg > team-master-key.txt

File Sharing Compliance Checklist

Before sharing any sensitive documents, verify these technical and legal requirements:

Pre-Share Verification:
  Encryption:
    - Algorithm strength: AES-256 minimum
    - TLS version: 1.3 or higher
    - Key derivation: PBKDF2, bcrypt, or Argon2

  Access Control:
    - Recipient verification enabled
    - Time-based expiration set
    - IP restriction applied (if available)
    - Audit logging enabled

  Data Minimization:
    - Metadata stripped: EXIF, author, revision history
    - Only necessary files included
    - Sensitive fields redacted if needed

  Legal Compliance:
    - GDPR: Legal basis for processing identified
    - CCPA: Privacy notice provided
    - HIPAA (if applicable): BAA signed with provider
    - Industry-specific: Sector regulations checked

Post-Share Monitoring:
  - Access logs reviewed within 24 hours
  - Recipient acknowledgment documented
  - Expiration verified on schedule
  - Deletion confirmed in logs

Troubleshooting Common Sharing Problems

Recipient cannot decrypt file:

# Verify GPG key import succeeded
gpg --list-keys recipient@email.com

# If missing, recipient needs to provide public key
gpg --import recipient_public_key.asc

# Test encryption/decryption locally first
echo "test" | gpg --encrypt --armor --recipient recipient@email.com | gpg --decrypt

Self-hosted service reaches storage limits:

# Check Nextcloud disk usage
sudo du -sh /var/www/nextcloud/data/*/files

# Implement retention policy
# Edit /var/www/nextcloud/apps/files/lib/Command/CleanupFileLocks.php
# Or use cron job for automatic purging:
0 2 * * * nextcloud maintenance:mode --on && nextcloud trashbin:cleanup && nextcloud maintenance:mode --off

VPN/proxy interferes with WebRTC in Syncthing:

# Configure Syncthing to use specific relay servers
# In configuration JSON:
{
  "syncThingIgnoredDevices": [],
  "discovery": {
    "servers": [
      "https://discover.syncthing.net/?insecure",
      "https://discovery.syncthing.net/"
    ]
  },
  "relays": [
    {
      "address": "relay.syncthing.net:22067",
      "dynamic": true,
      "statusAddr": "http://stat.syncthing.net/endpoint/[CLIENT-ID]",
      "locations": ["default"]
    }
  ]
}

Built by theluckystrike — More at zovo.one