Running the Node
Deze inhoud is nog niet vertaald.
Day-to-day work on a node is small. This is what there is.
Health
Section titled “Health”scripts/tc-operator/tc-operator status --config operator.yamlRead-only, needs no elevated rights and no terminal. It prints a human summary of each container’s state, the node’s federation identity, which flags are on, which integrations are configured, and the build currently running. It also writes a machine-readable JSON line, so you can point a monitor at it.
The containers it reports on, and what each one being down means:
| Container | What it is | If it is down |
|---|---|---|
db |
the database — all node state | everything is down |
auth |
signup, login, token issuance | no new logins; issued tokens work until they expire |
rest |
the REST API over the database | all client reads and writes fail |
functions |
all business logic and the federation handlers | app actions and federation fail; raw auth and REST still answer |
storage |
files and blobs | uploads and downloads fail; nothing else |
realtime |
sync nudges over WebSocket | clients fall back to foreground sweeps — degraded, not broken |
kong |
the single gateway in front of all of it | the whole API is unreachable even though the services are up |
Two more run alongside: a WebFinger sidecar, which is how peers resolve users on your node, and the proxy that terminates TLS and serves the surfaces.
/etc/trusted-codes/README.md on the box carries the same table with your
node’s actual container names, plus what every file in that directory is for.
/etc/trusted-codes/install.log has the full output of every command the
installer ran.
Starting and Stopping Surfaces
Section titled “Starting and Stopping Surfaces”Which surfaces are enabled comes from operator.yaml, but you can turn one on
or off at runtime without a re-install.
tc-operator service status # per surface: enabled, staged, servingtc-operator service start my # build if needed, then servetc-operator service stop business # remove the vhost; the bundle is kepttc-operator service restart verifytc-operator service start all # every surface except adminThe surfaces are my, business, verify, provider, status and admin.
startstages the bundle if it has not been built, adds the surface’s vhost and hot-reloads the proxy. A new host issues its certificate in roughly 30 to 60 seconds;service statusshowscert-pendinguntil it answers, thenserving.- A surface needs its own DNS A record before the certificate can issue.
admincan never be stopped. It is the recovery surface.- This is the only way to control surface serving. The admin app shows you the command but never starts or stops anything itself — a web application must not be able to control your host.
Admin Accounts
Section titled “Admin Accounts”Your node’s admin app is role-gated. There is one role you use:
operator_admin. It administers this server — users, sessions, login history,
blocked attempts, organisations, vaults, notifications.
It is denied every central control surface: operator grants, entitlements,
plans, system parameters, marketing, and the privileged actions behind them.
That denial is enforced at the server on every request, not just hidden in the
interface, and there is no path from operator_admin to the central
super_admin role.
Adding and Removing
Section titled “Adding and Removing”tc-operator add-admin --email someone@example.comtc-operator add-admin --email someone@example.com --revokeNo terminal gate, idempotent, safe to re-run. The verb is hardcoded to
operator_admin and can never grant the central role.
The account must already exist — the person has to have signed in at least once.
add-admin only grants; it does not create accounts. The installer’s
admin_email path is what creates the first one.
Two Capabilities on Top of the Role
Section titled “Two Capabilities on Top of the Role”tc-operator add-admin --email <addr> --can-revoketc-operator add-admin --email <addr> --can-revealtc-operator add-admin --email <addr> --revoke --can-reveal # that capability onlycan_revoke cuts a peer server off, in both directions. Your first admin gets
it at install, because an emergency control that needs a command-line step
mid-incident is not an emergency control.
can_reveal unmasks one address in the invitation log — a typed reason,
audited, rate-limited — and switches on the retention that creates the
recoverable copy in the first place. It is off by default and stays off until
you decide otherwise. It is new exposure of personal data, so it is your
consented decision rather than a default.
A bare --revoke takes the role and all capabilities. --revoke with a
capability flag removes only that capability.
Signing In
Section titled “Signing In”The admin app detects which methods your node has configured and shows them.
- Password. Always available, and your first way in:
admin_emailplus the one-time password the installer printed. It works on a bare node with no email and no OAuth, which is why it is the guaranteed route. Change it after first login. - Magic link. Needs SMTP. The option is hidden until the transport is configured.
- Google or Apple. Needs provider credentials in the auth service’s environment, with your own node’s callback URL registered at Google or Apple. The button appears automatically once they are set.
In every case, the node admits only users holding operator_admin or
super_admin. A successful sign-in by anybody else is rejected and signed out.
Portal URLs
Section titled “Portal URLs”Invitation links and portal references resolve to URLs derived from
home_server — https://my.<domain>, https://admin.<domain>, and so on. To
point them elsewhere, open the admin app and edit them under This Server →
Portal URLs. Changes take effect immediately, and re-running install never
overwrites a URL you have customised.
If Your Node Runs Under an Operating Grant
Section titled “If Your Node Runs Under an Operating Grant”sudo scripts/tc-operator/tc-operator renew-grant --config operator.yamlOne lease-renewal attempt: it signs an attestation, posts it centrally, verifies
the returned grant and stores it. Install wires a daily scheduled job for this,
so you normally never run it by hand. It exits cleanly and does nothing if
central is unreachable or no grant is present, and logs to
/etc/trusted-codes/renew-grant.log.
Rotating the Node’s mTLS Certificate
Section titled “Rotating the Node’s mTLS Certificate”Your node holds a self-signed client certificate, issued once at first install,
stored under /etc/trusted-codes/mtls/, valid for 398 days. Its fingerprint is
part of your admission payload — it is your node’s stable identity to the
registry, which is why re-running install deliberately preserves it and never
rotates it silently.
Rotate only when it nears expiry or you think the key was exposed. There is no single command for it yet:
sudo mv /etc/trusted-codes/mtls /etc/trusted-codes/mtls.oldsudo scripts/tc-operator/tc-operator install --config operator.yamlscripts/tc-operator/tc-operator submit-admissionInstall mints a fresh certificate, which means a new fingerprint. The
registry still trusts the old one until somebody at Trusted Codes verifies the
new fingerprint out of band and approves it — exactly as at first install. Keep
mtls.old until then, so you can go back.
How the Box Is Protected
Section titled “How the Box Is Protected”Every published container port binds to 127.0.0.1 only. This is the structural
control, and it matters more than it looks: Docker publishes ports by
inserting its own firewall rules, which bypass ufw. A firewall deny does not
block a published container port. A loopback-bound port is reachable only from
the box itself regardless. The firewall rules on 22, 80 and 443 are defence in
depth, not the mechanism.
Reach Postgres from your workstation over an SSH tunnel:
ssh -L 5432:127.0.0.1:5432 <your-box>The proxy is the only process bound to a public port. It terminates TLS and forwards to the gateway on loopback.
Secrets live only in /etc/trusted-codes/secrets.env, mode 0600. The admission
payload carries public key material only.