arizuko › howto › WebDAV mount
WebDAV
Every group folder is available over WebDAV at https://<host>/dav/<group>/. A WebDAV client that sends a Bearer token, for example rclone or curl, sees the same files that the agent reads and writes.
rclone mounts a group in four commands
Set up an rclone remote for your instance once, then mount a group:
# 1. point rclone at the WebDAV endpoint
rclone config create arizuko webdav \
url=https://<host>/dav/ \
vendor=other
# 2. on the host, mint a Bearer token that authd's key signs
arizuko token -i <instance> issue bearer <folder> --scope <scope> --sub <your-sub> --ttl 24h
# 3. give the token to rclone; it stores it in ~/.config/rclone/rclone.conf
rclone config update arizuko bearer_token=<paste-token-here>
# 4. mount a group as a local folder
mkdir -p ~/arizuko-atlas
rclone mount arizuko:atlas ~/arizuko-atlas --vfs-cache-mode writes
The files of the group are now under ~/arizuko-atlas/, for example CLAUDE.md, diary/, facts/ and media/. Edit them in your editor or add files. The agent reads the changes at its next turn.
/auth/login, then open https://<host>/dav/<group>/. dufs, the server under davd, shows a directory page with links.A URL path is a path under groups/
The URL /dav/<group>/<rest> maps to groups/<group>/<rest> under the data directory. davd serves <DATA_DIR>/groups/ read-write. proxyd removes the leading /dav before it forwards the request, and it applies the write block of davAllow.
| URL | path on the host |
|---|---|
/dav/ | a 302 redirect to /dav/<first-group>/ |
/dav/atlas/ | /srv/data/arizuko_<inst>/groups/atlas/ |
/dav/atlas/CLAUDE.md | /srv/data/arizuko_<inst>/groups/atlas/CLAUDE.md |
/dav/atlas/users/alice.md | /srv/data/arizuko_<inst>/groups/atlas/users/alice.md |
<group> is the folder name on disk, not the display name of the group. The dashboard lists the folders at /dash/groups/. The default group of a new instance is main.
The dashboard login also opens /dav/
The auth layer of /dash/ also protects /dav/. No separate WebDAV password and no Basic Auth exist.
| client | credential | how |
|---|---|---|
| browser | JWT cookie | sign in at /auth/login; the refresh_token cookie also works for /dav/ |
| rclone, curl | Bearer token | mint it with arizuko token -i <instance> issue bearer and send Authorization: Bearer <token> |
A request without a credential gets 303 See Other with Location: /auth/login. A browser follows the redirect. curl follows it only with -L. To check:
curl -s -o /dev/null -w '%{http_code}\n' https://<host>/dav/
# 303
curl -s -o /dev/null -w '%{http_code}\n' \
-H "Authorization: Bearer $TOKEN" \
https://<host>/dav/atlas/
# 200
The dashboard does not issue Bearer tokens. arizuko token -i <instance> issue bearer signs a JWT with the active key of authd, for the sub that --sub names. proxyd then reads the grants of that sub. No test opens /dav/ with such a token end to end.
--ttl.Grants decide which groups a user can open
Authentication tells proxyd who you are. Grants tell proxyd which group folders you can open. proxyd reads the grants for each request:
- Operator
- A user with the
**grant sees every group of the instance./dav/sends the operator to the first group in sorted order. Any other group opens when the operator types its path. - Other users
- A user sees only the groups that an
aclrow allows. A request for another group returns403 Forbidden, andproxydlogsdav forbiddenwith the sub and the path.
A login alone is not enough. A signed-in user without grants gets 403 on every group path.
proxyd blocks writes to logs and secret files
davd mounts <DATA_DIR>/groups/ read-write. The davAllow function of proxyd is the only place that blocks writes. The rules come from proxyd/main.go:
- Reads always pass
- The block never stops
GET,HEAD,OPTIONSandPROPFIND. Auth and grants still apply. - Logs are read-only
- Every write method on a
logssegment of a group path returns403:PUT,POST,MKCOL,DELETE,MOVE,COPYandPROPPATCH. - Secret files are read-only everywhere
- A path with a segment
.envor.git, or a segment that ends in.pem, refuses writes. Reads still work, so the agent can inspect them. - All other paths are writable
- A
PUTto/dav/atlas/notes/todo.mdwrites the file to disk, and the agent reads it at its next turn.
proxyd also checks the Destination header of MOVE and COPY with the same rules, so a move cannot write into a group or a path that the request line could not reach.
Four tasks show the use
An operator edits CLAUDE.md from a laptop
rclone mount arizuko:atlas ~/atlas --vfs-cache-mode writes
$EDITOR ~/atlas/CLAUDE.md
# save and unmount; the agent uses the new file at its next turn
A user gives the agent a file to read
curl -H "Authorization: Bearer $TOKEN" \
-T ./quarterly.csv \
https://<host>/dav/atlas/media/quarterly.csv
# then ask the agent in the chat: "read media/quarterly.csv and summarise"
The agent writes a file, and the user downloads it
The agent runs in a guest with its group folder shared read-write. It can write files, for example PDFs, charts or transcripts, everywhere except logs/. The user then downloads them:
curl -H "Authorization: Bearer $TOKEN" \
-o report.pdf \
https://<host>/dav/atlas/out/report.pdf
An operator lists the memory files of the users
The memory of each user is in <group>/users/<user>.md. With an operator grant, you can list all of them:
curl -X PROPFIND \
-H 'Depth: 1' \
-H "Authorization: Bearer $TOKEN" \
https://<host>/dav/atlas/users/
Only clients that send a Bearer header can sign in
rclone
Make the remote in one command, without prompts:
rclone config create arizuko webdav \
url=https://<host>/dav/ \
vendor=other \
bearer_token=$TOKEN
Mount with the VFS cache, so that the save-and-rename of an editor works:
rclone mount arizuko:atlas ~/atlas \
--vfs-cache-mode writes \
--dir-cache-time 30s
curl
# read a file
curl -H "Authorization: Bearer $TOKEN" \
https://<host>/dav/atlas/CLAUDE.md
# list a directory; Depth: 1 gives the direct children only
curl -X PROPFIND -H 'Depth: 1' \
-H "Authorization: Bearer $TOKEN" \
https://<host>/dav/atlas/
# upload a file
curl -X PUT --data-binary @./notes.md \
-H "Authorization: Bearer $TOKEN" \
https://<host>/dav/atlas/notes.md
Finder, Windows Explorer and davfs2
These clients send a user name and a password with HTTP Basic auth. proxyd accepts only Authorization: Bearer <JWT> or the refresh_token cookie, so these clients cannot sign in. Use rclone: rclone mount gives a local folder that Finder and Explorer can open.
Six problems have a known cause
- 303 redirect to
/auth/login - You are not signed in. In a browser, follow the redirect and sign in. With
curlor rclone, sendAuthorization: Bearer <token>.arizuko token -i <instance> issue bearermakes the token. - 403 Forbidden on a path that you can read
- The write block applies, because you wrote under
logs/or to.env, a*.pemfile or.git. Or you have no grant for that group.journalctl -u arizuko_<inst> | grep -E "dav (forbidden|blocked)"shows which one. - 404 "WebDAV not configured"
proxydhas no/dav/route, becauseWEBDAV_ENABLED=falseor the web layer is off.WEBDAV_ENABLEDdefaults totruewhenWEB_PORTis set. Set it in.env, runarizuko generateand restart.- 404 at
/dav/<group>/ - The group folder does not exist. Check the folder name in
/dash/groups/. - 423 Locked
- Another WebDAV client holds a lock on the file. Disconnect that client or wait.
dufslocks each file, and a lock can stay for some minutes after a hard disconnect. - The agent does not use an edit
- The write arrived, because
proxydlogged no403. A new file does not start a turn, so send the agent a message. Or the file is in a path that the agent does not read. TheCLAUDE.mdof the group says what the agent reads, for examplemedia/,facts/andusers/.
Only proxyd stands between the network and davd
TLS ends at the public edge in front of proxyd. Behind it, from proxyd to davd and from davd to the disk, traffic is plain HTTP on the Docker network. The network namespace is the trust boundary. davd checks no identity. It expects that every request has passed the auth check, davAllow and the grant check in proxyd. [SECURITY.md] has the full threat model.
Four pages give the details
- [davd/README.md]
- The daemon, a small wrapper around
sigoden/dufs. - webdav
- The same surface on one page.
- auth
- Where the Bearer token comes from.
- grants
- The limit to one group.