0003-owner-scoped-access.patch changes authorization, applied after the
de-brand and dark-theme patches:
- a bucket's ACL and policy may name only the owner's keys (accounts on
the owner's UserID), whoever writes them, root included;
- public access is read-only: all-users READ, and "*" allowed only
s3:GetObject and s3:ListBucket;
- the bucket policy never denies the owner's key;
- DeleteBucket, PutBucketVersioning, PutObjectLockConfiguration and
PutBucketOwnershipControls are reserved to root and admins;
- an ACL with the all-users READ grant can be written back unchanged.
docs/owner-scoped-access.md has the rules, what v1.11.0 already did,
and the leil-rig proof procedure with its 2026-11-10 result: 63 of 63
on the patched build, 29 of 63 failing on stock v1.11.0.
tests/owner-scope/ holds the proof script and a stdlib-only SigV4
request helper. README and the pipeline doc list the patch and how to
re-verify it after a rebase.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Upstream released v1.11.0 (e42ae7a, 2026-11-06): 42 commits, mostly
fixes, plus two WebUI features that add ~415 lines to explorer.html
(on-demand bucket size calculation, restore archived objects).
The series needed no content changes — the regenerated patches differ
from the v1.10.0 ones only in their `index <blob>..<blob>` lines, since
the de-brand edits sit above the regions upstream touched. Regenerating
them is still worthwhile: the v1.10.0 patches' pre-image blobs do not
exist in a v1.11.0 clone, so `git am --3way` could not use its 3-way
fallback and was silently applying them directly.
Verified before committing:
- round-trips from a clean clone to tree 8d509fe
- residual branding identical to the patched v1.10.0 tree (23
occurrences, same per-file spread, no regressions)
- all 5 light-mode Tailwind classes in the new explorer markup are
overridden in theme.css
- series touches only webui/; file count 1049 -> 1051
- goreleaser builds all 8 targets plus deb/rpm
- matrix accepts v1.11.0, refuses v1.10.0, PATCH_DIR still rebuilds
the archived series
v1.10.0 moves to patches/archive/ as *superseded*, not vulnerable: it is
the release carrying upstream's CVE-2026-111943 notice, and that fix
comes from the Go toolchain (>= 1.26.10 / 1.27.3) rather than from the
tag. The archive README and the top-level README now say so, instead of
implying every archived series predates a security fix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
v1.10.0 carries upstream CVE fixes that the older releases predate, so
stop building them. Their series move to patches/archive/<tag>/ rather
than being deleted — still available for a deliberate rebuild, just not
shipped — and ci/support-matrix.yaml now lists v1.10.0 alone.
Dropping the matrix entries was not enough on its own. Two gaps made
"not built" untrue:
* apply-patches.sh only consulted the matrix `if command -v yq`, and the
stock golang CI container has no yq — so in CI the registry was never
actually read. The tag fell through to patches/<tag> every time.
* An empty or missing patch directory was a warning and exit 0, i.e.
"building vanilla upstream". Archiving the directories would therefore
have made a dispatch for v1.8.0 publish an un-de-branded, unpatched,
CVE-vulnerable build under this project's release name — the exact
outcome we are trying to prevent.
So the matrix is now an enforced allowlist: a tag it does not list exits
1, as does a patch directory with no patches in it. It is parsed with yq
when present and with a small awk parse otherwise, so the allowlist holds
in the CI container too. If the parse ever broke, an unmatched tag is
refused rather than built, so the failure mode stays closed.
PATCH_DIR remains the one bypass, and is now the documented way to
rebuild an archived series on purpose. That path also needed a fix: the
patch list is globbed before we cd into the source tree, so a relative
PATCH_DIR — the form the new error message suggests — globbed fine and
then failed in git am. PATCH_DIR is now resolved to an absolute path,
with a missing directory reported as such.
Also re-pointed the runnable examples in README.md, ci/run.sh and the
workflow's dispatch hint from v1.5.0 to v1.10.0; following them verbatim
would now hit the refusal.
Verified by exercising every branch: v1.10.0 applies; v1.8.0 is refused
with exit 1; PATCH_DIR=patches/archive/v1.8.0 rebuilds the archived
series; an empty directory and a nonexistent one are both refused. The
awk parser was checked against defaulted `patches:` fields, several tags
sharing one directory, and comment lines containing decoy `- tag:` text.
All seven archived patch files are recorded as pure renames.
Note: existing published releases for the retired versions stay
downloadable until deleted by hand in Gitea.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
runs-on is now ubuntu-latest (any Linux runner with Docker; toolchain comes from the golang container). The workflow builds one version per run, triggered by a v* tag push or manual workflow_dispatch with a tag input - no scheduled builds. Removes the static matrix (and ci/matrix.sh) and hardens clone-source.sh tag detection to use GITHUB_REF. Docs/README updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ScoutFS-Build-style pipeline that pulls upstream versitygw release tags, applies the web-UI de-brand patch series, and builds GoReleaser releases (binaries + deb/rpm) for publishing to Gitea. Artifact names stay versitygw; only the embedded admin UI is rebranded to S3 Gateway.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>