Files and SSH

File manager API, SSH/SFTP access with key management, and sub-user folder scoping.

In preview files version 0.1.0 Part of Files, terminal and editor

Actions

27 actions, callable from the panel, the command palette and the API as POST /api/v1/a/<id>. Internal actions used between modules are not listed.

ActionWhat it doesRiskPreview
files.list List a folder (read) low No dry run
files.stat Stat a file or folder (read) low No dry run
files.read Read part of a file (read) low No dry run
files.write Save a file low No dry run
files.mkdir Create a folder low No dry run
files.move Move or rename low No dry run
files.copy Copy a file or folder low No dry run
files.delete Delete to trash medium No dry run
files.trash.list List the trash (read) low No dry run
files.trash.restore Restore from trash medium No dry run
files.trash.empty Empty the trash medium No dry run
files.chmod Change permissions medium No dry run
files.archive.create Create an archive low No dry run
files.archive.extract Extract an archive medium No dry run
files.search Search by name or content (read) low No dry run
files.usage.scan Disk usage of a folder (read) low No dry run
files.upload.chunk Upload a chunk low No dry run
files.upload.finish Finish an upload low No dry run
files.upload.abort Cancel an upload low No dry run
files.ssh.get SSH access of an account (read) low No dry run
files.ssh.set Set SSH mode high No dry run
files.ssh.status Effective sshd settings for an account (read) low No dry run
files.sshkey.add Add an SSH public key medium No dry run
files.sshkey.generate Generate an ed25519 key pair medium No dry run
files.sshkey.remove Remove an SSH key medium No dry run
files.ssh.reconcile Re-apply SSH access and drop expired keys medium No dry run
files.sshd.apply Apply the sshd hardening profile critical

Permissions and limits

Permissions

  • files.view Browse and read files
  • files.write Create and change files
  • files.delete Delete files and manage the trash
  • files.permissions Change file permissions
  • files.ssh.manage Manage SSH access and keys
  • files.server.manage Manage sshd on servers

Plan limits

  • files.ssh_keys SSH keys

Engineering notes

Generated from modules/files/docs.md at build d90e9e2. These are the notes the engineers keep next to the code: precise, technical, and honest about what is not done yet.

Security model (read this first)

  • Every file op runs in a helper process that is the account's Unix user (internal/agent/files_helper.go: the agent re-executes itself with SysProcAttr.Credential{uid,gid,groups}; the helper refuses to run as root and sets no_new_privs). The kernel enforces ordinary permissions; files are created account:account.
  • Paths are virtual (/ = home) and resolved with openat2(RESOLVE_BENEATH|NO_MAGICLINKS) against a dirfd of the home (files_root.go). Absolute symlinks, .. escapes and /proc links are refused by the kernel, race-free. Without openat2 (old kernel/seccomp) a component-wise O_NOFOLLOW walk is used, which refuses every symlink. Mutations use parent dirfd + validated leaf with *at() calls; writes are temp + rename and replace (never follow) a symlink at the target.
  • Sub-users (actor.Kind == "subuser") are confined: only scoped folder grants count (an unscoped role permission is ignored) and the helper refuses every symlink, so a link inside a granted folder cannot reach the rest of the home. Trash and usage ops need a grant on /.
  • Archives: names validated (no .., absolute, backslash, NUL), links/devices never extracted, entries created with NOFOLLOW walks, limits (4 GiB, 200k files, ratio 200) enforced on bytes actually written, rollback on failure.
  • .ssh, .rc-trash, .rc-uploads are panel-managed: not writable through the API; internals are not listed.
  • SSH keys are not read from ~/.ssh (user-writable). sshd is pointed at root-owned /etc/ssh/rc-keys/%u, rendered from typed key objects (restrictions: from CIDRs, git/sftp forced command, expiry; restrict always on, so no port forwarding). Modes via groups: rc-ssh-off (AuthorizedKeysFile none), rc-sftp (chroot /srv/rc-chroot/<u> bind-mounting the home via rc-chroot@<u>.service, internal-sftp, no TTY), rc-shell. Snippet /etc/ssh/sshd_config.d/50-respirecloud.conf, hardening 10-respirecloud-hardening.conf; every change is sshd -t validated and reverted on failure.

Actions

files.list/stat/read/write/mkdir/move/copy/delete/trash.*/chmod/archive.create/archive.extract/search/usage.scan, files.upload.chunk/finish/abort (resumable, 256 KiB chunks), files.ssh.get/set/status, files.sshkey.add/generate/remove, files.ssh.reconcile (drops expired keys), files.sshd.apply (admin, dry-run diff). Admins/resellers pass account_id; owners and sub-users act on their own account.

Verified (lab w2-05, Ubuntu 24.04 container, 2026-10-09)

See docs/tasks/w2/w2-05-files-terminal.handover.md.

Not done / next

Share links, versions, FTP/WebDAV, previews, access users, remote storage; bubblewrap cage (exec path is cageArgv in pty.go); per-account SSH on/off gated by package; password SSH + TOTP; sshd port change and the second-connection login test; session list/kill for SSH; quotas/trash retention jobs; no scheduler yet calls files.ssh.reconcile (needs a cron hook).