Pithos: a control panel for s3d, the Sia S3 gateway. Web console, desktop app and Theseus add-on.
Find a file
Local Dev a91d2c64b4 Pithos 0.3.4: show the Sia account, label it, switch and restore accounts
"Acting as" read like a choice of Sia account; it picks an S3 user on
this s3d, and every user shares the one Sia account the s3d is connected
to. So:

- The picker is "S3 user", with a tooltip saying all users share one Sia
  account; Buckets explains what a bucket is.
- Buckets and the Overview show "Sia account: <label> (indexer)". Pithos
  cannot see the account's email, so the Sia connection page lets the
  user label it (kept in pithos.json beside the s3d data).
- "Switch Sia account" stops s3d and moves its data (connection, users,
  keys, buckets, upload buffer) into previous-account-<stamp>/ next to
  s3d.yml, never deleting it; the guide then connects another account.
  It warns about uploads still waiting for Sia and offers a flush, and
  refuses while another s3d serves the config.
- "Earlier Sia accounts" lists those folders with Restore, which sets the
  current account aside the same way and swaps the old one back.

Also: a fresh connect now records which indexer it used, and a "not
connected" check is re-run after 30 s so a login made outside Pithos
shows up.
2026-10-03 22:57:46 +02:00
bin Pithos: a control panel for s3d, the Sia S3 gateway 2026-10-03 19:02:50 +02:00
core Pithos 0.3.4: show the Sia account, label it, switch and restore accounts 2026-10-03 22:57:46 +02:00
desktop Pithos: a control panel for s3d, the Sia S3 gateway 2026-10-03 19:02:50 +02:00
scripts Pithos: a control panel for s3d, the Sia S3 gateway 2026-10-03 19:02:50 +02:00
test Pithos 0.3.3: fix SignatureDoesNotMatch when opening a bucket 2026-10-03 22:12:44 +02:00
theseus Pithos 0.3.4: show the Sia account, label it, switch and restore accounts 2026-10-03 22:57:46 +02:00
ui Pithos 0.3.4: show the Sia account, label it, switch and restore accounts 2026-10-03 22:57:46 +02:00
.gitignore Pithos: a control panel for s3d, the Sia S3 gateway 2026-10-03 19:02:50 +02:00
LICENSE Pithos: a control panel for s3d, the Sia S3 gateway 2026-10-03 19:02:50 +02:00
package-lock.json Pithos: a control panel for s3d, the Sia S3 gateway 2026-10-03 19:02:50 +02:00
package.json Pithos 0.3.4: show the Sia account, label it, switch and restore accounts 2026-10-03 22:57:46 +02:00
README.md Pithos: document the extension update channel 2026-10-03 19:20:40 +02:00

Pithos

A control panel for s3d, the Sia Foundation's S3 gateway. s3d itself is managed through a CLI and a two-route admin API; Pithos puts a UI over all of it:

  • Gateway: install the pinned s3d release (SHA-256 checked), start, stop, restart, live logs, edit s3d.yml.
  • Sia connection: register s3d with an indexer (sia.storage or your own indexd) with an existing recovery phrase or a freshly generated one, and approve the connection in the browser.
  • Users & keys: create and delete users, issue and revoke access keys, copy ready-made aws, rclone and env-var config.
  • Buckets: browse as any user, create and delete buckets, upload by drag-and-drop, download, delete files and folders, presigned share links, public-read policies.
  • Upload pipeline: pending, uploaded, unpinned and failed objects from /stats/uploads, plus "flush now".

One core, three hosts

core/   control server: s3d process, CLI wrapper, SigV4 S3 client, admin API, HTTP API
ui/     the single-page UI the server serves (plain JS, no build step)

bin/pithos-web.js   web console    -> your browser
desktop/main.cjs    desktop app    -> an Electron window
theseus/            Theseus add-on -> a Theseus tab

Every host runs the same createPithos() server on a loopback port and points a view at it. A feature added to core/ + ui/ lands in all three.

Web console

npm install
node bin/pithos-web.js

