@xenos1996/usat 1.0.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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/USAT.md +596 -0
  4. package/dist/cli.d.ts +3 -0
  5. package/dist/cli.d.ts.map +1 -0
  6. package/dist/cli.js +438 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/config.d.ts +7 -0
  9. package/dist/config.d.ts.map +1 -0
  10. package/dist/config.js +72 -0
  11. package/dist/config.js.map +1 -0
  12. package/dist/detect/index.d.ts +58 -0
  13. package/dist/detect/index.d.ts.map +1 -0
  14. package/dist/detect/index.js +329 -0
  15. package/dist/detect/index.js.map +1 -0
  16. package/dist/engine/audit.d.ts +21 -0
  17. package/dist/engine/audit.d.ts.map +1 -0
  18. package/dist/engine/audit.js +295 -0
  19. package/dist/engine/audit.js.map +1 -0
  20. package/dist/engine/diff.d.ts +24 -0
  21. package/dist/engine/diff.d.ts.map +1 -0
  22. package/dist/engine/diff.js +136 -0
  23. package/dist/engine/diff.js.map +1 -0
  24. package/dist/engine/evaluate.d.ts +19 -0
  25. package/dist/engine/evaluate.d.ts.map +1 -0
  26. package/dist/engine/evaluate.js +377 -0
  27. package/dist/engine/evaluate.js.map +1 -0
  28. package/dist/engine/gate.d.ts +19 -0
  29. package/dist/engine/gate.d.ts.map +1 -0
  30. package/dist/engine/gate.js +47 -0
  31. package/dist/engine/gate.js.map +1 -0
  32. package/dist/engine/loader.d.ts +22 -0
  33. package/dist/engine/loader.d.ts.map +1 -0
  34. package/dist/engine/loader.js +360 -0
  35. package/dist/engine/loader.js.map +1 -0
  36. package/dist/engine/maturity.d.ts +20 -0
  37. package/dist/engine/maturity.d.ts.map +1 -0
  38. package/dist/engine/maturity.js +157 -0
  39. package/dist/engine/maturity.js.map +1 -0
  40. package/dist/engine/score.d.ts +19 -0
  41. package/dist/engine/score.d.ts.map +1 -0
  42. package/dist/engine/score.js +141 -0
  43. package/dist/engine/score.js.map +1 -0
  44. package/dist/engine/sections.d.ts +14 -0
  45. package/dist/engine/sections.d.ts.map +1 -0
  46. package/dist/engine/sections.js +50 -0
  47. package/dist/engine/sections.js.map +1 -0
  48. package/dist/index.d.ts +23 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +17 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/report/markdown.d.ts +16 -0
  53. package/dist/report/markdown.d.ts.map +1 -0
  54. package/dist/report/markdown.js +488 -0
  55. package/dist/report/markdown.js.map +1 -0
  56. package/dist/types.d.ts +282 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +16 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/util/glob.d.ts +11 -0
  61. package/dist/util/glob.d.ts.map +1 -0
  62. package/dist/util/glob.js +86 -0
  63. package/dist/util/glob.js.map +1 -0
  64. package/dist/util/project.d.ts +72 -0
  65. package/dist/util/project.d.ts.map +1 -0
  66. package/dist/util/project.js +586 -0
  67. package/dist/util/project.js.map +1 -0
  68. package/dist/util/yaml.d.ts +28 -0
  69. package/dist/util/yaml.d.ts.map +1 -0
  70. package/dist/util/yaml.js +48 -0
  71. package/dist/util/yaml.js.map +1 -0
  72. package/docs/ARCHITECTURE.md +119 -0
  73. package/docs/README.md +27 -0
  74. package/docs/adr/0001-record-architecture-decisions.md +35 -0
  75. package/docs/adr/0002-typescript-engine-over-python.md +49 -0
  76. package/docs/adr/0003-rules-are-data-not-code.md +50 -0
  77. package/docs/adr/0004-markdown-only-output.md +41 -0
  78. package/docs/adr/0005-maturity-dampens-severity.md +56 -0
  79. package/docs/adr/0006-severity-status-two-axes.md +48 -0
  80. package/docs/adr/0007-suppressions-are-visible-and-expiring.md +46 -0
  81. package/docs/adr/0008-report-trailer-and-diff.md +48 -0
  82. package/docs/adr/0009-fail-closed-on-malformed-input.md +56 -0
  83. package/docs/adr/0010-detector-design.md +54 -0
  84. package/docs/adr/0011-coexist-with-deep-scanners.md +52 -0
  85. package/docs/adr/README.md +32 -0
  86. package/docs/agent-integration.md +129 -0
  87. package/docs/ci-integration.md +163 -0
  88. package/docs/concepts.md +196 -0
  89. package/docs/configuration.md +105 -0
  90. package/docs/detectors.md +186 -0
  91. package/docs/getting-started.md +99 -0
  92. package/docs/maturity-profiles.md +156 -0
  93. package/docs/reference/api.md +193 -0
  94. package/docs/reference/cli.md +412 -0
  95. package/docs/rule-packs.md +278 -0
  96. package/docs/standards-mapping.md +171 -0
  97. package/package.json +96 -0
  98. package/rules/core/architecture.yaml +190 -0
  99. package/rules/core/cicd.yaml +212 -0
  100. package/rules/core/code-quality.yaml +261 -0
  101. package/rules/core/dependencies.yaml +132 -0
  102. package/rules/core/documentation.yaml +119 -0
  103. package/rules/core/future-readiness.yaml +91 -0
  104. package/rules/core/release.yaml +131 -0
  105. package/rules/core/repo.yaml +303 -0
  106. package/rules/core/security.yaml +494 -0
  107. package/rules/core/supply-chain.yaml +357 -0
  108. package/rules/core/testing.yaml +260 -0
  109. package/rules/detectors.yaml +2255 -0
  110. package/rules/index.yaml +41 -0
  111. package/rules/profiles/maturity.yaml +135 -0
  112. package/rules/stacks/ai-era.yaml +193 -0
  113. package/rules/stacks/api-backend.yaml +121 -0
  114. package/rules/stacks/cli.yaml +105 -0
  115. package/rules/stacks/compliance.yaml +157 -0
  116. package/rules/stacks/containers.yaml +124 -0
  117. package/rules/stacks/data.yaml +165 -0
  118. package/rules/stacks/go.yaml +134 -0
  119. package/rules/stacks/iac.yaml +128 -0
  120. package/rules/stacks/jvm.yaml +150 -0
  121. package/rules/stacks/ml-ai.yaml +140 -0
  122. package/rules/stacks/mobile.yaml +121 -0
  123. package/rules/stacks/node-typescript.yaml +166 -0
  124. package/rules/stacks/python.yaml +175 -0
  125. package/rules/stacks/rust.yaml +129 -0
  126. package/rules/stacks/solidity.yaml +139 -0
  127. package/rules/stacks/web-frontend.yaml +159 -0
  128. package/templates/AGENTS.audit.md +135 -0
  129. package/templates/AUDIT_REPORT.md +155 -0
