Files (drive)
Applies to: SimpleTwo 0.9.x, drive 0.5, agent 0.5.116 · Checked: 06.10.2026
drive is the role that stores the files a person keeps, as opposed to the files they sent
to a chat or by mail. Everybody has a personal space, home; every identity group has a shared
space. In the clients it is the Files tab on iOS, macOS and Android
(how people use it).
The role keeps no bytes of its own. Files live in object storage (the s3 role or the
organisation's store) in the simpletwo-drive bucket, and an object's key is the file's
path: the bucket is a real tree of directories that can be walked without SimpleTwo. Its own
database on postgres holds what the files do not: the change journal clients sync on, the name
index for search, the bin, versions, external links and their counters, unfinished uploads.
1. What you need first
| What | Why | Without it |
|---|---|---|
the postgres role or an external cluster | the role's own database; the coordinator creates it | the role does not start: it has no in-memory mode |
object storage — the s3 role or Settings → External stores | the files' bytes | the role starts but accepts only files up to 32 KB (they fit in a catalogue row); a larger upload answers no_object_store, /healthz shows object_store: none |
a public DNS name with an A record to the drive host's public address, and port 443 reachable from the internet | clients reach the role over HTTPS; the role obtains its Let's Encrypt certificate itself (TLS-ALPN-01 on 443) | no certificate, no drive_url, no Files tab in the clients (see §3) |
| the coordinator and the role on one session key | the role verifies tokens itself | the coordinator hands the key over; nothing to type |
Host size is 2 vCPU / 4 GB: there are no bytes on the host, the working set is the catalogue in postgres. But every download and every upload passes through the role (no client is ever given the store's address), so the role is bounded by bandwidth, not disk. There has been no load run for it yet — see sizing.
Count storage separately from chat and mail attachments. The product's figures are still assumptions, not measurements: 15–20 GB per person when existing file shares are carried in, and 3–5 GB per person a year on top.
With external storage the drive's bucket is always called simpletwo-drive — the console has no
field for its name. The role creates the bucket at start if it is missing; if the key does not
allow that, create the bucket beforehand.
2. Installation
- Servers & deploys → Add a host, role
drive. - Fill in:
- Public DNS name — e.g.
files.s2.<domain>. ItsArecord must point at this host's public address. This is the name clients get, external linkshttps://<name>/d/<token>point at it, and the role orders its certificate for it. - Private address — the host's leg toward postgres and storage. The database's and the
store's access rules are narrowed to this
/32; nothing needs redeploying, postgres ands3pick the new address up within about a minute. - Listen address —
:8088by default. Plain HTTP on the host's private address, used by the coordinator and the other services.
- Public DNS name — e.g.
- Run the generated command on the host. The agent installs the service, opens 8088 and — if the
host has a public name — 443. The service obtains a Let's Encrypt certificate for its name
itself (TLS-ALPN-01 on 443, like the calendar); no front and no port 80 are needed. The
certificate is kept in
/var/lib/simpletwo/drive-acme. The contact address for the certificate authority is the installation-wide one. - Wait for the name to be announced to clients — see the next section.
Check on the role's host and from outside:
curl -fsS http://<private address>:8088/healthz
curl -fsS https://<public name>/healthz
curl -fsS https://s2.<domain>/.well-known/simpletwo.json
The first two answers must carry "ok": true and an "object_store" that is not none. The
third must carry drive_url with https://<public name> (it appears within a couple of minutes
of the second request answering).
In earlier releases the coordinator image did not contain the drive service itself (the host
joined but installed nothing), the role had no TLS of its own, and drive_url was written only
when the host's settings were saved. Upgrade the coordinator and the agent, then press
Redeploy on the drive host.
3. The public name and drive_url
Clients learn where the drive is from the discovery document (/.well-known/simpletwo.json):
the drive_url field. No field, no Files tab: that is the client honestly saying the
installation has no drive, instead of showing buttons that do not work.
The coordinator announces drive_url as it does for mail and identity: once a minute it opens
https://<public name>/healthz and publishes https://<public name> only when it is the drive
service that answers. Once it stops answering, the field is withdrawn after 15 minutes and the tab
hides. Hence the requirements:
- the name comes from the host's row (the Public DNS name field when adding the host or in the host's Settings) and must resolve to the drive host's public address;
- the host's port 443 must be reachable from the internet — for Let's Encrypt and for clients;
- the certificate must be valid: clients do not open an address without one.
There is no drive switch in Settings → Product options: only a missing drive_url hides the
tab. The iOS, macOS and Android clients read drive_url from the same discovery document as the
mail and calendar addresses.
4. Spaces and rights
- Personal space (
personal:<login>) — for everybody who has signed in to a client. Only the owner sees it; the administrator does not see its content. - Group space (
group:<group>) — for every group the person's token carries. The role keeps no list of groups: remove somebody from a group in identity and with their next token they lose its space as well, with nothing to synchronise.
- All members of a group have the same rights in its space: read, upload, rename and delete. There are no read-only roles inside a space yet.
- Assigning the Drive feature in identity does not restrict access yet. The role is given identity's address but does not read the assignment feed: a personal space is created when the tab is first opened, and the Drive feature's state in identity does not reach "ready".
- The role accepts only the coordinator's session token. It does not verify identity's
platform token (
platform_token: identity) — an installation with a drive should not switch to it yet. - What happens to a leaver's personal space is not decided: the files stay, there is no policy.
5. Quotas
A person's space is set where mail's and chats' are — by a quota template: Console → Settings → Quotas, the Files part (space and largest file). Details — quotas.
- The quota is checked when an upload starts, on the declared size, not after the bytes have
crossed the network. A space with no room answers
quota_spent, a file over the limittoo_large. - Over quota only writes are refused. Reading, downloading and external links keep working; nothing is deleted.
- The role's own ceiling on one file is 2 GB (
DRIVE_MAX_UPLOAD_MB); a template can only lower it. - A group space's quota is set on the console's Files tab (below) — there are no templates for groups. A personal space's quota cannot be changed there: the role answers "a person's quota comes from the quota plan"; change the person's template instead.
6. The console's Files tab
Console → Files — two cards:
- What the drive holds — how many files and spaces, how much is charged to people and how much is actually stored, and the difference — what deduplication saves (the same file kept by forty people is stored once). Also the number of unfinished uploads.
- Spaces — find spaces by person or group, biggest first: whose, how much is used, the quota
in GB.
0means the installation's default. A quota below what is already stored deletes nothing: new files are refused.
The cards reach the role through the coordinator and need permissions: the totals
settings:read, the list of spaces users:read, a quota users:write. There is no device sync
state ("who downloaded what") in the console and there will not be: the service does not know it.
7. External links
A person can issue a link https://<public name>/d/<token> to a file for somebody outside the
organisation. The access level is read (download), comment (leave a remark about the
file) or write (put a new version of the file); read by default. A link may have an expiry,
a password and a download allowance; revocation bites on the next byte, because a link's bytes
always pass through the role. The role records every download: when, from which address, how many
bytes. The token is shown once and stored only as a hash — the same link cannot be issued again.
The role can switch links off, allow them only to named groups, impose an expiry and cap the level
(/v1/control/links/policy), but the coordinator has not brought that setting into the console
yet. Until it does, external links are allowed to everybody, with no mandatory expiry and at any
level. If that does not suit the organisation, hold off opening the drive to people until the
setting is in the console: /d/ cannot be closed while leaving the clients' access open — the
service serves both on one name and one port.
The clients have no "share a link" button yet, nor a comments screen: links are created and
comments read only through the role's API (reference). Other limits of
this version: a link is issued for a file only, not a folder; there is no page for the recipient —
a link without a password downloads the file straight away in a browser, and a browser cannot
open a password link by itself (the password travels in the request body or the
X-S2-Link-Password header, never in the address).
8. The bin, versions and sync rules
- Deleted items go to the space's bin and stay there 30 days (
DRIVE_BIN_DAYS), then are erased. Bytes are erased only when no other file points at the same content. - Earlier versions of a file are kept on every overwrite and go with the file when the bin erases it.
- What does not sync. The installation has a list of exclusion masks (
*.tmp,~$*,.DS_Storeand so on) a person may add to but not shorten. The role stores it and hands it to clients, but the console has no field for it: the default list built into the client applies.
9. Backup and restore
The bucket is the record of which files exist; the database is a derived index. Therefore:
- Back up the
simpletwo-drivebucket — the main thing and the largest. On thes3role it is the ZFS datasetsimpletwo/s3(snapshots andzfs send); on external storage, by its own tools. - Every hour the role puts a snapshot of the catalogue into each space
(
<space>/.catalogue.json): the bin, versions, links, comments. Connect the same bucket to a new database and you lose only what changed after the last snapshot; the files themselves are never lost. - The role's database is backed up with the other postgres databases (
pg_dump) — see upgrade and backup.
The role does not encrypt files: the decision is to encrypt below it, with ZFS. Today the agent
creates the dataset without encryption, and it cannot be switched on for an existing dataset —
only by creating a new one with encryption=on and copying the data over. The installation's
encryption switch does not cover the drive.
10. Not in this version
- WebDAV (Finder, Explorer), a drive web page and an outward S3 API.
- A sync folder on the computer ("like Dropbox"): decided, the daemon does not exist yet.
- Files in the Windows client: the sidebar has a Files section, but it is an empty screen.
- In the clients: rename, move, versions, a bin with restore, search and external links exist in the role, but the apps have no buttons for them yet.
- Server-side preview, antivirus checking of uploads (ICAP), content search — search is by name only.
- Migration of existing file shares.
- There will be no SMB: that is a decision, not a backlog item.
If something does not work
| Symptom | Likely cause |
|---|---|
| No Files tab | /.well-known/simpletwo.json has no drive_url: the coordinator has not reached https://<public name>/healthz (§3) |
https://<public name>/healthz does not answer | no A record to the drive host, 443 closed from outside, no public name on the host, or the certificate not issued yet — see the service's log on the host |
No simpletwo-drive service on the drive host | the coordinator predates the drive 0.5 release: its image had no role binary; upgrade and press Redeploy |
Small files upload, large ones get no_object_store | the role was given no store: no s3 role and no external store; /healthz → object_store: none |
quota_spent | the space is full: the person's template or the group's quota on the Files tab |
| No group space | the group is not in the person's token: check membership in identity; the change shows after the token is renewed |
| Host in error, "no dsn in the desired state" | no postgres and no external cluster |