AZ-012 — Supply-chain and container quality
Status
Done
Context
Read README, CI, Docker, techstack, testing and DoD. Formatting/lint/types/tests/builds, coverage/OpenAPI/TypeDoc and clean Docker initialization already block PRs. Secret scanning, dependency vulnerabilities, Dockerfile linting and periodic container/license inventories do not. CI has six validation jobs plus trusted-main migration and separate docs publishing. Installed Argon2/session dependencies and auth migrations from AZ-005 make these checks concrete.
Goal
Add useful blocking supply-chain/secret/Dockerfile/migration checks plus bounded periodic diagnostics, preserving existing gate/artifact/deployment contracts.
Requirements
Blocking PR checks
- Introduce canonical root scripts
security:dependencies,secrets:check,containers:lintanddb:checkhere; their exact internal tool versions/configuration belong in manifests, committed wrapper/config files and techstack. Commands must return nonzero on violations or scanner/setup failure; no secrets required. New workflow logic invokes these scripts instead of reimplementing checks in YAML. Do not add these network/container-dependent checks to offlinepnpm quality. - Dependency scan uses pnpm's existing audit facility (high/critical blocking, including relevant
production and development dependencies).
pnpm audit --audit-level highis the baseline; add a wrapper only for tested structured reporting/explicit advisory exceptions. Network/audit service failure is failed verification, not successful empty output. Any exception records specific advisory/package/version scope, owner, reason and expiry; expired exceptions fail. No blanket package/severity ignores or automatic package upgrades in this task. - Secret scan uses the open-source Gitleaks CLI, installed from a pinned release/checksummed binary
or pinned digest container via a committed reproducible wrapper. Do not require a paid Gitleaks
Action license or assume hosted private-repo scanning exists. Scan tracked working-tree files
locally and PR introduced Git history in CI with sufficient checkout history/merge base;
scheduled/manual full-history scan is additional. Redact findings before console/report output.
Known example credentials need narrowly scoped allowlist rules, not entire-file exclusions. Tests
use harmless synthetic scanner patterns, never real secrets. No remediation by merely committing
.gitignoreor burying a discovered real secret in a baseline. - Dockerfile lint uses pinned Hadolint across backend/frontend/db/gateway Dockerfiles. Review genuine existing findings and fix safe focused packaging issues, preserving Node 24/pnpm frozen install/workspace deploy/user/entrypoint/runtime config. Any narrow exception explains the concrete convention (such as deliberate mutable base-tag policy); do not force unrelated image-digest policy/technology change to satisfy generic advice.
- Migration/schema check validates Drizzle configuration/schema and committed SQL/journal
consistency, including no pending generated changes. Use the actual
db:generatemechanism in an isolated temporary copy/output so the check never mutates tracked files; detect new untracked migration output too, not onlygit diff. No handcrafted SQL parsing or separate schema authority. Existing real integration tests from AZ-005 prove fresh/upgrade/rerun; retain them invalidate:docker, not a redundant live database in the static schema job. - Add focused Node infrastructure tests under
tests/ci/for scanner wrappers/config/exit propagation, fixtures and migration drift detection. Existingpnpm test:cidiscovers.test.mjs. Do not test merely that a YAML step exists: exercise representative valid/invalid fixtures and scanner failure where feasible. Secret tests must redact expected matching sentinels too. - Add one blocking
supply-chainjob on normal PR/main CI with bounded timeout/read-only permissions/frozen install. Keep all six existing job identifiers and artifact policies. Add this job to trusted-mainstaging-migratedependencies; it must pass before migrations. Document the expanded operational merge gate and any stage-order changes. No staging secrets in PR jobs and no use ofpull_request_targetto bypass fork restrictions.
Periodic/informational checks
- Add scheduled/manual diagnostics workflow for all-severity dependency inventory, full-history
redacted secret scan, Trivy vulnerability inventory of freshly built application images, and
pnpm licenses list --jsondependency license inventory. Pin non-pnpm tools and avoid sending private source/secrets to unnecessary services. Trivy findings are informational initially; scanner execution failures still fail the diagnostics run. No separate PR image-build matrix or arbitrary license denylist without an actual project licensing decision. - Define modest cadence (weekly) and manual dispatch; no provider/live auth/recovery interaction. If persisting reports, document new names/source paths/format/retention/redaction and successful upload behavior separately from the six mandatory CI artifacts. No raw secret findings or mail previews in uploaded reports. Preserve failure-only Playwright diagnostics.
- Add concise vulnerability triage guidance: update dependency deliberately, test compatibility, scope exceptions, distinguish baseline informational findings from blockers. Do not introduce unsafe auto-fix, automatic application deployment, or speculative infrastructure.
Non-goals
No replacing ESLint/Prettier, security platform subscription, CodeQL/Sonar requirement, broad image/runtime migration, production registry/deployment, arbitrary license policy or scanner count maximization. Full HTML validation and accessibility remain other tasks' responsibilities.
Implementation guidance
Use root scripts/ and tests/ci/ for thin orchestration, respecting lint's existing .mjs
coverage. Wrappers handle paths safely, clean temporary output and validate downloads. Scan the
actual pnpm dependency graph/lockfile, not invented npm package-lock files. Handle private checkout
permissions/read-only artifacts explicitly. If a known real secret is found, stop exposure/record
the blocker and required credential rotation; scanner suppression is not a fix. Do not rotate
external credentials or send messages without authorization.
Acceptance criteria
- New scripts pass on valid source and fail for high/critical advisory fixtures, synthetic secret, genuine Dockerfile problem, migration drift and scanner/setup failure.
- Tools/downloads are pinned/reproducible, secret output redacted and exceptions narrow/expiring.
- Blocking supply-chain CI joins merge and staging-migration gates without removing existing checks or changing six-artifact semantics.
- Periodic diagnostics have bounded cadence, useful vulnerability/license purpose and safe report semantics; informational findings are not confused with verified security/compliance.
- Docker lint fixes preserve packaged startup, migration/seed and auth/native-dependency behavior.
Verification
pnpm quality
pnpm test:ci
pnpm security:dependencies
pnpm secrets:check
pnpm containers:lint
pnpm db:check
pnpm build
The four new scripts are introduced by this task, not baseline commands. Run pnpm validate:docker
if Dockerfiles/config/dependencies change; no duplicate integration/E2E rerun. Add and execute the
periodic script(s) introduced in implementation on safe local/CI inputs; record exact commands.
Hosted workflow conclusions/check discovery/report uploads require real revision-specific CI
evidence; local fixture tests cannot prove Actions permissions or upload success.
Documentation
Update CI/DoD enforcement mapping (new required job and periodic reports), development (setup/new commands/triage), techstack (tools/pinning), Docker (lint exceptions/targeted packaging changes), testing (infrastructure fixture tests), current-state/handover. Do not duplicate the whole gate table into AGENTS.md; retain canonical quality requirement.
Dependencies
AZ-005. May proceed independently of AZ-006–011 with coordinated config/lockfile/CI edits.