Ir al contenido

Running the Node

Esta página aún no está disponible en tu idioma.

Day-to-day work on a node is small. This is what there is.

Terminal window
scripts/tc-operator/tc-operator status --config operator.yaml

Read-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.

Which surfaces are enabled comes from operator.yaml, but you can turn one on or off at runtime without a re-install.

Terminal window
tc-operator service status # per surface: enabled, staged, serving
tc-operator service start my # build if needed, then serve
tc-operator service stop business # remove the vhost; the bundle is kept
tc-operator service restart verify
tc-operator service start all # every surface except admin

The surfaces are my, business, verify, provider, status and admin.

  • start stages 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 status shows cert-pending until it answers, then serving.
  • A surface needs its own DNS A record before the certificate can issue.
  • admin can 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.

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.

Terminal window
tc-operator add-admin --email someone@example.com
tc-operator add-admin --email someone@example.com --revoke

No 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.

Terminal window
tc-operator add-admin --email <addr> --can-revoke
tc-operator add-admin --email <addr> --can-reveal
tc-operator add-admin --email <addr> --revoke --can-reveal # that capability only

can_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.

The admin app detects which methods your node has configured and shows them.

  • Password. Always available, and your first way in: admin_email plus 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.

Invitation links and portal references resolve to URLs derived from home_serverhttps://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”
Terminal window
sudo scripts/tc-operator/tc-operator renew-grant --config operator.yaml

One 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.

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:

Terminal window
sudo mv /etc/trusted-codes/mtls /etc/trusted-codes/mtls.old
sudo scripts/tc-operator/tc-operator install --config operator.yaml
scripts/tc-operator/tc-operator submit-admission

Install 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.

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:

Terminal window
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.