@@ -0,0 +1,278 @@
1
+ # Writing rule packs
2
+
3
+ A rule pack is one YAML file. Register it in `rules/index.yaml`, and USAT decides at
4
+ audit time whether it applies.
5
+
6
+ ```yaml
7
+ id: stacks/mobile
8
+ title: Mobile (iOS / Android / Cross-platform)
9
+ section: S15
10
+ section_title: Platform-Specific
11
+ description: 'Activated when iOS, Android, React Native, Expo, or Flutter is detected.'
12
+ version: '1.0'
13
+ skip_when: # skip the WHOLE pack when true
14
+ all:
15
+ - { fact: 'platform:mobile', op: 'absent' }
16
+ - { fact: 'platform:ios', op: 'absent' }
17
+ - { fact: 'platform:android', op: 'absent' }
18
+ provides: ['platform:mobile'] # facts this pack asserts
19
+ rules:
20
+ - id: MOB-001
21
+ title: Crash reporting is integrated
22
+ section: S15
23
+ section_title: Platform-Specific
24
+ severity: HIGH
25
+ class: operations
26
+ applies_when: { fact: 'maturity:beta' } # optional per-rule gating
27
+ depths: [standard, deep] # optional
28
+ check:
29
+ kind: grep_present
30
+ pattern: '(Crashlytics|Sentry|BugSnag|Instabug)'
31
+ include: ['**/*.{ts,tsx,js,json,plist,xml,gradle,swift,kt}']
32
+ exclude: ['**/node_modules/**', '**/Pods/**']
33
+ flags: i
34
+ why: "On mobile you cannot watch the user's screen."
35
+ evidence: 'Where tokens/PII live: Keychain/Keystore, not AsyncStorage.'
36
+ remediation: 'Add Crashlytics or Sentry with dSYM upload.'
37
+ references: ['OWASP-MASVS-STORAGE-2']
38
+ ```
39
+
40
+ ## Pack fields
41
+
42
+ | Field | Required | Notes |
43
+ | --------------- | -------- | ----------------------------------------------------- |
44
+ | `id` | ✅ | Convention: `core/<name>` or `stacks/<name>` |
45
+ | `title` | ✅ | |
46
+ | `section` | | Default section for rules that omit one |
47
+ | `section_title` | | |
48
+ | `description` | | Shown by `usat rules` |
49
+ | `skip_when` | | Predicate; pack is skipped when **true** |
50
+ | `provides` | | Facts to add when the pack applies — lets packs chain |
51
+ | `rules` | ✅ | |
52
+
53
+ ## Rule fields
54
+
55
+ | Field | Required | Notes |
56
+ | -------------- | -------- | -------------------------------------------------------- |
57
+ | `id` | ✅ | Convention: `<PREFIX>-<NNN>`, e.g. `SEC-007` |
58
+ | `title` | ✅ | Imperative and specific: "Tokens and sessions expire" |
59
+ | `section` | ✅ | `S1`…`S16` |
60
+ | `severity` | ✅ | `CRITICAL` \| `HIGH` \| `MEDIUM` \| `LOW` \| `FUTURE` |
61
+ | `class` | ✅ | See below |
62
+ | `check` | ✅ | See below |
63
+ | `weight` | | Overrides the severity default |
64
+ | `applies_when` | | Predicate over detected facts |
65
+ | `depths` | | `[quick]` / `[standard]` / `[deep]`; omit for all |
66
+ | `why` | | Shown in the report and the judgement queue |
67
+ | `evidence` | | **Required for `manual` checks** — what proof looks like |
68
+ | `remediation` | | The fix |
69
+ | `references` | | Standard IDs: `CWE-89`, `ASVS-5.3.4`, `OWASP-LLM01:2026` |
70
+ | `tags` | | Free-form |
71
+
72
+ ### `class` drives dampening
73
+
74
+ `security` · `supply-chain` · `correctness` · `maintainability` · `operations` ·
75
+ `performance` · `compliance` · `documentation` · `style`
76
+
77
+ ---
78
+
79
+ ## Check kinds
80
+
81
+ ### `manual` — needs a human or an agent
82
+
83
+ ```yaml
84
+ check: { kind: manual }
85
+ ```
86
+
87
+ Produces ❓ NEEDS REVIEW and lands in the judgement queue. Always pair with
88
+ `evidence:` — it is the prompt the reviewer works from.
89
+
90
+ ### `file_exists` / `file_absent`
91
+
92
+ ```yaml
93
+ check: { kind: file_exists, files: ['.gitignore'] }
94
+ check: { kind: file_absent, files: ['.env', '*.pem'] }
95
+ ```
96
+
97
+ `file_absent` fails with locations when something is found.
98
+
99
+ ### `any_file`
100
+
101
+ ```yaml
102
+ check:
103
+ kind: any_file
104
+ patterns: ['README.md', 'readme.md', 'README.rst']
105
+ ```
106
+
107
+ ### `grep_present` / `grep_absent`
108
+
109
+ ```yaml
110
+ check:
111
+ kind: grep_present # PASS when found
112
+ pattern: '(zod|joi|pydantic|class-validator)'
113
+ include: ['**/*.{ts,tsx,js,jsx,py,go}']
114
+ exclude: ['**/*.test.*', '**/node_modules/**']
115
+ flags: i # i = case-insensitive
116
+ ```
117
+
118
+ `grep_absent` inverts it: any hit is a FAIL **with file:line locations** — this is
119
+ the workhorse for "no hardcoded secrets", "no `shell=True`", "no `http://`".
120
+
121
+ ### `grep_wrong` / `grep_deprecated`
122
+
123
+ ```yaml
124
+ check:
125
+ kind: grep_wrong # hits → ⚠️ WRONG
126
+ pattern: 'catch\s*\(\s*\w*\s*\)\s*\{\s*\}'
127
+
128
+ check:
129
+ kind: grep_deprecated # hits → 💀 DEPRECATED
130
+ pattern: 'new Buffer\s*\('
131
+ ```
132
+
133
+ Use `grep_wrong` for "present but done incorrectly" — the status auditors most often
134
+ miss (Rule 9).
135
+
136
+ ### `tracked_present` / `tracked_absent`
137
+
138
+ Asks **git** what is tracked, not what is on disk. Use for committed build output,
139
+ committed `.env`, committed model weights — anything whose presence in the working
140
+ tree is normal but whose presence in git is a bug.
141
+
142
+ ```yaml
143
+ check:
144
+ kind: tracked_absent
145
+ patterns: ['dist/**', 'node_modules/**', '.env', '**/*.pt']
146
+ ```
147
+
148
+ ### `count_min`
149
+
150
+ ```yaml
151
+ check:
152
+ kind: count_min
153
+ patterns: ['**/*.test.{ts,tsx}', '**/test_*.py']
154
+ min: 5
155
+ ```
156
+
157
+ ### `file_lines_max`
158
+
159
+ ```yaml
160
+ check:
161
+ kind: file_lines_max
162
+ patterns: ['src/**/*.ts']
163
+ max_lines: 800
164
+ ```
165
+
166
+ Any hit is ⚠️ WRONG with the line count. A cheap proxy for god objects.
167
+
168
+ ### `json_path`
169
+
170
+ ```yaml
171
+ check:
172
+ kind: json_path
173
+ file: 'package.json'
174
+ path: 'engines.node'
175
+ equals: '>=20'
176
+ ```
177
+
178
+ `equals` omitted ⇒ PASS when the key is merely set. Works on JSON (JSONC tolerated).
179
+
180
+ ### `command`
181
+
182
+ ```yaml
183
+ check:
184
+ kind: command
185
+ run: '! npm audit --production --audit-level=high | grep -qiE "critical|high"'
186
+ expect_exit: 0
187
+ ```
188
+
189
+ **Skipped unless `--allow-commands`** — reported as ❓ NEEDS REVIEW otherwise.
190
+ USAT never shells out without being asked.
191
+
192
+ ### `info`
193
+
194
+ Context only, never scored. Useful for explaining a section to a reader.
195
+
196
+ ---
197
+
198
+ ## Predicates
199
+
200
+ ```yaml
201
+ applies_when: { fact: 'has:database' }
202
+
203
+ applies_when:
204
+ any:
205
+ - { fact: 'lang:typescript' }
206
+ - { fact: 'lang:javascript' }
207
+
208
+ applies_when:
209
+ all:
210
+ - { fact: 'maturity:production' }
211
+ - { not: { fact: 'project:library' } }
212
+
213
+ # Numeric facts use metric:
214
+ applies_when: { fact: 'metric:contributors', op: 'gt', value: 2 }
215
+ applies_when: { fact: 'metric:tags', op: 'exists' }
216
+ ```
217
+
218
+ Operators: `exists` (default) · `absent` · `eq` · `neq` · `in` · `includes` · `gt` · `lt` · `matches`
219
+
220
+ Combinators: `all` · `any` · `not`
221
+
222
+ ### Fail-closed contracts (the engine does not guess)
223
+
224
+ Malformed input warns at load time and evaluates conservatively — see
225
+ ADR-0009. What to know as an author:
226
+
227
+ - `in` / `includes` compare **metric** values against the list. On flag
228
+ facts they are always false: presence alone never satisfies a value
229
+ comparison.
230
+ - `matches` compiles `value` as a regex; an invalid regex warns and the
231
+ predicate is false. Unknown operators and unknown predicate keys behave
232
+ the same way (rule skipped, warning on stderr).
233
+ - An empty grep `pattern` drops the rule with a warning — `new RegExp('')`
234
+ matches every line, so a missing pattern would otherwise FAIL (or PASS)
235
+ the whole repo.
236
+ - Duplicate rule IDs across packs: first definition wins, later ones warn.
237
+ - Override `severity` must be on the ladder and `weight` a finite number
238
+ ≥ 0, or the override is ignored with a warning. Run `node
239
+ scripts/check-docs.mjs`-adjacent `usat rules` after editing: the shipped
240
+ packs must load with **zero warnings** (enforced by `tests/e2e.test.ts`).
241
+
242
+ ---
243
+
244
+ ## Available facts
245
+
246
+ Run `usat detect .` on any project to see them. Namespaces:
247
+
248
+ `lang:*` `pm:*` `fw:*` `project:*` `platform:*` `db:*` `orm:*` `auth:*` `test:*`
249
+ `ci:*` `infra:*` `api:*` `obs:*` `ai:*` `has:*` `doc:*` `practice:*` `maturity:*`
250
+
251
+ Metrics (use `metric:<name>`): `commits`, `contributors`, `tags`, `branches`,
252
+ `files`, `daysSinceLastCommit`.
253
+
254
+ Full catalogue: [detectors.md](detectors.md).
255
+
256
+ ---
257
+
258
+ ## Style guide for rule authors
259
+
260
+ 1. **Title = the desired state**, not the defect. "Tokens and sessions expire", not "Missing token expiry".
261
+ 2. **`why` earns the rule its place.** If you cannot say why in one sentence, cut the rule.
262
+ 3. **`remediation` must be actionable.** "Improve security" is not a fix. "Set `SameSite=Lax` and require a CSRF token" is.
263
+ 4. **`evidence` is the deliverable for manual checks.** It tells the reviewer exactly what to produce.
264
+ 5. **Exclude tests and docs from security greps.** A rule that fires on its own documentation is a rule people will disable.
265
+ 6. **Prefer `grep_wrong` over `grep_absent`** when the _pattern_ is fine but a specific usage is not.
266
+ 7. **Cite the standard.** `CWE-89`, `ASVS-5.3.4`, `SLSA-Build-L2`, `OWASP-LLM01:2026`.
267
+ 8. **Severity = worst realistic outcome**, not typical. Dampening handles context; the rule should not.
268
+
269
+ ## Testing your pack
270
+
271
+ ```bash
272
+ usat rules --section S15 # did it load?
273
+ usat explain MOB-001 # did it parse as intended?
274
+ usat audit . --include stacks/mobile --depth deep
275
+ ```
276
+
277
+ A pack with a YAML syntax error is skipped with a warning on stderr — the audit never
278
+ crashes because of a bad rule file.
@@ -0,0 +1,171 @@
1
+ # Standards mapping — how USAT compares to the state of the art
2
+
3
+ > _USAT did not invent most of these checks. It reorganised them so one tool can
4
+ > apply them to any project, at any stage, without a certification budget._
5
+
6
+ ## The short version
7
+
8
+ | Framework | What it is | What USAT takes | What USAT adds |
9
+ | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
10
+ | **OWASP ASVS 5.0** | ~350 verification requirements across 17 chapters, levels L1–L3 [1](https://quality.arc42.org/standards/owasp-asvs) | The requirement set behind most `SEC-*` rules; ASVS IDs in `references` | Executable versions of the mechanically-checkable subset; level selection replaced by maturity profiles |
11
+ | **OpenSSF Scorecard** | 18 automated checks, 0–10, run against public repos [1](https://rywalker.com/research/openssf-scorecard) | The shape of S3 and S8; score-per-check | Runs on private repos and monorepos; mixes in code-level checks; adds the other 15 sections |
12
+ | **NIST SSDF (SP 800-218)** | Secure-development practice outcomes | Practice-level outcomes: protect, produce well-secured software, respond to vulnerabilities | Concrete evidence requirements per outcome |
13
+ | **SLSA v1.2** | Build L0–L3 plus an approved Source track (Nov 2025) [1](https://rywalker.com/research/slsa) | Provenance, attestation, and source-integrity requirements | Progressive rules (SBOM now, attestation at production) rather than a level you claim |
14
+ | **OWASP LLM Top 10 (2026)** | LLM01–LLM10 for LLM applications [1](https://www.cybersaint.io/cybersecurity-frameworks-and-standards/glossary/what-is-the-owasp-top-10-for-llm-and-agentic-ai) | The entire S14 section | Executable detection of AI stacks so the section self-activates |
15
+ | **OWASP Agentic AI Top 10 (ASI, 2026)** | ASI01–ASI10 for agent systems [2](https://www.trydeepteam.com/docs/frameworks-owasp-top-10-for-agentic-applications) | Excessive agency, tool misuse, memory poisoning, inter-agent trust | Rules for `AGENTS.md`/`CLAUDE.md` as executable-ish instructions |
16
+ | **CII Best Practices** | Open-source project maturity badge | README/LICENSE/SECURITY/CONTRIBUTING baseline | Automated, no self-assessment questionnaire |
17
+ | **ISO/IEC 5055** | Automated code-quality measurement (security, reliability, performance, maintainability) | The four quality characteristics behind S4/S5 | Free, YAML, and diffable |
18
+ | **WCAG 2.2 AA** | Accessibility success criteria | S13 checks | Same criteria, expressed as things a reviewer can verify in ten minutes |
19
+ | **EU CRA** | Cyber-resilience obligations for products with digital elements | SBOM, vulnerability handling, provenance expectations | A roadmap toward the obligations, not an audit |
20
+ | **OWASP SAMM** | Organisational assurance programme | Maturity-by-dimension thinking | Applies to a repository, not an org |
21
+
22
+ ---
23
+
24
+ ## Where USAT differs from the field
25
+
26
+ ### 1 · It is stage-aware; they are not
27
+
28
+ ASVS asks you to pick L1/L2/L3 _before_ you start [2](https://www.securecodinghub.com/blog/owasp-asvs-developers-complete-guide).
29
+ Scorecard gives an absolute 0–10. Neither asks "how old is this project, and does
30
+ that matter?"
31
+
32
+ USAT detects the stage and dampens severity accordingly — while holding a hard floor
33
+ on CRITICAL. [maturity-profiles.md](maturity-profiles.md)
34
+
35
+ ### 2 · It is agent-executable, not just human-readable
36
+
37
+ Every framework above is a document a human interprets. USAT ships:
38
+
39
+ - `rules/` — machine-readable versions of the same checks
40
+ - a deterministic engine that settles ~70% of them
41
+ - a **judgement queue** that tells an agent or reviewer exactly what evidence to produce
42
+
43
+ That split is the whole design. An LLM should not be asked to grep for `eval(`; it
44
+ should be asked whether authorisation is enforced per resource.
45
+
46
+ ### 3 · It separates "absent" from "wrong"
47
+
48
+ Every framework above has a checkbox. None distinguishes 🚫 MISSING from ⚠️ WRONG —
49
+ yet wrong is worse, because it looks finished. USAT gives WRONG its own status, its
50
+ own check kind (`grep_wrong`), and a score of 0.15 rather than 0.00.
51
+
52
+ ### 4 · It reports confidence alongside score
53
+
54
+ A 90/100 where only 40% of applicable rules could be verified is not a 90/100. USAT
55
+ prints confidence next to every dimension and marks unverifiable sections
56
+ _"— not verified"_ instead of silently awarding 10/10.
57
+
58
+ ### 5 · It is diffable
59
+
60
+ Every report embeds a machine-readable trailer so `usat diff` turns the next audit
61
+ into a progress report: fixed, regressed, newly applicable, net movement. None of the
62
+ frameworks above give you a first-class way to show you improved.
63
+
64
+ ### 6 · It covers the AI era as a first-class section
65
+
66
+ S14 is mapped to the OWASP LLM Top 10 (2026) and the OWASP Agentic AI Top 10 (ASI, 2026) — including risks that did not exist when the other frameworks were written:
67
+ excessive agency, unbounded consumption, RAG tenant leakage, memory/context poisoning,
68
+ and the fact that `AGENTS.md` is executable-ish instruction that commits like code.
69
+
70
+ ---
71
+
72
+ ## Detailed mapping
73
+
74
+ ### USAT section → standards
75
+
76
+ | USAT | ASVS 5.0 | SSDF | SLSA | Scorecard | Other |
77
+ | --------------------- | --------------------- | --------------- | ------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
78
+ | S1 Repository | — | PO.3, PS.1 | Source L1–L2 | Binary-Artifacts, License, Security-Policy | CII |
79
+ | S2 Security | V2–V14 (all chapters) | PW.1–PW.8, RV.1 | — | — | CWE, OWASP Top 10 |
80
+ | S3 Supply Chain | V14.1, V14.2 | PS.3, PO.3 | Build L1–L3, Source | Pinned-Dependencies, Vulnerabilities, Dangerous-Workflow, Token-Permissions, Signed-Releases, Branch-Protection | CRA Annex I |
81
+ | S4 Architecture | V1, V4 | PW.1 | — | — | ISO 5055 Maintainability |
82
+ | S5 Code Quality | V5, V7 | PW.7, PW.8 | — | — | ISO 5055 Reliability |
83
+ | S6 Data | V8, V5.3 | PW.4 | — | — | GDPR Art. 32 |
84
+ | S7 Testing | V1.1, V4.2 | RV.1.1, PW.8 | — | CI-Tests, Fuzzing | — |
85
+ | S8 CI/CD & Infra | V14.1 | PO.5, RV.3 | Build L2 | CI-Tests, Branch-Protection | DORA |
86
+ | S9 Release | V1.14 | PO.5, RV.2 | Build L2, Source L2 | Signed-Releases | SemVer |
87
+ | S10 Dependencies | V14.2 | PW.4, RV.1.1 | — | Vulnerabilities, Dependency-Update-Tool, Maintained | SPDX, Criticality Score |
88
+ | S11 Performance | V13 | — | — | — | ISO 5055 Performance |
89
+ | S12 Documentation | — | PS.1, PW.1 | — | — | CII |
90
+ | S13 A11y & Compliance | V14.4 (partly) | — | — | — | WCAG 2.2 AA, GDPR, CCPA, PCI-DSS 4.0 |
91
+ | S14 AI / LLM | — | — | — | — | OWASP LLM Top 10 (2026), OWASP ASI Top 10 (2026), NIST AI RMF, EU AI Act |
92
+ | S15 Platform | V-per-stack | — | — | — | MASVS, CIS Docker/K8s, SCWE |
93
+ | S16 Future | — | — | — | — | endoflife.date, FinOps |
94
+
95
+ ### Representative rule → control
96
+
97
+ | Rule | Control |
98
+ | ------------------------------------------- | ------------------------------------------------------- |
99
+ | `SEC-001` No hardcoded credentials | ASVS 2.10.4 · CWE-798 · OWASP A02:2021 |
100
+ | `SEC-005` SQL not built by concatenation | ASVS 5.3.4 · CWE-89 · OWASP A03:2021 |
101
+ | `SEC-011` Modern adaptive password hash | ASVS 2.4.1 · CWE-916 |
102
+ | `SEC-025` Adaptive hash present where auth | ASVS 2.4.1 · CWE-916 |
103
+ | `SEC-015` Authorization per request | ASVS 4.2.1 · CWE-639 · OWASP A01:2021 |
104
+ | `SEC-013` No `alg:none` | ASVS 3.2.3 · CWE-347 |
105
+ | `SUP-001` Lockfile committed | OpenSSF Pinned-Dependencies · SSDF PS.3.2 · SLSA Source |
106
+ | `SUP-005` Dependency scanning in CI | OpenSSF Vulnerabilities · SSDF RV.1.1 |
107
+ | `SUP-008` No workflow script injection | OpenSSF Dangerous-Workflow · CWE-94 |
108
+ | `SUP-009` Least-privilege token permissions | OpenSSF Token-Permissions · SLSA Build L2 |
109
+ | `SUP-012` Default branch protected | OpenSSF Branch-Protection · SLSA Source L2 · SSDF PO.2 |
110
+ | `SUP-014` SBOM published | SLSA · SSDF PS.3.2 · EU CRA Annex I |
111
+ | `SUP-015` Provenance attestation | SLSA Build L2 (v1.2) |
112
+ | `TEST-002` Tests run in CI on PRs | OpenSSF CI-Tests · SSDF RV.1.1 |
113
+ | `CICD-004` Rollback rehearsed | DORA time-to-restore · SSDF RV.3 |
114
+ | `CICD-010` Backups **and** tested restores | SSDF RV.3 · CIS Control 11 |
115
+ | `CTNR-001` Container not running as root | CIS Docker 4.1 · CWE-250 |
116
+ | `IAC-001` No public buckets / `0.0.0.0/0` | CIS AWS 2.1.5 · CWE-284 |
117
+ | `SOLID-001` Reentrancy protection | SWC-107 · Consensys best practices |
118
+ | `AI-001` Prompt injection | OWASP LLM01:2026 · ASI01:2026 |
119
+ | `AI-003` Least-privilege agents | OWASP LLM03:2026 · ASI02/ASI03:2026 |
120
+ | `AI-005` Bounded consumption | OWASP LLM06:2026 · ASI08:2026 |
121
+ | `AI-007` RAG tenant isolation | OWASP LLM09:2026 · ASI06:2026 |
122
+ | `COMP-001` Keyboard accessibility | WCAG 2.1.1 · EN 301 549 |
123
+ | `COMP-007` Data subject rights | GDPR Art. 15/17 · CCPA |
124
+
125
+ ---
126
+
127
+ ## Deliberate gaps
128
+
129
+ Things USAT intentionally does **not** do. An audit tool that oversells is worse than
130
+ none.
131
+
132
+ | Not done | Why | Do this instead |
133
+ | ---------------------------- | -------------------------------------------------- | -------------------------------------------------------------- |
134
+ | **Penetration testing** | No dynamic analysis, no fuzzing, no exploit chains | OWASP ASVS L2/L3 assessment, a pentest |
135
+ | **Deep SAST** | Requires whole-program analysis | CodeQL, Semgrep, Snyk Code — USAT checks they are _configured_ |
136
+ | **CVE lookup** | Needs network + advisory databases | `npm audit`, `osv-scanner`, `trivy`, Dependabot |
137
+ | **Compliance certification** | Only an accredited auditor certifies | Use USAT as the evidence checklist, then certify |
138
+ | **Runtime/DAST** | Nothing is executed | OWASP ZAP, Burp, your staging environment |
139
+ | **Formal verification** | Out of scope for a checklist | Certora, Halmos, Kani |
140
+ | **Org-level maturity** | USAT audits repositories | OWASP SAMM for programmes |
141
+
142
+ ### On Scorecard specifically
143
+
144
+ Scorecard is excellent and USAT's S3/S8 borrow its shape. Two honest caveats, both
145
+ documented by its own users: it measures **process hygiene, not code quality**, and
146
+ peer-reviewed research found **no clean correlation** between high scores and fewer
147
+ vulnerabilities [1](https://rywalker.com/research/openssf-scorecard). Scorecard also
148
+ needs a public repo and network access. USAT is the offline, code-level,
149
+ private-repo complement — run both.
150
+
151
+ ### On SARIF
152
+
153
+ SARIF 2.1.0 is the right interchange format for static-analysis _results_, and most
154
+ SAST tools emit it. USAT reports are prose-oriented — a scored, prioritised document
155
+ for humans and agents, not a machine-ingestible findings stream. If you need to feed
156
+ results into a dashboard, that is a small renderer away
157
+ (`src/report/`); the internal model already carries file, line, severity, and rule
158
+ identity for every finding. Contributions welcome.
159
+
160
+ ---
161
+
162
+ ## Sources
163
+
164
+ - [1](https://quality.arc42.org/standards/owasp-asvs) OWASP ASVS — version history, 17 chapters, cumulative L1–L3
165
+ - [2](https://www.securecodinghub.com/blog/owasp-asvs-developers-complete-guide) OWASP ASVS 5.0 — choosing a verification level
166
+ - [1](https://rywalker.com/research/openssf-scorecard) OpenSSF Scorecard — 18 checks, v5.5.0 (April 2026), and the caveats on what scores mean
167
+ - [1](https://rywalker.com/research/slsa) SLSA — spec v1.2 (Nov 2025), Build L0–L3, Source track approved
168
+ - [1](https://www.cybersaint.io/cybersecurity-frameworks-and-standards/glossary/what-is-the-owasp-top-10-for-llm-and-agentic-ai) OWASP Top 10 for LLM Applications, 2026 (LLM01–LLM10)
169
+ - [3](https://blog.ogwilliam.com/post/owasp-top-10-llm-applications-2026-whats-new) OWASP LLM Top 10 — 2025 vs 2026 changes
170
+ - [2](https://www.trydeepteam.com/docs/frameworks-owasp-top-10-for-agentic-applications) OWASP Top 10 for Agents, 2026 (ASI01–ASI10)
171
+ - [1](https://github.com/addyosmani/agent-skills/blob/main/CLAUDE.md) Agent Skills convention — `SKILL.md` + `references/`
package/package.json ADDED
@@ -0,0 +1,96 @@
1
+ {
2
+ "name": "@xenos1996/usat",
3
+ "version": "1.0.0",
4
+ "description": "Universal Software Audit Template — an open-source, self-adapting audit framework for any project, any stack, any stage",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "usat": "dist/cli.js"
9
+ },
10
+ "main": "./dist/index.js",
11
+ "types": "./dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./rules": "./rules/index.yaml"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "rules",
22
+ "templates",
23
+ "schema",
24
+ "docs",
25
+ "USAT.md",
26
+ "AGENTS.md",
27
+ "README.md",
28
+ "LICENSE"
29
+ ],
30
+ "keywords": [
31
+ "audit",
32
+ "software-audit",
33
+ "security-audit",
34
+ "code-audit",
35
+ "code-review",
36
+ "openssf",
37
+ "owasp-asvs",
38
+ "slsa",
39
+ "sast",
40
+ "agent",
41
+ "llm",
42
+ "template",
43
+ "tech-debt",
44
+ "quality-gate"
45
+ ],
46
+ "author": "",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/Er-Sajan-PLG/software-auditing-template.git"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/Er-Sajan-PLG/software-auditing-template/issues"
53
+ },
54
+ "homepage": "https://github.com/Er-Sajan-PLG/software-auditing-template#readme",
55
+ "engines": {
56
+ "node": ">=20.0.0"
57
+ },
58
+ "scripts": {
59
+ "build": "tsc -p tsconfig.json",
60
+ "usat": "node --experimental-strip-types src/cli.ts",
61
+ "lint": "eslint .",
62
+ "lint:fix": "eslint . --fix",
63
+ "format": "prettier --write .",
64
+ "format:check": "prettier --check .",
65
+ "typecheck": "tsc -p tsconfig.json --noEmit",
66
+ "test": "vitest run",
67
+ "test:watch": "vitest",
68
+ "test:cov": "vitest run --coverage",
69
+ "self-audit": "npm run build && node dist/cli.js audit . --out AUDIT.md",
70
+ "prepublishOnly": "npm run build"
71
+ },
72
+ "lint-staged": {
73
+ "*.{js,ts,mjs,cjs}": [
74
+ "eslint --fix",
75
+ "prettier --write"
76
+ ],
77
+ "*.{json,md,yaml,yml}": [
78
+ "prettier --write"
79
+ ]
80
+ },
81
+ "dependencies": {
82
+ "yaml": "^2.6.1"
83
+ },
84
+ "devDependencies": {
85
+ "@eslint/js": "^10.0.1",
86
+ "@types/node": "^26.4.1",
87
+ "@vitest/coverage-v8": "^5.0.0",
88
+ "eslint": "^10.10.0",
89
+ "husky": "^9.1.7",
90
+ "lint-staged": "^17.5.0",
91
+ "prettier": "^3.4.2",
92
+ "typescript": "^5.7.3",
93
+ "typescript-eslint": "^8.20.0",
94
+ "vitest": "^5.0.0"
95
+ }
96
+ }