fix: resolve remaining LOW security-edge items P3-3 and SC-14 - #77
Merged
Conversation
An empty catch around the registry/git-credential and history filter option fetches left the pickers silently empty on failure, which is indistinguishable from 'none configured' — an operator could launch a private-image or -repository scan anonymously believing no credential was saved. Set an optionsError state and reset the lists on failure, and show a non-blocking warning with a Retry action so a failed load is no longer mistaken for 'none configured'. See docs/ARCHIVE.md § 14 (Deviations) for this fix.
…ge (SC-14) The final image stage copies the backend tree wholesale, shipping the pytest suite and the dev env-example script into the published image — needless bloat and attack surface on a security tool's own image. Exclude backend/tests/ and backend/scripts/ from the build context via the root .dockerignore (the only ignore file Docker honors for the context), so the runtime COPY brings in only alembic/, alembic.ini, app/, pyproject.toml, and requirements.lock. No runtime code imports those trees, so the image still runs and imports unchanged. Guarded two ways: a static check in test_dockerfile_supply_chain.py, and a content assertion in the CI dogfood job that runs against the real built image and fails if /app/backend/tests or /app/backend/scripts is present (or if the runtime app/alembic trees go missing). See docs/ARCHIVE.md § 14 (Deviations) for this fix.
tyler-rich
force-pushed
the
claude/session-9d5ra6
branch
from
July 20, 2026 06:30
2199c38 to
74cf78a
Compare
tyler-rich
added a commit
that referenced
this pull request
Jul 31, 2026
The [0.2.0] section carried only what had been written into [Unreleased] since roughly 2026-07-24. Everything promoted in #70 (2026-07-13, i.e. #53-#67) and the #77-#88 batch that followed had never been changelogged at all — v0.1.0 was tagged 2026-07-09 and #70 landed four days later — so about two dozen PRs of security and correctness work that ships in 0.2.0 was absent. Backfilled from the #70 commit range and the §14 entries for that batch, merged into the existing Added/Fixed/Changed/Security sections rather than added as a separate block: 0.2.0 is one release, and a changelog-within-a-changelog would make a reader track which half applies to them. Three of the release's upgrade-affecting items live here and were invisible before: the SSRF egress guard (SCRYE_ALLOW_INTERNAL_EGRESS, default off), the remote-clone-URL requirement for repository targets, and the master-key entropy floor — which refuses to start a v0.1.0 deployment whose key file holds a raw passphrase, and whose remedy is the boot-and-rotate escape hatch plus a backup/restore cycle, not a fresh key. Also records three contract-visible API changes narrower than the envelope: timestamps serialize with an explicit Z, /api/audit renamed entries -> items, and scan list rows dropped options/error in favour of has_error.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves the two still-open LOW items with a security edge from the 2026-07 review-remediation backlog (
docs/reviews/STATUS.md§ "Remaining work"). They touch disjoint files and land as two separate commits.P3-3 — surface credential/filter option-fetch failures (frontend)
NewScanPage.tsxandScansPage.tsxeach wrapped their option fetch in an emptycatch, so a failed load left the credential/filter pickers silently empty — indistinguishable from "none configured." An operator could then launch a private-image or -repository scan anonymously, believing no credential was saved, only for the scan to fail minutes later with an opaque auth error.optionsErrorstate and reset the lists (rather than swallowing the error).Alertwith a Retry action above the registry/git-credential picker, telling the operator saved credentials couldn't load and launching now would scan anonymously.No frontend test added: the Vitest suite runs in the Node environment and covers only pure
src/lib/helpers — there is no jsdom/React-Testing-Library harness to render a page component, and adding one is out of scope for a minimal LOW fix (consistent with the existing untested page-effect posture noted in STATUS.md § 1).SC-14 — keep the backend test suite and dev scripts out of the runtime image (docker)
The final image stage copies the backend tree wholesale (
COPY … backend/ /app/backend/), shippingbackend/tests/andbackend/scripts/into the published scanner image — needless bloat and attack surface.backend/tests/andbackend/scripts/from the build context via the root.dockerignore(the only ignore file Docker honors for a normal build; abackend/.dockerignorewould be a silent no-op), leaving the layer ordering of the final stage untouched.COPY backend/now brings in onlyalembic/,alembic.ini,app/,pyproject.toml, andrequirements.lock— everything Alembic migrations +uvicorn app.main:appneed.tests/scripts(appand the Alembicenv.pyimport only fromapp), so the image still runs and imports unchanged.test_dockerfile_supply_chain.py, plus a content assertion in the CI dogfood job ("Image — build + dogfood self-scan") that runs against the real built image and fails if/app/backend/testsor/app/backend/scriptsis present (or if the runtimeapp/alembictrees go missing). The exclusion was also pre-confirmed by a faithful.dockerignorepattern-match simulation.Testing
tsc, and Vitest (21 tests) all green.ruffandblack --checkclean;test_dockerfile_supply_chain.py(incl. the new SC-14 guard) passes.backend/tests/backend/scripts.Docs
docs/ARCHIVE.md§ 14 entries added for both fixes.docs/reviews/STATUS.mdmoves P3-3 and SC-14 from "Remaining work" to "Resolved."