chore(audit): workflow-timeout + override-parity guardrails, OAuth state hardening - #114
Merged
Conversation
New github-actions-timeout-required rule in both apps' lint-meta; workflow discovery now walks up to the repo root .github/workflows in the monorepo layout, un-orphaning github-actions-permissions which silently scanned an empty set. Adds the two missing job timeouts the rule surfaced (apps-docs-linkcheck, infra-bootstrap-validate). Audit: F001
…ity rule New package-override-parity lint-meta rule: an app's overrides must be reflected in its own bun.lock and mirrored by sibling apps that resolve the same package. Surfaced three real instances: ui missing ws@8.21.0 (GHSA-58qx-3vcg-4xpx) and qs@6.15.2 (GHSA-q8mj-m7cp-5q26) mirrors of the docs pins, and docs' bun.lock resolving @types/react@19.2.14 despite its 19.2.15 override. Also regenerates the docs lint-meta catalog for this rule and github-actions-timeout-required. Audit: F002
consume() returned {} when the stored Valkey value failed JSON.parse or
was not an object — indistinguishable from a legitimately stored empty
state. Corrupted state now routes through the same null rejection path
as absent/forged state. Adds the missing oauth.state.test.ts covering
round-trip, replay burn, garbage, scalar, and unknown-field stripping.
Audit: F003
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
Executes all 3 findings from today's monorepo audit on one branch. Guardrail-first: 2 of 3 fixes ship as new lint-meta rules that surfaced (and now block) the whole defect class — the rules found 3 more real instances than the audit itself.
F001 —
fix(ci): workflow jobs must declaretimeout-minutes(7b62f8c)github-actions-timeout-requiredlint-meta rule in both apps (jobs without a timeout run to GitHub's 6h default and block PR checks; reusable-workflow calls exempt)..github/workflows— per-app lint-meta looked for<app>/.github/workflows, which doesn't exist in the monorepo layout, so the existinggithub-actions-permissionsrule (SHA pins + permissions blocks) was silently scanning an empty set. It now actually enforces against all 23 workflows. Standalone split-out repos are unaffected (the fallback never triggers).apps-docs-linkcheck(20m) andinfra-bootstrap-validate(10m).F002 —
fix(deps): security-override parity across apps (bf69ffa)package-override-paritylint-meta rule (api, supply-chain): an app'soverridesmust be reflected in its ownbun.lockand mirrored by sibling apps that resolve the same package.ws@8.20.1/7.5.10with no mirror of the docsws@8.21.0pin (GHSA-58qx-3vcg-4xpx) → mirrored.qs@6.15.1with no mirror of the docsqs@6.15.2pin (GHSA-q8mj-m7cp-5q26) → mirrored.bun.lockresolved@types/react@19.2.14despite its own19.2.15override (stale resolution) → re-resolved.ws@7.5.10up to 8.21.0 — security over local-only dev tooling; docs made the identical call. Revisit ifbun run lighthouseregresses.F003 —
fix(api): reject malformed OAuth state (2666bfe)oauthStateStore.consume()returned{}when the stored Valkey value failedJSON.parseor wasn't an object — indistinguishable from a legitimately stored empty state. Corrupted state now routes through the samenullrejection path as forged/expired state (→ 401).oauth.state.test.ts(round-trip, replay burn, garbage, JSON scalar, unknown-field stripping).Audit decisions log:
.audit/execution-summary.json(gitignored, local). The report's 7blocked_or_uncertainitems were skipped by design (they need evidence/maintainer decisions, not code).Test plan
bun run checkgreen in apps/api and apps/ui;bun run check:docs-datagreen in apps/docsConventions
any, no blindas, no!Screenshots
n/a — CI/lint-meta/API-internal changes only.