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
21 changes: 21 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# CodeQL configuration for .github/workflows/codeql.yml.
#
# Queries: the default security suite plus the maintainability/reliability
# queries (what GitHub's separate "Code quality" product runs), and the
# pack's alert-suppression query, which is what makes an inline
# // codeql[<rule-id>]
# comment (alone on its line, covering the next line) suppress one finding
# at one place. Without that query the marker is ignored - which is why the
# JWT-grant false positive in packages/esign-server/src/providers/docusign/auth.ts
# came back as alerts 1, 10 and 15 despite the marker from #58.
#
# A suppression travels with the code (an API dismissal is keyed on the
# alert's fingerprint and re-opens after every file move) and silences one
# site, not the query: a real weak password hash elsewhere still fails.
name: esign

queries:
- uses: security-and-quality

packs:
- codeql/javascript-queries:AlertSuppression.ql
8 changes: 3 additions & 5 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,9 @@ jobs:
uses: github/codeql-action/init@v4
with:
languages: javascript-typescript
# Default security suite plus the maintainability/reliability
# queries (what GitHub's separate "Code quality" product runs).
# Trial: drop this line to go back to security-only if the quality
# findings turn out to be noise next to eslint + typecheck.
queries: security-and-quality
# The query suite and the alert-suppression query (what makes an
# inline `codeql[rule-id]` marker count) live in the config file.
config-file: ./.github/codeql/codeql-config.yml

- name: Analyze
uses: github/codeql-action/analyze@v4
Expand Down
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ Underlying npm scripts (`npm test`, `npm run typecheck`, `npm run lint`,
`examples/*/src/`. `ESignature` is provider-agnostic - adding a provider is a
new `SigningSource`, the component never changes
- `graphql` stays on 16.x repo-wide (Apollo Server 5 peer range)
- A CodeQL false positive is suppressed where it sits: a
`// codeql[<rule-id>]` comment alone on the line above the flagged line
(`.github/codeql/codeql-config.yml` runs the pack's AlertSuppression
query, without which the marker is ignored). Never dismiss it in the
UI/API (fingerprint-keyed: the same finding re-opened three times across
file moves) and never exclude the query (it stays on for real findings)
- The git hooks (lefthook) run format, lint, commitlint and typecheck; CI is
the authoritative gate and every workflow must be green before merge

Expand Down
5 changes: 5 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,11 @@ rm -rf node_modules package-lock.json && npm install # Full reinstall (root loc
- Live DocuSign E2E is opt-in: repo variable `E2E_LIVE=true` (main, releases,
dispatch) or PR label `e2e:live` (same-repo PRs); secrets live in the
`docusign-demo` environment. `docs/operations/live-e2e-ci.md`.
- CodeQL (`codeql.yml`, informational) reads `.github/codeql/codeql-config.yml`,
which runs the suite plus the pack's AlertSuppression query. A false
positive is suppressed in place with `// codeql[<rule-id>]` alone on the
line above the flagged line - never by dismissing the alert (fingerprint-
keyed, re-opens on every file move) and never by excluding the query.
- Native E2E builds are cached on the inputs `scripts/native-deps-hash.sh`
sees plus `android/**` / `ios/**`; bump the cache key's `v` suffix when an
input the script cannot see changes.
Expand Down
2 changes: 1 addition & 1 deletion docs/development-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ diagram: [CI / Release Pipeline](diagrams/README.md#ci--release-pipeline).
| `e2e.yml` | `workflow_call` only | `build-packages` (version stamp, build, publint + arethetypeswrong, pack smoke; uploads the dist for `web` and the tarballs for `Publish`), `docker` (the service image from `examples/full-service-demo/Dockerfile`, same version stamp, booted with the mock provider against `/health` - `make docker-smoke` locally - and uploaded for `Publish`), `server-demos` (boots the mint-only and serverless examples with the mock provider and calls their routes - `make e2e-server-demos`), `live` (opt-in live DocuSign: JWT grant, real mint, Playwright on the real form; [operations/live-e2e-ci.md](operations/live-e2e-ci.md)) plus the E2E suites as jobs: `backend`, `web` (Playwright, bundles the demo against that dist - what a web consumer installs), `build-android` → `android` (emulator), and `build-ios` → `ios` (simulator) **only when opted in** (see below). Outputs the stamped `version` / `disttag` for `Publish` |
| `release.yml` | Push to main; CI completed on main | `Release PR / Tag` (push): keeps the `chore(release): X.Y.Z` PR current (version from the Conventional Commits since the last tag, `CHANGELOG.md` entry); when that PR merges, tags `vX.Y.Z`, creates the GitHub Release and dispatches `ci.yml` at the tag with `release_tag` (a release the workflow token creates never fires the `release:` trigger). `Re-run blocked releases` (CI completed green): re-runs the failed Publish of any release run for that commit (releases wait for / refuse a red main run). See [releasing.md](releasing.md) |
| `pull-request.yml` | PR closed; PR title edited | `Cancel in-flight runs` + `Remove branch badge` (closed): cancels the PR's still-running runs (the push-to-main run is unaffected) and removes its `gh-pages` badge directory. `Title` (edited): re-lints the PR title only; the gating lint is the `Commits` job in `checks.yml` (a title edit must not re-run the whole pipeline) |
| `codeql.yml` | Push to main, PRs, weekly | CodeQL security-and-quality analysis |
| `codeql.yml` | Push to main, PRs, weekly | CodeQL security-and-quality analysis<br>(suite + alert-suppression query:<br>`.github/codeql/codeql-config.yml`) |

Badges are per branch by construction: `gh-pages/badges/X/{unit,e2e,coverage}.svg`
(and a workflow badge filtered with `?branch=X`) all describe branch `X`
Expand Down
10 changes: 6 additions & 4 deletions packages/esign-server/src/providers/docusign/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ export const createJwtAssertion = (
const signingInput = `${base64Url(JSON.stringify(header))}.${base64Url(JSON.stringify(payload))}`;

// JWT-grant signature (RS256), not a password hash: the payload carries the
// OAuth host as the `aud` claim, which is why static analysis flags it
// (js/insufficient-password-hash, dismissed as a false positive in the
// repository's code-scanning alerts; inline markers are not honoured by
// GitHub's default CodeQL setup).
// OAuth host as the `aud` claim, which is why CodeQL's
// js/insufficient-password-hash flags it. The marker below suppresses that
// one finding on the next line (honoured because .github/codeql/codeql-config.yml
// runs the pack's AlertSuppression query); it travels with the code, unlike
// an alert dismissal, and leaves the query on for everything else.
const sign = createSign('RSA-SHA256');
// codeql[js/insufficient-password-hash]
sign.update(signingInput);
const signature = base64Url(sign.sign(config.privateKey as string));
return `${signingInput}.${signature}`;
Expand Down
Loading