- provision-agent-host.yml: multica_pat now comes from vault_multica_pats[inventory_hostname_short], one daemon-<host> token per host. A pre_task asserts the key exists (never prints the value) so a missing entry fails by host name instead of as a no_log "censored". - provision-wong-host.yml: spaceship-earth only. Grows the root partition, PV and LV/filesystem with growpart + community.general.lvg/lvol; idempotent (second run changed=0). Then applies obsidian_headless. - roles/obsidian_headless: Obsidian's official headless Sync client (obsidian-headless 0.0.14) as system user obsync under a sandboxed systemd unit with UMask=0077. Vault at /srv/obsidian/vault: everpure/ and wip/ obsync-only, inbox/ granted to multica via access + default ACLs, vault root traverse-only. Verifies the isolation as multica. Sign-in to Obsidian Sync stays manual (see the role README). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
3.5 KiB
Markdown
79 lines
3.5 KiB
Markdown
# obsidian_headless
|
|
|
|
Runs Obsidian's official headless Sync client
|
|
([`obsidian-headless`](https://obsidian.md/help/sync/headless), command `ob`,
|
|
open beta) as a dedicated unprivileged user under a systemd unit. It lays out
|
|
the vault folder so that other local users reach only the folders granted to
|
|
them.
|
|
|
|
Written for `spaceship-earth` (WDWL-22). Wong's daemon user (`multica`) may
|
|
read and write `inbox/` and nothing else. `everpure/` and `wip/` are `obsync`
|
|
only. Entry point: `playbooks/provision-wong-host.yml`.
|
|
|
|
## What it does
|
|
|
|
1. Creates the system user `obsync`, with a `0700` home in `/var/lib/obsync`.
|
|
That home holds the Obsidian account token and per-vault sync state.
|
|
2. Installs the pinned `obsidian-headless` into that user's npm prefix and
|
|
links `ob` into `/usr/local/bin`. Node.js is **not** installed here. The
|
|
role asserts that the runtime `multica_agent_host` installs is present and
|
|
is at least version 22.
|
|
3. Lays out the vault folder and its permissions:
|
|
|
|
| Path | Mode | ACL |
|
|
|---|---|---|
|
|
| `/srv/obsidian/` | `0710 obsync` | `user:multica:--x` |
|
|
| `/srv/obsidian/vault/` | `0710 obsync` | `user:multica:--x`, so `multica` can traverse but not list |
|
|
| `vault/everpure/`, `vault/wip/` | `0700 obsync` | none |
|
|
| `vault/inbox/` | `0770 obsync` | `user:multica:rwx`, plus the same as a **default** entry |
|
|
|
|
On a directory with an ACL, the mode's group bits are the ACL mask. A
|
|
`chmod 0700` would therefore void every named entry, which is why the
|
|
shared paths use `0710` and `0770`. The owning group is `obsync`'s private
|
|
group, so those bits grant nobody anything.
|
|
4. Installs `obsidian-sync.service` (`User=obsync`, `UMask=0077`, sandboxed)
|
|
and enables it. It is started only once a vault has been set up.
|
|
`Condition*=` lines keep it inert until then, including across reboots.
|
|
5. Verifies the isolation as the users themselves:
|
|
- `multica` writes, reads and deletes in `inbox/`.
|
|
- A folder and file created by `obsync` under umask `0077` (the way Sync
|
|
creates them) stay readable and writable by `multica`.
|
|
- `multica` is refused both listing the vault root and listing or writing
|
|
`everpure/` and `wip/`.
|
|
|
|
## Do modes and ACLs survive Sync?
|
|
|
|
Obsidian Sync carries no Unix modes or ACLs. Files are created locally by
|
|
`obsync`, so their permissions come from this host, not from the remote:
|
|
|
|
- In `inbox/`, the default ACL applies and the umask is ignored, so new
|
|
content is granted to `multica`.
|
|
- Everywhere else, `UMask=0077` applies, so new content is private to
|
|
`obsync`. That covers any new top-level folder and `.obsidian/`.
|
|
- If Sync deletes and recreates `inbox/` itself, the recreated folder is
|
|
private and `multica` loses access. The failure is closed, not open, and
|
|
re-running the play restores the grant.
|
|
|
|
## Manual step: sign in and set up the vault (once per host)
|
|
|
|
The role never handles the Obsidian account. Run these as `obsync`; `-H`
|
|
makes `HOME` point to `/var/lib/obsync`:
|
|
|
|
```bash
|
|
sudo -u obsync -H ob login
|
|
sudo -u obsync -H ob sync-list-remote
|
|
sudo -u obsync -H ob sync-setup --vault "<vault name>" \
|
|
--path /srv/obsidian/vault --device-name spaceship-earth
|
|
sudo systemctl start obsidian-sync
|
|
journalctl -u obsidian-sync -f
|
|
```
|
|
|
|
Re-running the play after this starts the unit as well. Do not also run
|
|
desktop Obsidian Sync on this host: Obsidian warns that two Sync clients on
|
|
one device conflict.
|
|
|
|
## Tags
|
|
|
|
`obsidian_user`, `obsidian_install`, `obsidian_layout`, `obsidian_service`,
|
|
`obsidian_verify`. The play itself is tagged `obsidian`.
|