Skip to content

fix(daemon): keep qsv get downloads private with qsv 26.x; name qsv 27.0.1 - #38

Merged
jqnatividad merged 4 commits into
mainfrom
feat/private-get-cache-pre-27
Oct 27, 2026
Merged

jqnatividad merged 4 commits into
mainfrom
feat/private-get-cache-pre-27

Conversation

@jqnatividad

@jqnatividad jqnatividad commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Privacy hardening for qsv-clientd's downloads through qsv get, and the switch from qsv 27.0.0 (withdrawn) to 27.0.1 in user-facing text.

Changes

  • Private get cache before qsv 27 (f59b657): with qsv 26.x or older that has get (qsvdp or a source build; the prebuilt qsv has it from 27.0.1), qsv-clientd sets QSV_CACHE_DIR to qsv-cache in its own directory, made 0700, for both get and get cache-fetch (they must share one cache). Those versions make their cache with the umask's modes. qsv 27 (fix(get): make the get cache and its dc: copies owner-only qsv#4928) keeps it owner-only itself, so it is left alone, as is a QSV_CACHE_DIR the user set.
  • Downloads never readable by others while qsv writes them (cddb731): viz <URL> and register --download stage in the folder the user chose. cache-fetch --output now writes into a 0700 mkdtemp directory inside it; the file is made 0600 there, moved into place, and the directory is always removed. Before, the file was made 0600 only after qsv finished. Fetch latest was never exposed (it stages in the daemon's 0700 cache). This matters with current qsv too: qsv 27.0.1 writes --output with the umask's modes, like its other writers (fix(get): --output files follow the umask, not the cache's 0600 qsv#4945). Fixes roborev findings 5881 and 5918.
  • qsv 27.0.1 (32c9aac, 361de5a): 27.0.0 was withdrawn before release, so the README, package description, DAEMON.md example, and the message serve and the tray show with an older qsv now name 27.0.1. The version checks (LIVE_SCHEMATICS_QSV, PRIVATE_GET_CACHE_QSV) stay at 27.0.0: builds of qsv master reporting 27.0.0 have every feature 27.0.1 does. The CHANGELOG notes the withdrawal; the released 0.6.0 notes are left as they were.

Testing

  • Full suite: 773 passed, 2 skipped (Windows-only) against a qsv 27.0.1 dev build, a qsv 27.0.0 dev build, and qsv 26.0.0.
  • The pre-27 get path is exercised only by the fake_qsv tests: the prebuilt qsv 26.0.0 has no get, and no qsvdp 26.x was available locally.
  • ruff, mypy, and mypy --platform win32 clean; new lines fully covered.

🤖 Generated with Claude Code

jqnatividad and others added 3 commits October 27, 2026 07:38
qsv 26.x and older make their `get` cache with the umask's modes, and a
download may be private (a CKAN token, a signed URL). With such a qsv
(qsvdp or a source build; the prebuilt qsv has `get` from 27.0.0),
qsv-clientd now points QSV_CACHE_DIR at `qsv-cache` in its own
directory, made 0700, for both `get` and `get cache-fetch`, which must
share one cache. qsv 27.0.0+ keeps its cache owner-only on Unix, so it
is left alone, as is a QSV_CACHE_DIR the user set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`viz <URL>` and `register --download` stage the data in the folder the
user chose for it. qsv writes `get cache-fetch --output` with the
umask's mode (often 0644), and the file was made 0600 only after qsv
finished, so another user could open it in the meantime if that folder
was readable to them. qsv now writes into a 0700 directory made inside
the staging folder (same filesystem); the file is made 0600 there,
moved into place, and the directory is always removed. Fetch latest
was never exposed: it stages in the daemon's own 0700 cache.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
qsv 27.0.0 was withdrawn before its release, so the README, the
package description, the DAEMON.md example and the message shown with
an older qsv now name 27.0.1. The version checks stay at 27.0.0: builds
of qsv master that report 27.0.0 have every feature 27.0.1 does, and
raising the floor would treat them as older qsv. The CHANGELOG notes
the withdrawal, and its Security entries now say that only qsv 26.x or
older with `get` was affected, since qsv 27 keeps the cache and
`cache-fetch --output` owner-only itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.29%. Comparing base (38c69b0) to head (361de5a).

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #38   +/-   ##
=======================================
  Coverage   99.29%   99.29%           
=======================================
  Files          30       30           
  Lines        4230     4247   +17     
  Branches      550      552    +2     
=======================================
+ Hits         4200     4217   +17     
  Misses         16       16           
  Partials       14       14           
Files with missing lines Coverage Δ
src/qsv_client/daemon/config.py 100.00% <100.00%> (ø)
src/qsv_client/daemon/fetch.py 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

qsv 27.0.1 (dathere/qsv#4945) writes `get cache-fetch --output` with the
umask's modes, as qsv's other writers do, so the staging fix protects
downloads with current qsv too, not only with qsv 26.x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jqnatividad
jqnatividad merged commit a3a2563 into main Oct 27, 2026
21 checks passed
@jqnatividad
jqnatividad deleted the feat/private-get-cache-pre-27 branch October 27, 2026 12:09
@jqnatividad jqnatividad mentioned this pull request Oct 27, 2026
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