Content multica creates in inbox/ is owned multica:multica, so obsync fell into "other" (---) and Sync could neither read nor upload Wong's submissions. Found after the real Sync sign-in on spaceship-earth; the earlier verify only tested the obsync -> multica direction. Shared folders now carry user:obsync:rwx as an access and a default entry alongside the shared user's, and verify tests the multica -> obsync direction (read + rewrite, as merge needs). Second run changed=0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
82 lines
3.7 KiB
Markdown
82 lines
3.7 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` and `user:obsync:rwx`, each also 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`.
|
|
- What `multica` creates stays readable and writable by `obsync`. Those
|
|
files are owned `multica:multica`, so without the named `user:obsync`
|
|
default entry Sync could not read them and would never upload them.
|
|
- `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`.
|