A modern, flexible, enterprise-grade file storage and sync platform built in Go. Inspired by Seafile Pro but designed for multi-cloud storage with support for immediate (S3/Disk) and archival (Glacier) storage classes.
Notice: Test it at your own risk and create issues here. The project is somewhat AI slop, but we will get it to be better over time with Claude's help xD.
SesameFS aims to be a world-class replacement for enterprise file sync and share (EFSS) solutions with these key differentiators:
- Multi-Region Storage with Intelligent Routing: Multiple backends with hostname-based routing and automatic failover
- Smart Two-Tier Storage: Hot (S3 Standard/IA) and cold (Glacier IR/Deep Archive) with automatic tiering
- Distributed-First Architecture: Cassandra + stateless API servers = global scale
- SHA-256 Internal Storage: Modern security with transparent SHA-1 translation for Seafile compatibility
- Modern Authentication: OIDC-native with accounts.sesamedisk.com plus user API keys for desktop clients, CLI, and automation
- True Multi-Tenancy: Complete tenant isolation with per-tenant storage backends
- Seafile Client Compatible: Works with existing Seafile desktop and mobile apps
| Component | Technology | Version |
|---|---|---|
| Language | Go | 1.25.5 |
| Database | Apache Cassandra | 5.0.6 |
| Object Storage | S3-compatible | - |
| Archive Storage | AWS Glacier | - |
| Authentication | OIDC | - |
| API Framework | Gin | 1.10.0 |
| Chunking | FastCDC | - |
| Container Base | Debian Trixie | 13 slim |
| Feature | Seafile | SesameFS |
|---|---|---|
| Storage Backend | Local filesystem only | S3, Glacier, Disk - configurable |
| Multi-Region Storage | Single backend | Multiple backends with hostname routing |
| Storage Failover | None | Automatic failover to healthy backends |
| Cold Storage | Not supported | Smart cold tier (auto-selects Glacier IR/Deep) |
| Database | MySQL/PostgreSQL (single node) | Cassandra (global, distributed) |
| Chunking | Rabin CDC, fixed sizes | FastCDC, adaptive to network speed |
| Chunk Sizes | Fixed 1-8MB | Adaptive 2-256MB based on connection |
| Hash Security | SHA-1 everywhere | SHA-256 internally (SHA-1 translated) |
| Authentication | Custom + LDAP | OIDC-native |
| Multi-tenancy | One hostname per instance | Multiple hostnames per cluster |
| Session State | Sticky sessions required | Stateless (any server, any request) |
| Upload Resume | Same server only | Any server (distributed tokens) |
| Security Scanning | ClamAV only (optional) | ClamAV + YARA + URL scanning |
| Phishing Detection | Not available | YARA rules + document analysis |
| Deployment | C + Python (complex) | Go (single binary) |
- Project structure and Go modules setup
- Configuration management (YAML + env overrides)
- Cassandra connection and schema
- Library CRUD operations
- S3 storage integration (MinIO compatible)
- Basic file upload/download via
/seafhttp/ - Token-based file access (configurable TTL)
- FastCDC chunking with adaptive sizing
- Block storage layer (content-addressable)
- Block check/upload/download endpoints
- Distributed token store (Cassandra-backed, stateless)
Tested with: Seafile Desktop Client for macOS - login, sync, file upload all working.
-
/api2/legacy route aliases -
GET /api2/repos/- List libraries -
GET /api2/repos/:id/dir/?p=/- Directory listing -
POST /api2/auth-token/- Auth token exchange (dev credentials oremail + API key) - Sync protocol endpoints (
/seafhttp/repo/:id/*) - Commit/FS object model in Cassandra
Status: Core functionality working. See docs/FRONTEND.md.
- Library list (My Libraries)
- Directory browsing inside libraries
- File/folder icons and thumbnails
- Create new library
- Delete library (single and batch)
- Create folder
- Delete folder/file (single and batch)
- File locking UI (lock icon, lock/unlock actions)
- File tags display and management
- Share info dialog (view shares)
- File upload via web
- File download via web
- Copy/Move operations
- History/versions
- Search
- Content-addressable block storage (S3)
- Block deduplication (by SHA256)
- Distributed token store (Cassandra TTL)
- Any server can handle any request (stateless)
-
POST /api/v2/files/commit- Finalize chunked upload - Upload session tracking (for resume across servers)
-
hostname_mappingstable in Cassandra - Tenant resolution middleware (hostname -> org_id)
- URL generation uses request hostname
- Per-org storage configuration (S3 regions)
- Per-org settings and quotas
- Multi-region S3 routing (nearest to user)
- Directory operations (list, create, delete)
- File operations (info, delete, move, copy, batch delete)
- File locking (lock, unlock, check lock status)
- File tagging (create, update, delete tags)
- Share info display (internal shares, links)
- Quota management per org
- Admin APIs
- Audit logging
- Share links (view - create/delete pending)
- OIDC authentication integration
- Glacier integration (upload + restore)
- ClamAV integration (TCP, INSTREAM protocol)
- YARA rules engine (phishing detection)
- URL extraction and scanning (Safe Browsing, PhishTank)
- Office document analysis (oletools)
- PDF analysis (pdfid/pdf-parser)
- Share link abuse prevention
- WOPI protocol endpoints (CheckFileInfo, GetFile, PutFile)
- JWT authentication
- Co-authoring with real-time sync
- File locking during edit
- Document conversion
- Search (Elasticsearch)
- Thumbnails and previews
- Client-side encryption
- Real-time notifications (WebSocket)
- File versioning UI
- Docker & Docker Compose v2 - Install Docker
- Go 1.25+ - Install Go (only needed to run outside Docker)
# Clone the repository
git clone https://github.com/Sesame-Disk/sesamefs.git
cd sesamefs
# Create your local config (defaults work out of the box)
cp .env.example .env
# Start the full dev stack (Cassandra + MinIO + SesameFS + OnlyOffice)
docker compose up --build
# Test the API
curl http://localhost:3000/ping
# -> "pong"
# Test with a dev token
curl http://localhost:3000/api2/account/info/ \
-H "Authorization: Token dev-token-admin"
# Billing portal redirect (Docker dev defaults to the Sesame test billing URL)
curl -I http://localhost:3000/billing/
curl -I http://localhost:3000/accounts/delete/
# Stop when done
docker compose down/billing/ is always an internal SesameFS route. The backend checks authentication and redirects to the external portal configured by BILLING_URL. In local Docker Compose, that env var defaults to https://t-accounts.sesamedisk.com/billing/ for testing only.
/accounts/delete/ follows the same pattern. SesameFS validates authentication first, then redirects to the external Accounts URL configured by ACCOUNTS_DELETE_ACCOUNT_URL.
# 1. Start the infrastructure and run Cassandra bootstrap once
docker compose up cassandra minio minio-init cassandra-bootstrap -d
# 2. Run SesameFS locally against it
go run ./cmd/sesamefs serve
# 3. Run tests
go test ./...cp .env.prod.example .env
# Fill in all values in .env, then bring up Cassandra first:
docker compose -f docker-compose.prod.yml up -d cassandra
# Run the one-shot Cassandra bootstrap explicitly from the designated node:
docker compose -f docker-compose.prod.yml --profile bootstrap up cassandra-bootstrap
# Start the normal app services:
docker compose -f docker-compose.prod.yml up -d sesamefs frontendIf SesameFS runs behind nginx or another reverse proxy, set server.trusted_proxies in your YAML config or SERVER_TRUSTED_PROXIES in .env to the exact proxy IP/CIDR values that are allowed to supply X-Forwarded-For and X-Real-IP. In the supported production chain client -> central nginx -> internal SesameFS nginx -> Go, the internal nginx, typically the nginx inside the frontend container, preserves the real client IP already resolved by the central nginx, so Go only needs to trust the internal nginx hop. This assumes that internal nginx is private and only reachable from trusted internal paths. Leaving it empty is the secure default and makes SesameFS use the direct peer IP instead.
See docs/DEPLOY.md for the full production guide (DNS, SSL, firewall, etc.).
# Bootstrap multi-region environment
./scripts/bootstrap.sh multiregion
# Run tests in container
./scripts/run-tests.sh multiregion all
# Stop the environment
./scripts/bootstrap.sh multiregion --downSee docs/MULTIREGION-TESTING.md for detailed testing scenarios.
SesameFS includes a web interface extracted from Seafile Pro (Seahub), modified to work as a standalone React SPA.
# Start backend + frontend nginx
docker compose up -d sesamefs frontend
# Open http://localhost:3000
# Login: admin@sesamefs.local / dev-token-123See docs/FRONTEND.md for detailed setup guide.
sesamefs/
├── cmd/sesamefs/ # Main application entry point
├── internal/
│ ├── api/ # HTTP handlers
│ │ ├── v2/ # REST API v2
│ │ └── sync.go # Seafile sync protocol
│ ├── chunker/ # FastCDC implementation
│ ├── storage/ # Storage backends (S3, Glacier, Disk)
│ ├── db/ # Cassandra repository layer
│ └── models/ # Domain models
├── frontend/ # React web UI
│ ├── Dockerfile # Multi-stage: node builder + nginx:alpine runtime
│ └── nginx.conf # SPA routing + proxy_pass to Go backend
├── nginx/
│ └── nginx.conf.template # Nginx config (SSL, proxy, OnlyOffice)
├── scripts/ # Dev/test scripts
├── docs/ # Detailed documentation
├── docker-compose.yaml # Development stack (MinIO, dev tokens)
├── docker-compose.prod.yml # Production stack (S3, OIDC, SSL)
├── configs/ # YAML config files (dev, prod, regions)
│ ├── config.docker.yaml # Config baked into the dev Docker image
│ ├── config.prod.yaml # Config mounted in production
│ ├── config.example.yaml # Base example config
│ ├── config-eu.yaml # EU multiregion sample
│ └── config-usa.yaml # USA multiregion sample
├── .env.example # Dev environment template
└── .env.prod.example # Production environment template
Unlike traditional Seafile (multiple ports), SesameFS uses a clean two-container split behind a single nginx entry point:
Internet → nginx (TLS, rate limiting)
├── /api2/, /api/v2/, /api/v2.1/, /seafhttp/, /d/, /u/d/, /lib/ → sesamefs (Go :8080)
└── / → frontend (nginx:alpine :80)
- Go backend (
sesamefs:8080): pure API + Seafile sync protocol. No SPA serving. - React frontend (
frontend:80): nginx:alpine serving the React build with SPA routing. - Outer nginx: TLS termination, rate limiting, CSP headers, mobile UA routing.
This is intentional for cloud-native deployments — frontend and backend can be built, scaled, and deployed independently.
| Document | Contents |
|---|---|
| docs/DEPLOY.md | Production deployment guide (VPS, SSL, S3, OIDC) |
| docs/ARCHITECTURE.md | Design decisions, storage architecture, GC, schemas |
| docs/API-REFERENCE.md | API endpoints, implementation status, compatibility |
| docs/TESTING.md | Test coverage, benchmarks, running tests |
| docs/MULTIREGION-TESTING.md | Multi-region testing guide |
| docs/FRONTEND.md | Web UI setup, patterns, Docker, troubleshooting |
| docs/OIDC.md | OIDC authentication configuration |
| docs/TECHNICAL-DEBT.md | Known issues, migration plans, incremental fixes |
| docs/MIGRATION-FROM-SEAFILE.md | Seafile migration guide |
| docs/LICENSING.md | Legal considerations |
MIT License (may change in future)
See LICENSE for details.
Note on Seafile Compatibility: SesameFS implements a Seafile-compatible API for interoperability purposes. SesameFS is an independent project, not affiliated with Seafile Ltd. See docs/LICENSING.md for details.
See CONTRIBUTING.md (coming soon)