It prints a one-time sign-in link for 127.0.0.1:8700. To reach it from another machine, set a password and put a TLS reverse proxy in front:

PITHOS_PASSWORD='long random secret' node bin/pithos-web.js --listen 0.0.0.0:8700 --allow-host pithos.example.org

Other flags: --config <s3d.yml>, --s3d <binary>, --bin-dir <dir>, --password-file <file>.

Desktop

npm run desktop

The window signs in with the server's one-time secret; nothing else on the machine can drive the API. Quitting stops s3d cleanly. Installed s3d builds go to the app's user-data folder.

Theseus

node scripts/build-theseus-addon.mjs

builds dist/theseus-addon/pithos/ (about 0.9 MB). Copy it into TheseusNavigator/bundled-addons/ to bundle it, or publish it as a community extension. The dock menu has Open Pithos and Stop s3d.

Shipping an update. The add-on updates on its own extension channel, not with Theseus releases:

  1. Bump version in theseus/addon.json (and package.json).
  2. Rebuild the bundled copy: node scripts/build-theseus-addon.mjs ../TheseusNavigator/bundled-addons/pithos, then commit, so new installs carry the same version.
  3. Sign it and publish it on the channel at https://navigate.st/bns/theseus.x/extensions/pithos/ (Sia bucket bns/theseus/extensions/pithos/), as described in TheseusNavigator/docs/ADDON-UPDATES.md.

Installed copies pick the update up within about 30 seconds of the next launch and switch to it on the launch after that. The Theseus version stays the same.

The add-on leaves out the pty module (12 MB of native code), so on Windows the indexer login runs in its own console window and Pithos picks up the result when it closes.

Which s3d instance it manages

The same one a hand-run s3d would use: S3D_CONFIG_FILE if set, otherwise %APPDATA%\s3d\s3d.yml (Windows), ~/Library/Application Support/s3d/s3d.yml (macOS), /etc/s3d/s3d.yml (Linux). Every s3d call Pithos makes gets S3D_CONFIG_FILE pinned, so the daemon and the CLI calls always agree.

If another s3d process is already serving that config (a service, or one started by hand), the overview shows it as external and reads its stats, but Pithos won't start a second copy.

Pithos needs s3d v0.2.0 or newer: users list and keys list arrived in 0.2.0. Older builds get an upgrade banner.

Security model

  • The server binds loopback by default and refuses Host headers other than its own address (DNS-rebinding guard). Binding beyond loopback requires a password of at least 12 characters.
  • Sessions are HttpOnly, SameSite=Strict cookies. Every non-GET request also needs an x-pithos: 1 header, so a cross-site form cannot drive the API.
  • The recovery phrase is only written to the s3d login process's terminal. It is never stored, logged or sent anywhere else. A generated phrase is shown once and must be acknowledged.
  • Downloads are served with a sandboxing CSP and nosniff, so a stored HTML object cannot run script on the console's origin.
  • s3d keeps access-key secrets in plain text in its own SQLite database. Pithos shows them to whoever is signed in to the console, so treat console access as root on the gateway.

How it talks to s3d

Need Mechanism
users, keys, version, registration check s3d users …, s3d keys …, s3d version, s3d login with stdin closed
indexer login s3d login in a pseudo-terminal (it reads the phrase with term.ReadPassword)
buckets and objects the S3 API, signed with SigV4 as the chosen user's first access key
stats, flush the admin API (/stats/uploads, /objects/flush) with the configured admin password

test/sigv4.test.js cross-checks the signer against the AWS CLI on awkward keys and prefixes and on presigned URLs (npm test).

Limits and next steps

  • Uploads are single PUTs, capped at 5 GiB (s3d's part limit). Multipart uploads from the browser would lift that.
  • Object versioning, lifecycle rules and multipart-upload cleanup are not in the UI yet.
  • Desktop installers (electron-builder) are not set up yet.
  • Multi-tenant mode, where end users sign in with a wallet and each get their own s3d user and quota, is the planned follow-up. It is the Hestia direction in Hephaestus/DESIGN-hestia.md.

License

MPL-2.0. s3d is MIT, © The Sia Foundation.