S3Vault

Secure unified private file serving for Frappe/ERPNext — local disk and S3-compatible object storage

Install S3Vault

bench get-app https://github.com/countynetkenya/s3vault

Add the Frappe Gems badge to your README

Maintain S3Vault? Paste this into your README:

[![Listed on Frappe Gems](https://frappegems.com/api/method/frappe_gems.seo.badge?app=countynetkenya%2Fs3vault)](https://frappegems.com/gems/apps/countynetkenya/s3vault)

About S3Vault

s3vault

CI License: MIT Frappe v16

s3vault is an open-source Frappe app that provides secure, unified private file serving for Frappe/ERPNext sites. It replaces Frappe's default file serving with a permission-aware, backend-agnostic approach supporting:

  • Local disk — streams files from any absolute path with Frappe permission enforcement.
  • S3-compatible object storage — generates short-lived presigned URLs and issues an HTTP 302 redirect, so large files bypass your app server entirely.

Features

Local S3 Compatible
Frappe permission check
Streams via app server ❌ (presigned redirect)
Works with Frappe Cloud
Auto-deletes on File delete
Bulk import of existing objects

Supported S3-compatible providers

Provider Endpoint format
Hetzner Object Storage .your-objectstorage.com
AWS S3 s3.amazonaws.com
MinIO minio.yourdomain.com
Wasabi s3.wasabisys.com
DigitalOcean Spaces .digitaloceanspaces.com
Backblaze B2 s3.us-west-004.backblazeb2.com (S3-compat mode)
Cloudflare R2 .r2.cloudflarestorage.com

Any endpoint that speaks the S3 API (AWS Signature v4) works.


Requirements

  • Frappe ≥ 16.0
  • Python ≥ 3.10
  • minio Python package (installed automatically)

Installation

# 1. Get the app
bench get-app https://github.com/county-network-kenya/s3vault

# 2. Install on your site
bench --site  install-app s3vault

# 3. Run migrations (installs Custom Fields on the File DocType)
bench --site  migrate

> Frappe Cloud: use the Apps tab in your Cloud dashboard to install the > app from GitHub, then click Migrate on your bench.


Configuration

1 — Create a Vault Storage document

Go to s3vault → Vault Storage → New and fill in:

S3 Compatible backend:

Field Example
Title Hetzner-FSN1
Backend S3 Compatible
Endpoint fsn1.your-objectstorage.com
Region eu-central-1
Bucket Name my-private-bucket
Access Key ``
Secret Key ``
Presigned URL Expiry (seconds) 10800 (3 h)

Local backend:

Field Example
Title Archive-NAS
Backend Local
Root Path /mnt/nas/frappe-files

2 — Attach a vault file

When creating or updating a File document, set the two extra fields:

Field Value
vault_storage Link to your Vault Storage (e.g. Hetzner-FSN1)
vault_storage_key The S3 object key or local relative path (e.g. pdfs/report-2024.pdf)

Files served via vault use the URL pattern /vault-file//.

3 — Bulk-import existing S3 objects

If you already have objects in an S3 bucket and want to register them as Frappe File documents:

bench --site  execute \
    s3vault.vault.utils.register_s3_files.run \
    --kwargs '{
        "vault_storage": "Hetzner-FSN1",
        "prefix": "pdfs/",
        "attached_to_doctype": "Customer",
        "dry_run": true
    }'

Remove "dry_run": true to actually create the records.


How it works

Browser                 Frappe / s3vault          Storage
  |                            |                          |
  |-- GET /vault-file/ABC/x -->|                          |
  |                            |-- permission check       |
  |                            |                          |
  |          S3 backend:       |                          |
  |<-- 302 presigned URL ------| <-- presigned URL -------|
  |-- GET presigned URL --------------------------------------------->|
  |<-- file bytes ---------------------------------------------------|
  |                            |                          |
  |          Local backend:    |                          |
  |<-- 200 file bytes ---------| read(path) ------------->|

VaultFile is registered via override_doctype_class, so every File document on your site is vault-aware. Files that have no vault_storage_key behave identically to core Frappe File documents.


Why s3vault instead of frappe-attachments-s3?

zerodha/frappe-attachments-s3 is the long-standing community app for S3 attachments, and it served us well as prior art — we ran it in production before building s3vault. We replaced it because its design is wrong for access-controlled files:

frappe-attachments-s3 s3vault
Public files file_url rewritten to a permanent direct S3 URL (bucket + endpoint exposed in the DB and to every viewer) key stored server-side only; URL minted per request
Private files file_url embeds the raw S3 key in a /api/method/...generate_file?key=... link raw keys never leave the server
Authorization seam none — one fixed presigned-URL endpoint VaultFile.get_vault_url() / VaultFileRenderer are override points for app-specific access rules (e.g. role gates, expiring grants, watermarking)
Backends AWS-shaped (no custom endpoint upstream) any S3-compatible endpoint + local disk, multiple named backends per site
Scope global — all attachments go to S3 per-file opt-in via vault_storage_key
Framework target Frappe v13 era, sparsely maintained built for Frappe v16

In short: frappe-attachments-s3 answers "store my attachments in S3"; s3vault answers "serve private files from anywhere without ever exposing a stable URL or a raw object key". If you only need the former, the Zerodha app may still fit. Credit to it for the doc-event upload pattern, which informed s3vault's ingest design (both MIT).


Development

# Clone
git clone https://github.com/county-network-kenya/s3vault
cd s3vault

# Lint
pip install ruff
ruff check s3vault/

Pull requests are welcome! Please open an issue first for significant changes.


License

MIT © 2025 County Network Kenya

Related Developer Tools apps for Frappe & ERPNext

  • Frappe — Low code web framework for real world applications, in Python and Javascript
  • Frappe Docker — Docker environment for developing, deploying, and running Frappe applications (ERPNext and custom apps) in production and development
  • Builder — Craft beautiful websites effortlessly with an intuitive visual builder and publish them instantly
  • Bench — CLI to manage Multi-tenant deployments for Frappe apps
  • Frappe Ui — A set of components and utilities for rapid UI development
  • Press — Full service cloud hosting for the Frappe stack - powers Frappe Cloud
  • Gameplan — Open Source Discussions Platform for Remote Teams
  • Doppio — A Frappe app (CLI) to magically setup single page applications and Vue/React powered desk pages on your custom Frappe apps.