@zigrivers/scaffold 3.6.0 → 3.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -12
- package/content/knowledge/backend/backend-api-design.md +103 -0
- package/content/knowledge/backend/backend-architecture.md +100 -0
- package/content/knowledge/backend/backend-async-patterns.md +101 -0
- package/content/knowledge/backend/backend-auth-patterns.md +100 -0
- package/content/knowledge/backend/backend-conventions.md +105 -0
- package/content/knowledge/backend/backend-data-modeling.md +102 -0
- package/content/knowledge/backend/backend-deployment.md +100 -0
- package/content/knowledge/backend/backend-dev-environment.md +102 -0
- package/content/knowledge/backend/backend-observability.md +102 -0
- package/content/knowledge/backend/backend-project-structure.md +100 -0
- package/content/knowledge/backend/backend-requirements.md +103 -0
- package/content/knowledge/backend/backend-security.md +104 -0
- package/content/knowledge/backend/backend-testing.md +101 -0
- package/content/knowledge/backend/backend-worker-patterns.md +100 -0
- package/content/knowledge/cli/cli-architecture.md +101 -0
- package/content/knowledge/cli/cli-conventions.md +117 -0
- package/content/knowledge/cli/cli-dev-environment.md +121 -0
- package/content/knowledge/cli/cli-distribution-patterns.md +106 -0
- package/content/knowledge/cli/cli-interactivity-patterns.md +116 -0
- package/content/knowledge/cli/cli-output-patterns.md +107 -0
- package/content/knowledge/cli/cli-project-structure.md +124 -0
- package/content/knowledge/cli/cli-requirements.md +101 -0
- package/content/knowledge/cli/cli-shell-integration.md +130 -0
- package/content/knowledge/cli/cli-testing.md +134 -0
- package/content/knowledge/library/library-api-design.md +306 -0
- package/content/knowledge/library/library-architecture.md +247 -0
- package/content/knowledge/library/library-bundling.md +244 -0
- package/content/knowledge/library/library-conventions.md +229 -0
- package/content/knowledge/library/library-dev-environment.md +220 -0
- package/content/knowledge/library/library-documentation.md +300 -0
- package/content/knowledge/library/library-project-structure.md +237 -0
- package/content/knowledge/library/library-requirements.md +173 -0
- package/content/knowledge/library/library-security.md +257 -0
- package/content/knowledge/library/library-testing.md +319 -0
- package/content/knowledge/library/library-type-definitions.md +284 -0
- package/content/knowledge/library/library-versioning.md +300 -0
- package/content/knowledge/mobile-app/mobile-app-architecture.md +283 -0
- package/content/knowledge/mobile-app/mobile-app-conventions.md +180 -0
- package/content/knowledge/mobile-app/mobile-app-deployment.md +298 -0
- package/content/knowledge/mobile-app/mobile-app-dev-environment.md +257 -0
- package/content/knowledge/mobile-app/mobile-app-distribution.md +264 -0
- package/content/knowledge/mobile-app/mobile-app-observability.md +317 -0
- package/content/knowledge/mobile-app/mobile-app-offline-patterns.md +311 -0
- package/content/knowledge/mobile-app/mobile-app-project-structure.md +245 -0
- package/content/knowledge/mobile-app/mobile-app-push-notifications.md +321 -0
- package/content/knowledge/mobile-app/mobile-app-requirements.md +147 -0
- package/content/knowledge/mobile-app/mobile-app-security.md +338 -0
- package/content/knowledge/mobile-app/mobile-app-testing.md +400 -0
- package/content/knowledge/web-app/web-app-api-patterns.md +224 -0
- package/content/knowledge/web-app/web-app-architecture.md +116 -0
- package/content/knowledge/web-app/web-app-auth-patterns.md +256 -0
- package/content/knowledge/web-app/web-app-conventions.md +121 -0
- package/content/knowledge/web-app/web-app-data-patterns.md +218 -0
- package/content/knowledge/web-app/web-app-deployment-workflow.md +143 -0
- package/content/knowledge/web-app/web-app-deployment.md +134 -0
- package/content/knowledge/web-app/web-app-design-system.md +158 -0
- package/content/knowledge/web-app/web-app-dev-environment.md +173 -0
- package/content/knowledge/web-app/web-app-observability.md +221 -0
- package/content/knowledge/web-app/web-app-project-structure.md +160 -0
- package/content/knowledge/web-app/web-app-rendering-strategies.md +133 -0
- package/content/knowledge/web-app/web-app-requirements.md +112 -0
- package/content/knowledge/web-app/web-app-security.md +193 -0
- package/content/knowledge/web-app/web-app-session-patterns.md +214 -0
- package/content/knowledge/web-app/web-app-testing.md +249 -0
- package/content/knowledge/web-app/web-app-ux-patterns.md +162 -0
- package/content/methodology/backend-overlay.yml +73 -0
- package/content/methodology/cli-overlay.yml +69 -0
- package/content/methodology/library-overlay.yml +67 -0
- package/content/methodology/mobile-app-overlay.yml +71 -0
- package/content/methodology/web-app-overlay.yml +79 -0
- package/dist/cli/commands/init.d.ts +21 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +261 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +206 -0
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/config/schema.d.ts +1392 -64
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +82 -5
- package/dist/config/schema.js.map +1 -1
- package/dist/config/schema.test.js +302 -1
- package/dist/config/schema.test.js.map +1 -1
- package/dist/core/assembly/overlay-loader.d.ts.map +1 -1
- package/dist/core/assembly/overlay-loader.js +2 -1
- package/dist/core/assembly/overlay-loader.js.map +1 -1
- package/dist/core/assembly/overlay-loader.test.js +56 -0
- package/dist/core/assembly/overlay-loader.test.js.map +1 -1
- package/dist/e2e/game-pipeline.test.js +1 -0
- package/dist/e2e/game-pipeline.test.js.map +1 -1
- package/dist/e2e/project-type-overlays.test.d.ts +16 -0
- package/dist/e2e/project-type-overlays.test.d.ts.map +1 -0
- package/dist/e2e/project-type-overlays.test.js +834 -0
- package/dist/e2e/project-type-overlays.test.js.map +1 -0
- package/dist/types/config.d.ts +19 -2
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +0 -1
- package/dist/types/index.js.map +1 -1
- package/dist/wizard/questions.d.ts +27 -1
- package/dist/wizard/questions.d.ts.map +1 -1
- package/dist/wizard/questions.js +142 -3
- package/dist/wizard/questions.js.map +1 -1
- package/dist/wizard/questions.test.js +206 -8
- package/dist/wizard/questions.test.js.map +1 -1
- package/dist/wizard/wizard.d.ts +21 -0
- package/dist/wizard/wizard.d.ts.map +1 -1
- package/dist/wizard/wizard.js +27 -1
- package/dist/wizard/wizard.js.map +1 -1
- package/package.json +1 -1
- package/dist/types/wizard.d.ts +0 -14
- package/dist/types/wizard.d.ts.map +0 -1
- package/dist/types/wizard.js +0 -2
- package/dist/types/wizard.js.map +0 -1
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: library-requirements
|
|
3
|
+
description: API contract stability, semver commitments, consumer compatibility, and breaking change policy for published libraries
|
|
4
|
+
topics: [library, requirements, semver, api-contract, breaking-changes, compatibility]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Library requirements differ fundamentally from application requirements: every public API decision becomes a contract with downstream consumers who cannot easily update. Stability, predictability, and clear communication of change are the highest-priority concerns. A library that breaks its consumers silently, or without adequate notice, loses trust permanently.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Library requirements must explicitly capture the public API surface and the stability guarantees attached to each part of it. Distinguish stable APIs (semver-protected), experimental APIs (no stability guarantee), and internal APIs (not for external use). Document breaking change policy, minimum supported runtime versions, and peer dependency expectations upfront. Requirements must include consumer use cases — not just feature descriptions — because API design is driven by how consumers will actually call the library.
|
|
12
|
+
|
|
13
|
+
Key commitments to define:
|
|
14
|
+
- Which exports are public and semver-protected
|
|
15
|
+
- Which are experimental (`@alpha`, `@beta`, `@experimental`)
|
|
16
|
+
- Minimum Node.js / runtime versions supported
|
|
17
|
+
- Peer dependency version ranges and their constraints
|
|
18
|
+
- Deprecation notice period before removal (recommended: 2+ major versions)
|
|
19
|
+
- Supported environments (ESM-only, CJS-only, dual, browser, Node-only, universal)
|
|
20
|
+
|
|
21
|
+
## Deep Guidance
|
|
22
|
+
|
|
23
|
+
### API Contract as a First-Class Requirement
|
|
24
|
+
|
|
25
|
+
The public API surface is a contract. Treat it with the same rigor as a legal agreement. Before writing any code, define:
|
|
26
|
+
|
|
27
|
+
**What is public:**
|
|
28
|
+
```
|
|
29
|
+
Public API (semver-protected):
|
|
30
|
+
- All named exports from the package root (index.ts)
|
|
31
|
+
- All types and interfaces exported from the root
|
|
32
|
+
- Constructor signatures, method names, parameter order, return types
|
|
33
|
+
- Error types thrown by public methods
|
|
34
|
+
- Event names and payload shapes (for event-emitter APIs)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**What is explicitly internal:**
|
|
38
|
+
```
|
|
39
|
+
Internal (not public, no stability guarantee):
|
|
40
|
+
- Anything exported from /internal/* paths
|
|
41
|
+
- _prefixed exports (by convention)
|
|
42
|
+
- Anything documented as "implementation detail"
|
|
43
|
+
- Test utilities not in a separate @scope/lib-test-utils package
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**What is experimental:**
|
|
47
|
+
```
|
|
48
|
+
Experimental (may change without semver):
|
|
49
|
+
- Exports tagged @alpha or @beta in JSDoc
|
|
50
|
+
- Features behind feature flags
|
|
51
|
+
- Exports from /experimental/* subpaths
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Define these categories in your requirements document, not in code comments alone.
|
|
55
|
+
|
|
56
|
+
### Semver Commitments
|
|
57
|
+
|
|
58
|
+
Semver has precise semantics for libraries. Teams frequently misapply it:
|
|
59
|
+
|
|
60
|
+
**PATCH (1.0.x):** Bug fixes only. No new APIs. No behavior changes for correct usage. A bug fix that changes observable behavior in a way consumers may depend on is a MINOR or MAJOR change.
|
|
61
|
+
|
|
62
|
+
**MINOR (1.x.0):** Backward-compatible additions. New exports. New optional parameters (at the end of argument lists). New optional properties on config objects. Extending return types with additional optional fields. New overloads.
|
|
63
|
+
|
|
64
|
+
**MAJOR (x.0.0):** Any breaking change. This includes:
|
|
65
|
+
- Removing or renaming exports
|
|
66
|
+
- Changing required parameter types or order
|
|
67
|
+
- Narrowing accepted input types
|
|
68
|
+
- Widening return types in ways that break type narrowing
|
|
69
|
+
- Changing thrown error types
|
|
70
|
+
- Dropping support for a previously supported Node.js version
|
|
71
|
+
- Changing peer dependency minimum versions
|
|
72
|
+
- Behavior changes that violate documented semantics
|
|
73
|
+
|
|
74
|
+
A common mistake: treating TypeScript type-only changes as "not breaking." Changing a type from `string` to `string | null` is a breaking change for consumers who never account for null.
|
|
75
|
+
|
|
76
|
+
### Consumer Compatibility Matrix
|
|
77
|
+
|
|
78
|
+
Requirements must specify the compatibility matrix:
|
|
79
|
+
|
|
80
|
+
```markdown
|
|
81
|
+
## Runtime Support
|
|
82
|
+
|
|
83
|
+
| Runtime | Minimum Version | Status |
|
|
84
|
+
|----------------|-----------------|------------|
|
|
85
|
+
| Node.js | 18.0.0 | Supported |
|
|
86
|
+
| Node.js | 20.0.0 | Supported |
|
|
87
|
+
| Node.js | 22.0.0 | Supported |
|
|
88
|
+
| Bun | 1.0.0 | Supported |
|
|
89
|
+
| Deno | 1.40.0 | Experimental |
|
|
90
|
+
| Browser (ESM) | Modern (ES2020) | Supported |
|
|
91
|
+
|
|
92
|
+
## TypeScript Support
|
|
93
|
+
|
|
94
|
+
Minimum TypeScript version: 5.0
|
|
95
|
+
Bundled type definitions: Yes (.d.ts in dist/)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Define this matrix in requirements, not after the fact. Dropping Node 18 support is a major version bump — plan it deliberately.
|
|
99
|
+
|
|
100
|
+
### Peer Dependency Policy
|
|
101
|
+
|
|
102
|
+
Peer dependencies express "your project must also have X installed." They are fundamentally different from regular dependencies:
|
|
103
|
+
|
|
104
|
+
**When to use peer dependencies:**
|
|
105
|
+
- The library is an extension/plugin of another library (e.g., a React component library — React is a peer)
|
|
106
|
+
- The library integrates with a framework the consumer already has
|
|
107
|
+
- Bundling the dependency would create duplicate instances (React, any singleton library)
|
|
108
|
+
|
|
109
|
+
**Peer dependency requirements to document:**
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"peerDependencies": {
|
|
113
|
+
"react": ">=18.0.0",
|
|
114
|
+
"react-dom": ">=18.0.0"
|
|
115
|
+
},
|
|
116
|
+
"peerDependenciesMeta": {
|
|
117
|
+
"react-dom": {
|
|
118
|
+
"optional": true
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
State in requirements: which peer deps are required vs. optional, and what happens if the consumer provides an incompatible version.
|
|
125
|
+
|
|
126
|
+
### Breaking Change Policy
|
|
127
|
+
|
|
128
|
+
Document your policy before you ship v1:
|
|
129
|
+
|
|
130
|
+
**Recommended policy:**
|
|
131
|
+
1. No breaking changes in patch or minor releases (strict semver)
|
|
132
|
+
2. Deprecate before removing: at least one minor release with `@deprecated` JSDoc
|
|
133
|
+
3. Major version bump for any breaking change, no matter how small
|
|
134
|
+
4. Provide migration guide for every major version bump
|
|
135
|
+
5. Maintain previous major version with security patches for N months after next major (define N upfront — 12 months is common)
|
|
136
|
+
6. Communicate breaking changes in CHANGELOG.md with migration steps
|
|
137
|
+
|
|
138
|
+
**Experimental API exception:**
|
|
139
|
+
Experimental APIs tagged `@alpha` or `@beta` may break in minor or patch releases. Consumers opt in by using experimental exports. Document this explicitly.
|
|
140
|
+
|
|
141
|
+
### Use-Case-Driven Requirements
|
|
142
|
+
|
|
143
|
+
Library requirements fail when they describe features instead of consumer use cases. Write requirements from the consumer's perspective:
|
|
144
|
+
|
|
145
|
+
**Weak (feature-centric):**
|
|
146
|
+
> The library exports a `parse()` function that accepts a string and returns an object.
|
|
147
|
+
|
|
148
|
+
**Strong (use-case-centric):**
|
|
149
|
+
> A consumer building a configuration loader needs to: (1) parse a TOML string into a typed JavaScript object, (2) receive a typed parse error with line/column information if parsing fails, (3) validate the parsed object against a schema and receive typed validation errors. The API must be synchronous (no async) for use in module initialization.
|
|
150
|
+
|
|
151
|
+
Use cases drive API design. The feature-centric description could be satisfied by dozens of different APIs; the use-case description constrains the design to what actually serves consumers.
|
|
152
|
+
|
|
153
|
+
### Minimum Viable Requirements Checklist
|
|
154
|
+
|
|
155
|
+
Before beginning library implementation:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
[ ] Public API surface enumerated (all exports listed)
|
|
159
|
+
[ ] Stability tier assigned to each export (stable / experimental / internal)
|
|
160
|
+
[ ] Supported runtime versions documented
|
|
161
|
+
[ ] Supported TypeScript versions documented
|
|
162
|
+
[ ] Peer dependencies and version ranges documented
|
|
163
|
+
[ ] Breaking change policy written
|
|
164
|
+
[ ] Deprecation notice period specified
|
|
165
|
+
[ ] Distribution format requirements (ESM, CJS, both, IIFE)
|
|
166
|
+
[ ] Bundle size budget (if applicable — important for browser libraries)
|
|
167
|
+
[ ] Tree-shaking requirement (yes/no and constraints)
|
|
168
|
+
[ ] License and attribution requirements
|
|
169
|
+
[ ] At least 3 concrete consumer use cases documented
|
|
170
|
+
[ ] Error handling contract defined (throws vs. returns Result type)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
This checklist is non-negotiable for any library that will have external consumers.
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: library-security
|
|
3
|
+
description: Supply chain security, dependency auditing, npm provenance, SBOM, and security policy for published libraries
|
|
4
|
+
topics: [library, security, supply-chain, npm-provenance, sbom, dependency-auditing, cve]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Library security is supply chain security. When a library is published to npm and installed by thousands of projects, a single compromised release or a malicious dependency can propagate vulnerabilities to all consumers simultaneously. The 2021 `ua-parser-js` incident and the 2022 `node-ipc` sabotage demonstrated that even widely-used libraries with established maintainers can be compromised. Library authors bear a responsibility to their consumers that application developers do not — a security failure in a library is a security failure for every project that depends on it.
|
|
8
|
+
|
|
9
|
+
## Summary
|
|
10
|
+
|
|
11
|
+
Library security encompasses four areas: dependency hygiene (minimal, audited, regularly updated dependencies), publish security (protected npm accounts, CI-based publishing with provenance), input validation (libraries that process untrusted input must handle malformed data safely), and disclosure (responsible vulnerability reporting process for consumers to report issues). Enable npm provenance on all published packages. Pin GitHub Actions to commit SHAs. Keep devDependencies patched and runtime dependencies minimal.
|
|
12
|
+
|
|
13
|
+
Core security practices:
|
|
14
|
+
- `npm audit` in CI — fail on high/critical vulnerabilities
|
|
15
|
+
- npm publish with `--provenance` for attestation
|
|
16
|
+
- Two-factor authentication on npm account
|
|
17
|
+
- Pin GitHub Actions to commit SHAs, not tags
|
|
18
|
+
- SECURITY.md with disclosure process
|
|
19
|
+
- Minimal runtime dependencies (each dep is an attack surface)
|
|
20
|
+
|
|
21
|
+
## Deep Guidance
|
|
22
|
+
|
|
23
|
+
### Dependency Auditing
|
|
24
|
+
|
|
25
|
+
Every dependency is a trust decision. Minimize trust surface:
|
|
26
|
+
|
|
27
|
+
**In CI, fail on vulnerabilities:**
|
|
28
|
+
```yaml
|
|
29
|
+
# .github/workflows/ci.yml
|
|
30
|
+
- name: Security audit
|
|
31
|
+
run: npm audit --audit-level=high
|
|
32
|
+
# Fails if any high or critical CVEs are found in dependencies
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Regular automated updates:**
|
|
36
|
+
```yaml
|
|
37
|
+
# .github/dependabot.yml
|
|
38
|
+
version: 2
|
|
39
|
+
updates:
|
|
40
|
+
- package-ecosystem: npm
|
|
41
|
+
directory: /
|
|
42
|
+
schedule:
|
|
43
|
+
interval: weekly
|
|
44
|
+
open-pull-requests-limit: 10
|
|
45
|
+
groups:
|
|
46
|
+
devDependencies:
|
|
47
|
+
dependency-type: development
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Dependabot opens PRs for dependency updates weekly. Review them and merge; don't let them accumulate. Stale dependencies accumulate vulnerabilities.
|
|
51
|
+
|
|
52
|
+
**Audit devDependencies too:**
|
|
53
|
+
```bash
|
|
54
|
+
# npm audit includes devDependencies by default
|
|
55
|
+
npm audit
|
|
56
|
+
|
|
57
|
+
# Check only production dependencies (what consumers install)
|
|
58
|
+
npm audit --omit=dev
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
A vulnerability in a devDependency can compromise your CI pipeline and inject malicious code into the published package even if consumers never install the devDependency.
|
|
62
|
+
|
|
63
|
+
### npm Provenance
|
|
64
|
+
|
|
65
|
+
npm provenance creates a cryptographic link between a published package and the GitHub Actions workflow that built it. Consumers can verify that `my-library@1.0.0` was built from exactly commit `abc123` by the expected workflow:
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
# .github/workflows/release.yml
|
|
69
|
+
jobs:
|
|
70
|
+
release:
|
|
71
|
+
permissions:
|
|
72
|
+
id-token: write # Required for provenance
|
|
73
|
+
contents: read
|
|
74
|
+
steps:
|
|
75
|
+
- run: npm publish --provenance --access public
|
|
76
|
+
env:
|
|
77
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
After publishing with `--provenance`, consumers can verify:
|
|
81
|
+
```bash
|
|
82
|
+
npm audit signatures my-library
|
|
83
|
+
# Verifies: Attestation verified for my-library@1.0.0
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Provenance is essential for libraries installed in security-sensitive environments. Enable it on all public packages.
|
|
87
|
+
|
|
88
|
+
### npm Account Security
|
|
89
|
+
|
|
90
|
+
The npm account is the most critical attack surface for library security:
|
|
91
|
+
|
|
92
|
+
1. **Enable 2FA (mandatory):** npm.com → Account Settings → Two-Factor Authentication → Enable for auth and publishing
|
|
93
|
+
2. **Use Granular Access Tokens:** Create a publish token with `Automation` type and scope to specific packages only
|
|
94
|
+
3. **Rotate tokens regularly:** Invalidate and recreate publish tokens quarterly
|
|
95
|
+
4. **Use trusted publishing** (npm + GitHub Actions OIDC): Eliminates long-lived tokens entirely:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# npm trusted publishing: configure in npm package settings, then:
|
|
99
|
+
npm publish --provenance
|
|
100
|
+
# No NPM_TOKEN secret needed — GitHub OIDC provides the auth
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Trusted publishing is the most secure approach — there is no token to steal, rotate, or accidentally expose in logs.
|
|
104
|
+
|
|
105
|
+
### Pinning GitHub Actions to Commit SHAs
|
|
106
|
+
|
|
107
|
+
GitHub Actions tags (like `actions/checkout@v4`) can be moved by the action author, making them effectively mutable. A compromised action author could update `v4` to inject malicious code. Pin to commit SHAs:
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
# BAD: tag can be moved
|
|
111
|
+
- uses: actions/checkout@v4
|
|
112
|
+
- uses: actions/setup-node@v4
|
|
113
|
+
|
|
114
|
+
# GOOD: pinned to specific commit
|
|
115
|
+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
|
116
|
+
- uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af # v4.1.0
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Use a tool like `renovate` or `pin-github-action` to automate SHA pinning and updates:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx pin-github-action .github/workflows/*.yml
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This converts all `@v4` references to pinned SHAs and creates a comment with the resolved version.
|
|
126
|
+
|
|
127
|
+
### Input Validation and Denial of Service
|
|
128
|
+
|
|
129
|
+
Libraries that parse untrusted input must handle malformed data defensively:
|
|
130
|
+
|
|
131
|
+
**ReDoS (Regular Expression Denial of Service):**
|
|
132
|
+
```typescript
|
|
133
|
+
// VULNERABLE: catastrophic backtracking on malformed input
|
|
134
|
+
const emailRegex = /^([a-zA-Z0-9]+)*@/
|
|
135
|
+
|
|
136
|
+
// SAFE: linear time regex or use a dedicated library
|
|
137
|
+
import { isEmail } from 'validator' // battle-tested input validation library
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Test regex performance with adversarial inputs:
|
|
141
|
+
```bash
|
|
142
|
+
npx vuln-regex-detector 'your regex here'
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Size limits for inputs:**
|
|
146
|
+
```typescript
|
|
147
|
+
export function parseConfig(input: string, options?: ParseOptions): Config {
|
|
148
|
+
const maxSize = options?.maxSize ?? 1_048_576 // 1 MB default
|
|
149
|
+
|
|
150
|
+
if (Buffer.byteLength(input, 'utf-8') > maxSize) {
|
|
151
|
+
throw new ParseError(
|
|
152
|
+
`Input exceeds maximum size of ${maxSize} bytes`,
|
|
153
|
+
0, 0
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
// ... parse
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
**Prototype pollution prevention:**
|
|
161
|
+
```typescript
|
|
162
|
+
// When merging user-provided objects, guard against prototype pollution
|
|
163
|
+
function mergeOptions<T extends object>(defaults: T, overrides: unknown): T {
|
|
164
|
+
if (typeof overrides !== 'object' || overrides === null) return defaults
|
|
165
|
+
// Guard against __proto__, constructor, prototype keys
|
|
166
|
+
const safe = Object.fromEntries(
|
|
167
|
+
Object.entries(overrides as Record<string, unknown>)
|
|
168
|
+
.filter(([key]) => key !== '__proto__' && key !== 'constructor' && key !== 'prototype')
|
|
169
|
+
)
|
|
170
|
+
return { ...defaults, ...safe }
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### SECURITY.md and Disclosure Policy
|
|
175
|
+
|
|
176
|
+
Every library must have a SECURITY.md file documenting how to report vulnerabilities:
|
|
177
|
+
|
|
178
|
+
```markdown
|
|
179
|
+
<!-- SECURITY.md -->
|
|
180
|
+
# Security Policy
|
|
181
|
+
|
|
182
|
+
## Supported Versions
|
|
183
|
+
|
|
184
|
+
| Version | Supported |
|
|
185
|
+
|---------|-----------|
|
|
186
|
+
| 2.x | Yes |
|
|
187
|
+
| 1.x | Security fixes only until 2025-01-01 |
|
|
188
|
+
| < 1.0 | No |
|
|
189
|
+
|
|
190
|
+
## Reporting a Vulnerability
|
|
191
|
+
|
|
192
|
+
**Do not open a public GitHub issue for security vulnerabilities.**
|
|
193
|
+
|
|
194
|
+
Please report vulnerabilities via GitHub's private vulnerability reporting:
|
|
195
|
+
https://github.com/org/my-library/security/advisories/new
|
|
196
|
+
|
|
197
|
+
Or email: security@example.com
|
|
198
|
+
|
|
199
|
+
Include:
|
|
200
|
+
- Description of the vulnerability
|
|
201
|
+
- Steps to reproduce
|
|
202
|
+
- Impact assessment
|
|
203
|
+
- Affected versions
|
|
204
|
+
|
|
205
|
+
**Response timeline:**
|
|
206
|
+
- Acknowledgment: within 48 hours
|
|
207
|
+
- Initial assessment: within 7 days
|
|
208
|
+
- Fix + disclosure: within 90 days (coordinated disclosure)
|
|
209
|
+
|
|
210
|
+
We follow [responsible disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure).
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Software Bill of Materials (SBOM)
|
|
214
|
+
|
|
215
|
+
For libraries used in regulated industries (healthcare, finance, government), consumers may require an SBOM — a machine-readable list of all dependencies:
|
|
216
|
+
|
|
217
|
+
```yaml
|
|
218
|
+
# .github/workflows/release.yml
|
|
219
|
+
- name: Generate SBOM
|
|
220
|
+
uses: anchore/sbom-action@v0
|
|
221
|
+
with:
|
|
222
|
+
format: spdx-json
|
|
223
|
+
artifact-name: sbom.spdx.json
|
|
224
|
+
|
|
225
|
+
- name: Attach SBOM to release
|
|
226
|
+
uses: softprops/action-gh-release@v2
|
|
227
|
+
with:
|
|
228
|
+
files: sbom.spdx.json
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
This generates a SPDX-format SBOM and attaches it to the GitHub Release. Consumers in regulated environments can use this to verify the library's dependency chain.
|
|
232
|
+
|
|
233
|
+
### Secret Detection
|
|
234
|
+
|
|
235
|
+
Never accidentally publish secrets in the library source:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# Add git-secrets or similar to pre-commit hooks
|
|
239
|
+
brew install git-secrets
|
|
240
|
+
git secrets --install
|
|
241
|
+
git secrets --register-aws
|
|
242
|
+
|
|
243
|
+
# Or use gitleaks:
|
|
244
|
+
brew install gitleaks
|
|
245
|
+
gitleaks protect --staged # Pre-commit check
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
In CI:
|
|
249
|
+
```yaml
|
|
250
|
+
- name: Scan for secrets
|
|
251
|
+
uses: trufflesecurity/trufflehog@main
|
|
252
|
+
with:
|
|
253
|
+
path: ./
|
|
254
|
+
base: ${{ github.event.repository.default_branch }}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
Never include `.env` files, API keys, private keys, or credentials in the published package. The `files` field in `package.json` is the allowlist — everything else is excluded. Verify with `npm pack --dry-run`.
|