A server-sent file list could name paths outside the s3d folder (or the key file in it), and a failed move back deleted every listed path. Transfers now accept only s3d data paths, check all of them before writing, never overwrite, and clean up only what they wrote. A lost reply could lose or fork the drives: move-up and move-down now ask the server who holds them before touching the local copy, and once the server is told to release, the local copy is never removed (the release is retried). The gateway no longer lets one account route another's access key id, refuses . and .. in shared-key paths, strips presign parameters before re-signing, counts upload size on disk, stops s3d before it can be restarted mid-move, and claims sign-up proofs before checking them. The key file is never replaced when unreadable, a local edit removes the older encrypted copy, listing pages no longer repeat, and data hashes stream instead of loading whole files. |
||
|---|---|---|
| .. | ||
| deploy | ||
| test | ||
| auth.js | ||
| electrum.js | ||
| gate.js | ||
| main.js | ||
| package.json | ||
| README.md | ||
| rules.js | ||
| server.js | ||
| sigv4.js | ||
| store.js | ||
| supervisor.js | ||
pithos-hosted
The server half of Pithos's On Silent Mode: one s3d per person, each on
that person's own Sia account, behind a gateway that adds sign-in, per-folder
access and traffic limits. The client half (encryption, moving drives) is in
../core/hosted.js and ../core/hosted-routes.js.
What it serves
| Path | Who | What |
|---|---|---|
/hosted/v1/challenge, /hosted/v1/session |
anyone | Ed25519 sign-in; first sign-in needs a sign-up proof |
/hosted/v1/me, /rules, /data/... |
session | account, access rules, moving the s3d data folder in and out |
/api/... |
session | the owner's Pithos API, forwarded to their s3d's control server (an allowlist; object routes are refused so nothing bypasses client-side encryption) |
/p/<account>/<drive>/<path> |
anyone | files under a public rule |
/l/<token> |
anyone | one file under a share link, until it expires |
| everything else | S3 keys | path-style S3. Owner keys go straight to their s3d, which checks the signature; keys minted for other people are verified here, held to their folder and rights, and re-signed with the owner's key |
s3d processes listen on loopback only (portBase + 2 * slot). Each one
starts on the account's first request and is stopped after idleMinutes,
leftovers flushed to Sia first; at most maxRunning run at once.
State is files under root: users/<id>/ (account, s3d.yml, data, rules,
usage), sessions.json (token hashes), gate.json, keys.json,
grants.json, links.json. Back up that folder and you have backed up the
service.
Sign-up gate
gate in the config enables any of:
bns: { api }: the user signspithos-hosted signup <account id>with the wallet that owns a BNS name;apiis a BNS gateway answering/api/name/<name>with the owner. One slot per name.deposit: { address, minSats, confirmations, electrum: { host, port, tls } }: a BCH payment toaddresscarrying OP_RETURNpithos:<account id>. One slot per transaction. Refunds are an operator decision.invites: ["code", ...]: one use each.
perIpPerDay limits sign-ups per client address (set trustProxy behind
nginx so X-Forwarded-For is used).
Running it
cd /opt/pithos && npm install --omit=dev --omit=optional
cd hosted && npm install --omit=dev
cp deploy/pithos-hosted.example.json /etc/pithos-hosted.json # edit it
node main.js --config /etc/pithos-hosted.json
deploy/ has a systemd unit and an nginx site for s3.silentmode.st
(streamed bodies, Host passed through: s3d checks signatures against the
host the client signed). The s3d binary must be the version Pithos pins
(core/binary.js), the same on both sides of a move.
Stopping the service flushes every running s3d first, so give systemd time
(TimeoutStopSec=300).
Tests
npm test here covers SigV4 verification, rules and the sign-up gate.
The full path (move up, encrypt, share, grant, move back) needs a real s3d;
it was exercised against a mock indexer during development.
Not yet
- Signed streaming uploads (
STREAMING-AWS4-HMAC-SHA256-PAYLOAD) from shared keys are refused; owner keys are unaffected. - Shared keys and links reach readable copies only. Sharing encrypted files with a person (wrapping the folder key to theirs) is the next step.
- No quotas here: storage is each person's own Sia account. Paid storage is Hestia, a separate product.