oauthlint 0.2.1 → 0.2.3

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 (3) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +139 -17
  3. package/package.json +3 -3
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Maurice Anney
3
+ Copyright (c) 2026 Auspeo
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,46 +1,148 @@
1
+ <div align="center">
2
+
1
3
  # oauthlint
2
4
 
3
- > Catch the OAuth/OIDC/JWT anti-patterns AI coding tools systematically produce.
5
+ **Catch the OAuth / OIDC / JWT anti-patterns AI coding tools systematically produce.**
4
6
 
5
- CLI wrapper around [`oauthlint-rules`](../oauthlint-rules) a Semgrep
6
- rule pack curated by an IAM engineer.
7
+ A curated, multi-language Semgrep rule pack · JS/TS · Python · Go · Java · Rust (and growing) · CLI + GitHub Action + VS Code · free & MIT
7
8
 
8
- ## Quick start
9
+ [![npm](https://img.shields.io/npm/v/oauthlint.svg)](https://www.npmjs.com/package/oauthlint)
10
+ [![npm downloads](https://img.shields.io/npm/dm/oauthlint.svg)](https://www.npmjs.com/package/oauthlint)
11
+ [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
12
+ [![docs](https://img.shields.io/badge/docs-oauthlint.dev-2f6feb.svg)](https://oauthlint.dev)
13
+
14
+ </div>
9
15
 
10
16
  ```bash
11
17
  npx oauthlint scan ./src
12
18
  ```
13
19
 
14
- You need [Semgrep](https://semgrep.dev/docs/getting-started/) installed
15
- (`pipx install semgrep` or `brew install semgrep`). The CLI invokes it
16
- under the hood and normalises the output for humans and CI.
20
+ > Requires [Semgrep](https://semgrep.dev/docs/getting-started/) on the machine running the scan (`pipx install semgrep` or `brew install semgrep`). The CLI invokes it under the hood and normalises the output for humans and CI.
21
+
22
+ 📖 **Full documentation & rule catalogue [oauthlint.dev](https://oauthlint.dev)**
23
+
24
+ ---
25
+
26
+ ## The problem
27
+
28
+ LLM coding assistants — Cursor, Claude, GitHub Copilot, Gemini — ship the *same*
29
+ OAuth/JWT mistakes across every project they touch:
30
+
31
+ - a JWT verified with `alg: none` accepted
32
+ - `client_secret` hard-coded in source
33
+ - an OAuth flow with no `state` and no PKCE
34
+ - a token written to `localStorage`, readable by any XSS
35
+ - `redirect_uri` allow-listed with a `*` wildcard
36
+ - a `/login` POST with no rate limiting
37
+ - a password persisted in plaintext
38
+ - `Math.random()` used for a CSRF token
39
+
40
+ oauthlint is the layer between generic SAST and an enterprise IAM program:
41
+ **free, focused, developer-first.** Every finding names the rule, the exact
42
+ `file:line`, *why* it's dangerous, and *how* to fix it — with CWE/OWASP mappings.
43
+
44
+ ## Why oauthlint, and not just Semgrep?
45
+
46
+ Honest answer: nothing stops you from writing these rules yourself. Semgrep is
47
+ open source — it's the engine we run — and a capable engineer could reproduce a
48
+ lot of this. There's no technical moat and we won't pretend otherwise. What
49
+ oauthlint gives you is the work most people never do:
50
+
51
+ - **Low false positives, validated against real auth libraries.** The rules are
52
+ run against `jose`, NextAuth, PyJWT, Authlib, `golang/oauth2`, `oauth2-rs`,
53
+ Spring Security and more. Anything that fires on mature library source goes to
54
+ a triage queue, not to you — validated across thousands of files of real
55
+ auth-library source, with **zero false positives** on the clean libraries
56
+ ([validation report](https://oauthlint.dev/VALIDATION)).
57
+ - **One coherent product across every language it covers.** Same concepts, same ID scheme,
58
+ same docs — not a patchwork of community rules with mismatched styles.
59
+ - **Every finding teaches.** All 90 rules link to a fix page with CWE and OWASP
60
+ mappings. It's a lesson, not a grep hit.
61
+ - **The angle the registry doesn't have:** oauthlint specifically targets the
62
+ auth bugs AI coding tools ship on repeat, encoded in each rule's
63
+ `llm-prevalence` metadata and measured by a [reproducible benchmark](https://github.com/Auspeo/oauthlint/tree/main/benchmark).
64
+
65
+ Use oauthlint when you'd rather not write and maintain an auth rule pack
66
+ yourself. That's the whole pitch.
67
+
68
+ ## Quick start
69
+
70
+ ```bash
71
+ # one-shot scan, no install
72
+ npx oauthlint scan ./src
73
+
74
+ # fail CI on HIGH severity and above
75
+ npx oauthlint scan ./src --fail-on HIGH
76
+
77
+ # machine-readable output
78
+ npx oauthlint scan ./src --json
79
+
80
+ # GitHub Code Scanning
81
+ npx oauthlint scan ./src --format sarif > oauthlint.sarif
82
+
83
+ # auto-apply safe fixes (e.g. cookie flags)
84
+ npx oauthlint scan ./src --fix
85
+ ```
17
86
 
18
87
  ## Commands
19
88
 
20
89
  ```
21
90
  oauthlint scan [path] Scan a directory (default: current dir)
22
91
  oauthlint scan --json Emit machine-readable JSON
92
+ oauthlint scan --format sarif Emit SARIF for GitHub Code Scanning
23
93
  oauthlint scan --severity HIGH Only show findings ≥ HIGH
24
94
  oauthlint scan --fail-on off Never fail the build (CI dry-run)
95
+ oauthlint scan --fix Auto-apply safe fixes
25
96
  oauthlint list List every shipped rule
26
97
  oauthlint list --json Same, as JSON
27
98
  oauthlint init Generate .oauthlintrc.yml at cwd
28
99
  oauthlint init --force Overwrite an existing config
100
+ oauthlint doctor Check your setup (Semgrep, config, …)
29
101
  ```
30
102
 
31
- ## Exit codes
103
+ ## Use it in CI
32
104
 
33
- | Code | When |
34
- |------|------|
35
- | 0 | No findings ≥ `failOn` threshold |
36
- | 1 | At least one HIGH finding |
37
- | 2 | At least one CRITICAL finding |
38
- | 127 | Semgrep is not installed |
105
+ Run the CLI in a workflow and upload SARIF to **GitHub Code Scanning** so
106
+ findings appear inline on the PR:
107
+
108
+ ```yaml
109
+ # .github/workflows/oauthlint.yml
110
+ jobs:
111
+ oauthlint:
112
+ runs-on: ubuntu-latest
113
+ steps:
114
+ - uses: actions/checkout@v4
115
+ - run: pipx install semgrep # the engine oauthlint runs
116
+ - run: npx oauthlint scan ./src --format sarif > oauthlint.sarif
117
+ - uses: github/codeql-action/upload-sarif@v3
118
+ with:
119
+ sarif_file: oauthlint.sarif
120
+ ```
121
+
122
+ Or just fail the build on HIGH findings: `npx oauthlint scan ./src --fail-on HIGH`.
123
+
124
+ > A dedicated **GitHub Action** and a **VS Code extension** (inline diagnostics +
125
+ > Quick Fix suppressions) are on the way — follow the [repo](https://github.com/Auspeo/oauthlint) for releases.
126
+
127
+ ## What it catches
128
+
129
+ Rules across OAuth 2.0, OIDC, JWT, cookies, CORS, secrets and session hygiene —
130
+ each mapped to CWE & OWASP, each with a documentation page. Languages covered
131
+ today (more on the way):
132
+
133
+ | Language | Libraries |
134
+ |----------|-----------|
135
+ | JavaScript / TypeScript | jose, jsonwebtoken, NextAuth, express, … |
136
+ | Python | PyJWT, Authlib, requests, Flask, Django |
137
+ | Java | Spring Security, jjwt, nimbus-jose-jwt |
138
+ | Go | golang-jwt, crypto/tls, net/http |
139
+ | Rust | jsonwebtoken, reqwest, actix/tower |
140
+
141
+ 👉 **Browse the full, always-current catalogue at [oauthlint.dev/rules](https://oauthlint.dev/rules/).**
39
142
 
40
143
  ## Configuration
41
144
 
42
- Create a `.oauthlintrc.yml` at your repo root with `oauthlint init`. The
43
- file follows the schema in [`src/core/config.ts`](./src/core/config.ts).
145
+ Generate a `.oauthlintrc.yml` at your repo root with `oauthlint init`:
44
146
 
45
147
  ```yaml
46
148
  version: 1
@@ -54,6 +156,26 @@ rules:
54
156
  failOn: HIGH
55
157
  ```
56
158
 
159
+ ### Inline suppression
160
+
161
+ ```ts
162
+ // oauthlint-disable-next-line auth.jwt.alg-none -- legacy code, replaced in Q2
163
+ return jwt.verify(token, key, { algorithms: ['RS256', 'none'] });
164
+ ```
165
+
166
+ Wholesale silencing (`oauthlint-disable-file *`) is intentionally unsupported —
167
+ the next reviewer needs to see exactly which lines opted out, and why.
168
+
169
+ ## Exit codes
170
+
171
+ | Code | When |
172
+ |:----:|------|
173
+ | `0` | No finding at or above the `--fail-on` threshold |
174
+ | `1` | At least one **HIGH** finding |
175
+ | `2` | At least one **CRITICAL** finding, or a scan whose output could not be parsed (it never silently exits clean) |
176
+ | `127` | Semgrep is not installed |
177
+
57
178
  ## License
58
179
 
59
- MIT — see [LICENSE](../../LICENSE).
180
+ MIT — see [LICENSE](https://github.com/Auspeo/oauthlint/blob/main/LICENSE).
181
+ Built and maintained by [Auspeo](https://github.com/Auspeo).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oauthlint",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Catch the OAuth/OIDC/JWT anti-patterns AI coding tools systematically produce. CLI wrapper around the oauthlint-rules Semgrep rule pack.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -47,7 +47,7 @@
47
47
  "picocolors": "1.1.1",
48
48
  "yaml": "2.9.0",
49
49
  "zod": "3.24.1",
50
- "oauthlint-rules": "0.2.1"
50
+ "oauthlint-rules": "0.2.2"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@types/node": "22.10.5",
@@ -65,7 +65,7 @@
65
65
  "homepage": "https://oauthlint.dev",
66
66
  "bugs": "https://github.com/Auspeo/oauthlint/issues",
67
67
  "license": "MIT",
68
- "author": "Maurice Anney <webofboss@gmail.com>",
68
+ "author": "Auspeo (https://github.com/Auspeo)",
69
69
  "engines": {
70
70
  "node": ">=20.0.0"
71
71
  },