In Theseus, Pithos now links the person's Theseus ID to their hosted account
by itself, once, right after signing in to Silent Mode (or on the first look
at an account already signed in): one consent prompt, then Pithos is listed
under Settings › Theseus ID. On a Theseus without the add-on API it does
nothing, so the add-on can ship before the Theseus release that carries it.
The gateway serves /console on its own origin: sign in with the Theseus ID
and see the account's state, sign-up, usage and Theseus ID, with a console
session that cannot reach files. Three fixed files under a CSP that allows
only this origin.
The bundled copy in TheseusNavigator/bundled-addons/pithos is rebuilt from
Pithos/ with no version bump; the release that ships it bumps the version.
When s3d still lists a file as waiting but its buffered copy is gone,
Upload now fails with a raw admin error and nothing says which files are
behind it. Overview and Drives now list them (waiting, copy missing in
two checks a moment apart, no upload running, older than two minutes),
each with Upload again… (replace it from the original) or Remove, and
Upload now explains the cause instead of passing s3d's error through.
The browser app must read and write the same encrypted files as the
desktop Pithos. web/lib/crypt.js reimplements core/crypt.js on Web
Crypto (AES-SIV and CMAC built from AES-CBC with a zero IV and AES-CTR,
since Web Crypto has neither), and web/lib/sigv4.js the SigV4 signing.
Cross-tests: the RFC 5297 vector, identical drive keys and names, bodies
encrypted on one side and opened on the other (empty, chunk-edge and
multi-chunk files, ranges), tamper and wrong-path rejection, and equal
SigV4 headers and presigned URLs.
pithos.sia itself is the website, so people had no obvious address to
type for the app. /app (and /app/<page>) now opens Pithos in Theseus and
through the website's Open my Pithos; it is no longer read as an S3 user
named app.
Pithos runs on the user's computer, so the pithos.sia website could only
describe it. Two ways in now:
- Open in browser (Theseus, desktop) opens the current page in the default
browser with a one-time sign-in link (60 s, single use), unlike the
host's reusable ?t= link.
- The website links to http://127.0.0.1:47621/open?path=/<user>/<drive>.
Any page or local program could follow that link, so the host first
asks the user in its own window (a native dialog on the desktop,
Theseus's approval prompt with the vault unlocked). Only loopback Host
names are accepted, one question at a time, and the website learns
nothing either way.
Sessions started this way are marked external, so the browser does not
get host-only controls such as Back to sidebar.
A share link from s3d only opened where s3d is reachable, which on a
default setup is this computer. Pithos now makes a Sia shared-object URL
for the file the way the Sia SDK does (the indexer's sealed object, its
data key opened with a key derived from s3d's app key) and registers it
at navigate.st, which streams the file from Sia hosts for anyone, with
seeking, even with this computer off. A shared-object URL reads that one
object and nothing else in the account. Files still waiting on this
computer are uploaded first. A folder gets a page with its files and a
player. Settings lists the links, each one can be switched off.
sia-share is the navigate.st side, in Go on the Sia SDK: it keeps short
ids, checks every URL against an allowed indexer, serves files sandboxed
so a shared page cannot run script on navigate.st, and caps sign-ups per
address and downloads per link per day. Host reads are paid by its own
app on Silent Mode's indexer account.
S3 has no rename, so files, folders and drives kept the name they were
made with. s3d copies objects in its own database (the copy points at
the same data on Sia), so a rename is a copy to the new name and a
delete of the old: quick, and it uses no extra storage. A drive rename
makes a new bucket, moves every file, rebuilds public access for the new
name (a policy names its bucket) and removes the old one. Names that
already exist are refused. Drives on Silent Mode encrypt with keys tied
to each name, so their client gets no rename until it can re-encrypt.
The drives page and Overview now show how much of the Sia account is
used and how much is free. s3d does not report it; the indexer's
GET /account does, signed with the app key s3d registered (read from its
database for this one request, BLAKE2b-256 + Ed25519 as indexd expects).
A person with several sia.storage accounts (or phrases) could not tell
which one a Pithos s3d used: s3d records only the indexer URL. Pithos now
reads the app key s3d stores after login and asks the indexer, with a
request signed the way indexd's app API expects, for the account's key,
storage used and last use. Those match what sia.storage shows for the app,
and the page explains that the login and the phrase together decide the
account. Earlier accounts set aside on this computer show their key too.
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.
Hosted drives sit on a server that holds the Sia connection key, so private
files must be unreadable there. Names are encrypted per path segment with
AES-SIV (deterministic, so folders and prefix listing still work on the
server) and bodies with chunked AES-256-GCM bound to drive and path, with
sizes computable both ways so uploads stream and range reads stay cheap.
s3d only sends full ~40 MB blocks to Sia, so a handful of small files can
stay in the local buffer forever (seen: 63 objects, 6 MiB, nothing on Sia).
An opt-in setting now flushes once the pending set has not changed for N
minutes, judged from s3d's upload stats so uploads from any S3 client count.
Failed flushes back off up to an hour instead of hammering a broken indexer.
The SigV4 encoder kept '/' unescaped in object paths by swapping in a
"never matches" regex (/$^/) for query values, but that regex matches the
empty string, so every empty query value went out as "/": prefix= became
prefix=/ and ?policy became ?policy=/. The request then no longer matched
what was signed, and listing any bucket or reading its policy failed
against s3d. Bucket listing and creation carry no query, so they worked.
Verified end to end against s3d (list, folders, upload, download, public
policy, folder delete) and against the aws cli; two regression tests.
s3d is driven entirely by a CLI and a two-route admin API, which keeps
Sia storage out of reach for anyone who does not live in a terminal.
Pithos wraps it: install the pinned s3d release (checksum verified),
start/stop and logs, indexer login, users and access keys, a bucket and
object browser with share links and public-read policies, and the
upload pipeline stats.
One control server (core/) serves one UI (ui/), and three hosts run it:
a web console, an Electron desktop window and a Theseus add-on, so a
feature lands everywhere at once. The server binds loopback, rejects
foreign Host headers, and signs views in with a one-time secret that
becomes a SameSite=Strict cookie. s3d login reads the recovery phrase
with term.ReadPassword, so it is driven through a pty, with a console
window fallback where the pty module is not shipped.