Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

# None of this workflow's jobs write to the repository, comment on PRs, or
# otherwise need more than read access to the checked-out code. Pin an
# explicit least-privilege ceiling here rather than inheriting the ambient
# repository/org default GITHUB_TOKEN grant (mirrors release.yml, which
# scopes itself to the single `contents: write` it actually needs).
permissions:
contents: read

env:
DATABASE_URL: postgresql://fanilab:fanilab@localhost:5432/fanilab_backend?schema=public
REDIS_URL: redis://localhost:6379
Expand Down
8 changes: 7 additions & 1 deletion docs/SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,13 @@ Dependabot (`.github/dependabot.yml`) tracks npm, Docker base images, and GitHub

Dependabot only proposes upgrades — it does not fail a build for a known-vulnerable dependency that hasn't been upgraded yet. To close that gap, the `audit` job in `.github/workflows/ci.yml` runs `pnpm audit --audit-level=high` on every PR and on `main`; a `high` or `critical` advisory anywhere in the dependency tree (direct or transitive) fails CI. Run it locally with `pnpm audit`.

**Accepted exceptions:** none currently. If an advisory has no available fix and must be temporarily tolerated, it must be listed here with the advisory id, the affected package, a rationale, and an owner — the audit threshold is never lowered globally to work around a single unfixable advisory.
**Accepted exceptions:** none currently at or above the `high` CI threshold. If an advisory has no available fix and must be temporarily tolerated, it must be listed here with the advisory id, the affected package, a rationale, and an owner — the audit threshold is never lowered globally to work around a single unfixable advisory.

**Known residual advisories below the `high` threshold** (do not fail CI, recorded here for visibility):

- `GHSA-w5hq-g745-h8pq` — `uuid` <11.1.1, missing buffer bounds check in v3/v5/v6 when a `buf` argument is supplied. Reached only via `autocannon > hyperid > uuid`; `autocannon` is a dev-only load-testing tool (`pnpm load-test`), never bundled or run in production, and this project never passes a `buf` argument. No override is applied because `hyperid` has not published a release depending on a patched `uuid`.

The `pnpm.overrides` block in `package.json` pins forward-patched versions of `tar`, `handlebars`, `vite`, `esbuild`, `nanoid`, `js-yaml`, and `fast-uri` — all pulled in transitively through build/lint/test tooling (`bcrypt`'s native-build toolchain, `eslint-plugin-boundaries`, the Vitest/Vite stack) — to clear the `critical`/`high` advisories those chains carried.

## Reporting Timeline & Disclosure

Expand Down
16 changes: 13 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"@types/bcrypt": "^5.0.2",
"@types/jsonwebtoken": "^9.0.7",
"@types/node": "^22.9.0",
"@vitest/coverage-v8": "^2.1.4",
"@vitest/coverage-v8": "^3.2.7",
"autocannon": "^8.0.0",
"eslint": "^9.14.0",
"eslint-config-prettier": "^9.1.0",
Expand All @@ -75,7 +75,7 @@
"tsx": "^4.23.12",
"typescript": "^5.6.3",
"typescript-eslint": "^8.67.0",
"vitest": "^2.1.4"
"vitest": "^3.2.7"
},
"lint-staged": {
"*.{ts,js}": [
Expand All @@ -96,6 +96,16 @@
"esbuild",
"msgpackr-extract",
"prisma"
]
],
"overrides": {
"tar@<7.5.21": ">=7.5.21",
"handlebars@<4.7.9": ">=4.7.9",
"vite@<6.4.3": "^6.4.3",
"esbuild@<0.25.0": "^0.25.0",
"nanoid@<3.3.18": "^3.3.18",
"js-yaml@<4.3.1": "^4.3.1",
"fast-uri@<3.1.5": "^3.1.5",
"@fastify/static@<10.1.2": "^10.1.2"
}
}
}
Loading
Loading