The latest release on main is the only supported version. Older
versions are not patched; pin to a tag if you need a stable release
window.
Email security@DeepBlueCLtd.github.io (or your project's preferred channel) with a description, reproduction steps, and the affected version/commit. Do not open a public issue for security-sensitive reports.
We aim to acknowledge within 72 hours and ship a fix within 14 days for high-severity issues. Low-severity issues are batched into the next release.
The app accepts the user's own GitHub PAT to enable write operations (create branch, commit, open PR). PAT handling rules:
- Stored in
localStorageonly. Never sent to any server other thanhttps://api.github.com. No telemetry, no third-party storage. - Never logged. PATs do not appear in console output, network inspector previews, or thrown error messages.
- User-revocable. The Settings panel shows whether a token is
stored and offers a "Clear token" action that removes it from
localStorageimmediately. - Scope guidance. The app requires
reposcope (classic PAT) or fine-grainedcontents: read+write+pull requests: read+writeon the target repo. The Settings panel links to GitHub's PAT creation page with the recommended scope pre-selected.
If a user accidentally pastes a token into a shared browser, they should revoke it on github.com immediately — the app cannot revoke tokens on the user's behalf.
Threats specific to a public GitHub Pages SPA driven by Actions:
-
GITHUB_TOKENdeclared at minimum scope per workflow. The default permissions forGITHUB_TOKENwere tightened in 2023; even so, every workflow in.github/workflows/should pin itspermissions:block to exactly what it needs. The kit's defaults:Workflow permissionsci.yml(default — read-only; no writes needed) lighthouse.yml(default) deploy.ymlcontents: write(gh-pages push only)pr-preview.ymlcontents: write,pull-requests: write(sticky comment)pr-preview-cleanup.ymlcontents: writeIf you add a workflow, set its
permissions:at workflow level (not job level) and grant only what's needed. Avoidpermissions: write-all. -
Do not use
pull_request_targetagainst the head ref.pull_request_targetruns in the base repo context and has access to secrets — using it to check out the PR head ref means executing attacker-controlled code with secret access. The kit'spr-preview.ymltriggers on plainpull_request(no secret access; builds run in a sandbox per the GitHub Actions security model) and renders against the bundledVITE_DEFAULT_OWNER/VITE_DEFAULT_REPO, not against the PR's own GitHub history. If you need to act on a PR with elevated scopes, use aworkflow_run-triggered follow-up that reads the artifact produced by thepull_requestjob rather than the head ref directly. -
Pin third-party actions to a commit SHA.
@v4resolves to whatever the action's maintainer points thev4tag at — including, in some past supply-chain incidents, an altered commit. Pin to a SHA for the actions you don't control:uses: JamesIves/github-pages-deploy-action@<full-40-char-sha> # v4.5.0
First-party
actions/*(actions/checkout,actions/setup-node,actions/github-script) are GitHub-maintained and conventionally pinned to@v4major-version tags; pinning these to SHAs is best practice but lower priority than pinning third-party actions. -
.env*files never enter source control. The kit's.gitignoreincludes.envand.env.local. Theimport-from-source.shscript has a Step 3 guard that refuses to proceed if a.env*file is present anywhere in the extracted branch — protecting against a stray committed env file travelling out of the monorepo. If the guard fires: rotate any secrets the file contains immediately, remove the file from the source repo's history (git filter-repoor BFG), then re-run. -
Service-worker scope confined to the app's base path.
vite-plugin-pwais configured so the service worker registers at theVITE_BASE_URLscope (e.g.,/<repo>/). It cannot intercept requests outside that path on the same origin. If a future build moves the app to the origin root (VITE_BASE_URL=/), audit the scope before deploying.
This repo uses the following Actions secrets:
| Secret | Required? | Scope | Used by |
|---|---|---|---|
GITHUB_TOKEN |
Auto-provided | Per-workflow permissions: block |
deploy.yml, pr-preview.yml, pr-preview-cleanup.yml |
LHCI_GITHUB_APP_TOKEN |
Optional | PR status checks | lighthouse.yml |
LIVE_GITHUB_TOKEN |
Optional (opt-in) | Read-only on target repo | live.yml (if enabled) |
GITHUB_TOKEN: auto-rotated per workflow run; no manual rotation.LHCI_GITHUB_APP_TOKEN: rotate annually, or immediately on staff departure / suspected compromise. Update viaSettings → Secrets and variables → Actions.LIVE_GITHUB_TOKEN: fine-grained PAT — rotate per the issuing org's policy. Use a service identity rather than an individual's account where possible.
If a secret is suspected leaked:
- Revoke immediately on github.com (
Settings → Developer settings → Personal access tokensfor PATs;Settings → Appsfor GitHub Apps). - Rotate the secret in
Settings → Secrets and variables → Actions. - Audit recent workflow runs for unexpected activity.
- Open a follow-up issue tracking the rotation and any policy changes the incident reveals.
main should be protected with these settings:
- Require pull request reviews before merging (1 approving review).
- Require status checks to pass before merging:
ci.yml / lint-typecheck-testci.yml / e2elighthouse.yml / lighthouse
- Require branches to be up to date before merging.
- Restrict who can push to
main(deploy automation only).
pr-preview.yml is not a required gate — preview deploys are
nice-to-have, not merge blockers.
This repo ships a small dummy BACKLOG.md and a sample specs/
directory at the root, used to render meaningful content on the
default URL (and on per-PR previews). The dummy dataset is
intentionally generic — no production credentials, no internal links,
no business-confidential strings. If you fork this repo for adopter
use, you may replace the dummy with your own sample content.