Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CraftFileGate

CraftFileGate is a file server: an SFTP client, an HTTP script or a browser puts files on it and takes files from it, and the server stores them on one or more storages. It replaces a classic SFTP server (ProFTPD, OpenSSH internal-sftp) when the files do not all live on a local disk, or when the accounts come from an identity provider.

What it does

NeedAnswer
Put and take filesSFTP, REST file API, web file explorer
Store the fileslocal disk, upstream SFTP server, S3 and compatibles, HDFS via Knox (read only)
Authenticatepassword, SSH public key, JWT token (secret, public key or JWKS)
Grant rightsroles, which mount storages and grant rights on them by path; refusal by default
Monitoraudit trail, JSON logs, Prometheus metrics, OpenTelemetry traces
Administeradmin API and web console: sessions, bans, configuration in force
Deploya static binary, Docker images, a Helm chart

The words of this guide

WordMeaning
backenda named storage, described in [[backends]]
rolea set of mounts; a user receives one or more
mounta backend seen by the user at a path (mount_path), starting from a subdirectory (home_dir), with its ACL
ACLthe rights (read, write, list, delete, rename) by path, within a mount
doora way in: SFTP, REST API, file explorer, admin console

The chapter Users, roles and mounts explains them with examples.

Quick start

A server on a local disk, a user alice who sees only her directory.

1. Generate a host key

ssh-keygen -t ed25519 -f /etc/craft-file-gate/host_ed25519 -N ""

A key listed in host_keys but missing refuses startup.

2. Write the configuration

Create /etc/craft-file-gate/config.toml:

#:schema ./config.schema.json
[server]
shutdown_grace_period_secs = 30
# max_sessions_per_user = 10  # optional, unlimited by default

[sftp]
listen = "0.0.0.0:2222"
host_keys = ["/etc/craft-file-gate/host_ed25519"]
# login_grace_secs = 120      # unauthenticated connection cut after this (0 = never)

[auth]
jwt_sentinel_username = "jwt"
timeout_secs = 5
# roles_file = "/etc/craft-file-gate/roles.toml"  # optional, otherwise inline [[roles]]
# authz_base_url = "https://authz.internal"  # optional, remote mapping service

[auth.jwt]
secret = "changez-moi-en-production"
# public_key_file = "/etc/craft-file-gate/jwt_public.pem"  # alternative to the secret
# jwks_url = "https://idp.interne/.well-known/jwks.json"   # alternative: identity provider keys
# jwks_refresh_interval_secs = 3600                        # default, minimum 1
# username_path = "/sub"       # default
# authorities_path = "/groups" # default

[auth.methods]
jwt   = { enabled = true }
# Password and public key are proofs of the local store, not separate
# methods: you declare them under `local`.
local = { enabled = true, password = true, pubkey = true }

[admin]
listen = "127.0.0.1:8080"
bearer_token = "changez-moi-en-production"

[log]
level = "info"
format = "json"

# ── Storage and rights ──
[[backends]]
name = "local"
type = "local"
root = "/srv/sftp"

[[roles]]
name = "utilisateurs"

[[roles.mounts]]
backend = "local"
home_dir = "/{username}"   # alice sees /srv/sftp/alice as her root /
create_home = true

[[roles.mounts.acl]]
path = "/"
rights = ["read", "write", "list", "delete", "rename"]
recursive = true

# ── Local users ──
[[users]]
username = "alice"
# password: changez-moi-en-production
password_hash = "$argon2id$v=19$m=19456,t=2,p=1$QzIrOEdtBZI4UL4ddXDbkg$yudDYsZSLamFZHWeKlFpFWtkP4kX6ALV8GNKs3pEXBk"
# authorized_keys = ["ssh-ed25519 AAAA... alice@poste"]
authorities = ["utilisateurs"]

The JWT secret, the admin token and alice’s password (changez-moi-en-production) are public. The server starts with them, but emits one WARN per example value still in place. To replace alice’s [[users]] block:

echo -n "mot-de-passe" | craft-file-gate hash-password --user alice

The process must be able to write to /srv/sftp: create_home creates alice/ there at her first login.

3. Start the server

craft-file-gate --config /etc/craft-file-gate/config.toml

For Docker and Kubernetes, see the guide (“Operating”).

4. Connect

sftp -P 2222 alice@votre-serveur

ls shows the content of /srv/sftp/alice, and nothing above it.

What next

ToRead
give everyone what they should seeUsers, roles and mounts, Recipes
connect S3 or an upstream SFTP serverBackends
connect an identity providerAuthentication
deploy in a containerDocker, Kubernetes
understand a refusalTroubleshooting, Audit
look up a keyConfiguration reference