The log
Each device keeps a log of who did what there. It covers sessions started and ended, other devices and agents attaching, how much they typed, what was refused, changes to the rules (access.toml and your organization’s managed.toml), and devices paired, forgotten or blocked.
$ alto log --since 1h2026-11-10 15:29:44 41 started session 7 sam claude2026-11-10 15:31:02 42 attached session 7 sam on studio as moderator, may read, send, kill, approve2026-11-10 15:31:02 43 input session 7 sam on studio 38 bytes, 1 line2026-11-10 15:31:04 44 detached session 7 sam on studio2026-11-10 15:40:19 45 refused session 7 alex on laptop refused: not allowed to kill session 7 on this device: watching only (its log says why: access-3fa2c1)2026-11-10 15:52:11 46 ended session 7 sam ended it- Who: another device by its name here and the login Tailscale gave it, an agent by its name (and the session it runs in, here), you by this device’s account.
- Typing: one entry for each burst from one client, with its size and how many lines. The text itself is never kept.
- Joining: the mode each client joined in, and a mode refused with the rest.
- Refusals: what the caller was told, and the whole reason (the rule, the nearest grant). That’s the
access-…reference a refused device is shown. - Rules: when
access.tomlormanaged.tomlis added, changed or removed, with a hash of what it holds now. Not who changed it: they’re files anyone with access to them can edit.
Reading it
Section titled “Reading it”alto log prints everything; narrow it with:
| Option | Keeps |
|---|---|
--since 2h |
What happened in the last two hours (30m, 1d, …) |
--session 7 |
What happened in session 7 |
--by NAME |
What a device, a login, an agent or an account here did |
--json |
Entries as kept: one JSON object per line |
alto --on studio log reads studio’s. Your own devices may; a device paired from another account needs a grant to read that device’s device (see Access). It gives the newest 5000 entries at most; narrow it for more.
Sending it to a security tool
Section titled “Sending it to a security tool”$ alto log export --ocsf --since 1d > alto.ocsf.jsonlexport --ocsf gives each entry as an OCSF 1.3 event, one JSON object per line, for a SIEM or anything else that reads OCSF. It takes the same --since, --session and --by, and --on for another device’s.
| Entries | OCSF class |
|---|---|
started, ended |
Process Activity (Launch, Terminate) |
attached, detached |
Authentication (Logon, Logoff) |
input, refused |
API Activity (a refusal as a failure, with what the caller was told) |
paired, allowed, blocked, forgot |
Account Change (the device as the account) |
rules, managed |
Entity Management (the file as a policy) |
Each event keeps its entry whole under unmapped, so nothing is lost on the way. The export can’t be checked by verify, though: check the log itself.
Checking it
Section titled “Checking it”$ alto log verifyok: 1214 entries follow on and are signed by this device, to entry 1214Each entry has a number one more than the one before and the hash of the entry before. Each is also signed with this device’s own key (the one other devices know it by). An entry changed, removed or moved breaks that, and verify names where:
$ alto log verify --dir ./copyalto: the log doesn't follow on at entry 812 (2026-11-10.jsonl, line 9): its signature isn't this device's: it was changed, or written elsewhere--dir checks a copy; --key checks against a device’s public key rather than this one’s. It checks files here: to check another device’s log, run it on that device.
What it can’t show: entries cut off the end, or a log rewritten by someone holding this device’s key, which is the person signed in here. Checking proves an entry is this device’s and in its place, against anyone else.
Where it’s kept
Section titled “Where it’s kept”log/ in Alto’s state folder, a file for each day (UTC): ~/Library/Application Support/alto/log/ on macOS, ~/.local/state/alto/log/ on Linux, %LOCALAPPDATA%\alto\log\ on Windows. The folder is readable by you only. Nothing removes old files yet.