Skip to content

Release 0.4.0: deletion-safety hardening - #3

Merged
vindfjur merged 2 commits into
mainfrom
release/0.4.0
Jun 14, 2026
Merged

Release 0.4.0: deletion-safety hardening#3
vindfjur merged 2 commits into
mainfrom
release/0.4.0

Conversation

@vindfjur

Copy link
Copy Markdown
Owner

Hardening release driven by an external security audit.

Highlights

  • Ownership markers + inode identity gate every auto-delete; legacy <=0.3 entries never auto-removed.
  • Journaled, lock-protected, recoverable deletion; ephemdir recover for ambiguous states.
  • fd-relative POSIX cleanup with symlink / parent-trust / mount-boundary checks; no rmtree fallback.
  • Deletion guard (root/home/data-dir) holds even under --force.
  • Real flock registry lock; corrupt/tampered registries quarantined or refused.
  • Service runs python -I -m ephemdir from /; install-service validates interpreter, package tree and startup hooks (trust boundary documented).
  • Python 3.10+ Linux/macOS; reproducible hash-pinned builds.

245 tests, ruff + mypy --strict clean.

vindfjur added 2 commits June 14, 2026 16:03
Driven by an external security audit. No data-loss path may delete a
directory ephemdir cannot prove it created.

- .ephemdir ownership marker (uuid + inode) matched before any auto-delete;
  legacy <=0.3 entries shown as 'legacy' and never auto-removed.
- Journaled two-phase deletion with per-directory OS locks; every sweep
  starts with a recovery pass; ambiguous states parked for `recover`.
- POSIX cleanup is fd-relative (O_DIRECTORY|O_NOFOLLOW, dir_fd ops) with
  symlink, parent-trust and Linux mount-boundary checks; no rmtree fallback.
- Deletion guard refuses root/home/data-dir even with --force.
- Real flock/msvcrt registry lock; corrupt registries quarantined under lock;
  malformed entries rejected on load; world/group-writable registry refused.
- 64-bit random token in names; service runs `python -I -m ephemdir` from /
  with scrubbed env; install-service validates interpreter, full package tree
  and startup hooks (documented trust boundary in README/SECURITY).
- Python 3.10+ on Linux/macOS only; reproducible hash-pinned builds; pinned
  Actions. 245 tests, ruff + mypy --strict clean.
- requirements-build.txt: add tomli==2.4.1 (marker python_version<"3.11")
  with hashes. `build` needs tomli on 3.10 (no stdlib tomllib), which broke
  `pip install --require-hashes` on the 3.10 jobs.
- core._staging_ownership: a recorded-but-missing marker no longer counts an
  inode match as ownership. ext4/tmpfs reuse a freed inode number immediately,
  so a foreign tree recreated at the private staging path could inherit the
  recorded (dev, ino). It is now classified "unverified" and parked for
  recovery instead of deleted. macOS/APFS hid this; Linux CI caught it.
@vindfjur
vindfjur merged commit 35b7325 into main Jun 14, 2026
9 checks passed
@vindfjur
vindfjur deleted the release/0.4.0 branch June 14, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant