# mesh-reads A node's files and accounts, read through the mesh (novox/hq ADR 0310, extending ADR 0268 §5; hq to-be 41 WP8; issue 418). It holds the node seat `node-reads` on every node, the control-node included, so reading a file, searching one, listing a directory, the owner and mode of each component of a path and looking up an account or a group never go through the login shell's `execute`, and an approval is asked for an act, never for a read. ## Who it reads as The account `mesh-reads`, which this module makes on every node (`runs-as`, ADR 0259 §8): no login shell, a home of its own under `/var/lib`, and no group beside its own. The tool runner serves it in a runtime of its own, on its own bus credential, never the machine's runtime, which runs as the operator's account. So the node's file modes bound what it sees: a file only the operator, root or a module's own account may read is refused by its mode, and the answer says so. It refuses every read when it finds itself running as root. ## What it refuses by name Before any read, whatever the file modes would allow (ADR 0310 §5): - **The places the mesh keeps a secret on this node**, which the controller composes from the manifests and gives it as `MESH_SECRET_PLACES`: the directory of every module's own secret (its bus credential among them), every credential file and grant directory, the vault's directories, and where the operator-sealed secrets are kept. Without that list the module does not start. - **The known credential files of a machine's programs** (`refuse.go`): an account's `.ssh`, `.gnupg`, `.aws`, `.kube`; the agent's `.credentials.json`, `.netrc`, `.pgpass`, `.git-credentials`; private key names (`id_ed25519`, `*.key`, `ssh_host_*_key`); `/etc/shadow`; `/etc/ssl/private`, `/etc/wireguard` and the network manager's connections. - **Histories and profiles**: shell and program histories (`.zsh_history`, `.bash_history`, `.psql_history`, `.viminfo` …), browser and mail profiles (`.mozilla`, `.config/google-chrome`, `.config/chromium` …), a process's `environ`, `mem`, `fd`, `map_files`, `root` and `cwd` under `/proc`, and `/etc/rancher` and `/etc/kubernetes/admin.conf`. **What was opened is judged, not the name.** The type is checked before the open, so a device or a fifo is never opened; the file is opened non-blocking (in a search without following a link), checked again on its descriptor, and the path the kernel gives for that descriptor is judged by name like any path asked. A link flipped between the check and the open therefore reaches nothing a name refuses, and a deleted file is refused. **Limit:** a hard link to a secret file under another name is not seen by the name rule; the file's own mode, and the kernel's protected hard links, are what bound it. `stat` and `readlink` say a secret place's owner and mode, and mark it, because those are not its content; `list`, `read` and `search` refuse it. ## The content rule Every answer passes the content rule's secret class, from `mesh-sdk`'s `outward` package (ADR 0310 §4): a line of a file or a matching line shaped like a secret is withheld and its number said, as is a link target or an account's words. Every line of a `BEGIN … END` block — a private key's or a certificate's — is withheld whole, because one base64 line of a key can pass the rule alone. A path and an entry's name are not judged: they are what the caller named or what the file system calls a thing, and the rule would take a temporary directory's or a container layer's name for a token. ## Its verbs and their bounds | verb | replaces | bounds | |---|---|---| | `stat` | `stat`, `ls -ld`, `namei -l`, `findmnt -T` | 200 paths, 64 components each; links followed only with `follow` | | `readlink` | `readlink`, `readlink -f`, `realpath` | one path | | `list` | `ls`, `ls -la` | 2000 entries, cut and said | | `read` | `cat`, `head`, `tail`, `less` | 64 KiB, or up to 256 KiB when asked; cut at a line and said; text only | | `search` | `grep`, `grep -r`, `grep -F` | a fixed string; 100 matches (500 asked), 4 deep (8 asked), 5000 files, 4 MiB a file, 20 seconds (checked inside a file too); the named path's file system only, the others named; the bound met is said | | `account` | `getent passwd`, `getent group`, `id`, `groups` | 2000 accounts and groups; never a password field | No answer is larger than 1 MiB. Nothing here writes a file.