Repository navigation
Description
Problem and scope
The durable query-job store sets POSIX directory/file modes to 0700/0600, but those mode bits do not remove macOS inherited ACL allow entries. The current jobs.private_dir, database creation, and worker result creation can therefore retain access for another local account when UCSF_AGENT_JOB_ROOT is inside a traversable shared directory with inheritable ACLs. Windows currently relies on the profile's existing ACLs rather than enforcing a protected owner-only DACL.
This is a pre-existing storage boundary, separate from the asynchronous wait/capacity/error improvements. No default-profile disclosure or production compromise is claimed.
Controlled synthetic observation
An independent macOS probe created a temporary parent with an inheritable everyone allow/read/list/search ACL and instantiated the real JobStore beneath it. The managed root reported mode 0700 and the SQLite database mode 0600, while ls -lde still showed an inherited everyone list/search ACL on the root and an everyone read ACL on the database.
The outer temporary directory remained 0700, no real credentials or records were used, and no read by another account was attempted. Actual disclosure additionally requires that another account can traverse every ancestor. Worker results use the same inherited-ACL plus chmod pattern and need the same correction.
Recommended correction while preserving the user experience
- Keep the existing submit, wait, status, cancel and result tools unchanged. Enforce owner-private storage in the backend without adding routine approval dialogs.
- Open managed directories/files with retained no-follow handles. Verify ownership and reject unexpected symbolic links and multiply linked regular private files before repairing permissions; avoid chmod/ACL changes through pathname aliases.
- Remove inherited/unwanted macOS/Linux ACL grants and protect new storage before publishing sensitive bytes. Securely repair existing owned stores before reading them.
- On Windows, apply a protected current-user DACL using a no-reparse retained handle, or fail with an actionable storage-configuration error if that guarantee cannot be established.
- Keep private stores recoverable and explain unsafe ownership/unsupported permission errors rather than silently weakening protection or deleting data.
Acceptance evidence
Include isolated inherited-ACL tests for old and newly created stores, descriptor/symlink/hardlink controls, first-publication checks, platform-specific Windows ACL checks, and a Linux two-UID read-denial control where available. Document untested platforms and distinguish source review from executed verification. Do not claim protection from arbitrary code running as the same OS user.
Related host tracking: BaranziniLab/biorouter#436; analogous owner-private storage concerns: BaranziniLab/biorouter#445 and #453.
Activity
Protect durable job storage with owner-private descriptor repairs
Broccolito commentedon Oct 24, 2026
Independent review found an additional legacy-migration race within this same storage issue. Windows
SetSecurityInfocan propagate inheritable directory ACE changes to existing children. If an ordinary other account can mutate a legacy directory, it can insert an entry after enumeration; a previous whole-tree preflight therefore does not alone bind every object affected by that later propagation. A private parent is insufficient for a known writable child because Windows normally bypasses traversal checks. This scenario does not require root, the same OS account, or a handle opened before migration. See Microsoft's file access rules and SetSecurityInfo behavior.The practical correction being implemented is a conservative preflight of every managed directory before any existing ACL change. Automatic repair refuses directories with effective mutation rights for ordinary other principals, and ACL formats it cannot safely classify. The exceptions are the current user and explicitly privileged SYSTEM/Administrators identities; arbitrary token groups are not treated as trusted. The explicit recovery code is
private_storage_requires_quiescent_repair.Normal already-private stores, concurrent SQLite journals and legacy read-only ACL cleanup keep their existing tools and prompts. For unsafe legacy stores, the response asks the user to stop writers and obtain a trusted administrator's safe repair without following links, or select a fresh private job root while preserving the original store for recovery. Merely moving a directory does not repair its existing ACLs. This avoids quietly applying a recursive permission change to attacker-inserted aliases.
Verification will retain the existing normal-job and outside-alias controls and add a deterministic nested-directory case with effective Everyone-write permission and an unprotected outside hardlink canary. The corrected implementation must refuse before any repair callback and preserve root/child/outside ACLs and file content. An unprotected canary matters because protected DACLs would mask the propagation problem. A same-process deterministic insertion fixture will be labeled accurately; it is not evidence of an actual second-account run unless such a run is performed.
These follow-ups are being verified at new exact heads before merge/closure. They do not claim transactional migration against administrators, arbitrary code running as the same user, or already-open historical handles. No production credentials or records are used.
Broccolito commentedon Oct 24, 2026
Implemented in PR #4, final head
f9a6e40f0e9c92a47fec4b56214474b847c214fe. The backend preserves the six job tools and normal private-store/elevated SQLite workflow. Every managed Windows directory is checked before any existing ACL repair; ordinary foreign mutation grants and unknown ACE forms are refused withprivate_storage_requires_quiescent_repair. Exact process default ownership is accepted only within the current-user/SYSTEM/Builtin-Administrators boundary, while protected DACLs grant only TokenUser.Recommendation for refused legacy stores: stop all writers, retain a backup, and have the owner/administrator remove other ordinary accounts' write/delete/change-permission rights throughout the managed tree, or select a fresh private job root while retaining the old data. Read/list-only inherited ACLs are repaired automatically; no routine approval dialog is introduced.
Validation: all six exact-head Linux/macOS/Windows CI jobs succeeded; Windows execution passed ten controls with zero skips. These include an unprotected outside-canary propagation boundary, nested foreign-writable refusal before any repair callback, actual link/ACL/SQLite controls, and injected unknown-ACE/non-admin-owner helper negatives. No production credentials, PHI or live database queries were used. Native host acceptance remains tracked separately in BaranziniLab/biorouter#436; same-user/admin processes and pre-existing foreign handles remain outside the stated threat model.
Complete async query-job waiting and result handoff (#4)