Files
librenotes/internal
libretechandClaude Opus 4.7 c9b8c4445b Add per-tenant filesystem isolation
internal/tenant/ provides FS, a sandboxed handle for a single
tenant's notes directory. Implementation strategy:

- Defence in depth: every relative path is validated up front
  (rejects "..", absolute paths, NUL bytes, empty), then handed
  to os.Root (Go 1.24+) which enforces the boundary at the
  syscall layer using openat(2)+RESOLVE_BENEATH on Linux. This
  closes TOCTOU races and symlink-target swapping.
- WriteFile is atomic (write to .tmp, rename in-root). Mode 0o600
  on files, 0o700 on directories. Tenant root is created with
  0o700 by Open().
- Errors are normalised: fs.ErrNotExist -> ErrNotFound, anything
  os.Root rejects as "outside" the root -> ErrInvalidPath. The
  HTTP layer can map cleanly to 404 / 400.

Tests cover the full traversal attack surface — "../", absolute
paths, mixed separators, NUL bytes, "." and "" — plus symlink
escapes and cross-tenant isolation. All vectors return errors;
none escape the root.

Closes #10.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 22:17:38 +02:00
..