sfscanner 0.1.0 → 0.2.1

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 (53) hide show
  1. package/README.md +141 -214
  2. package/THIRD_PARTY_NOTICES.md +385 -48
  3. package/dist/_types/contracts/preflight-prerequisite-types.d.ts +73 -0
  4. package/dist/_types/packages/scanner-cli/src/index.d.ts +6 -0
  5. package/dist/_types/packages/scanner-cli/src/v2/arguments.d.ts +102 -0
  6. package/dist/_types/packages/scanner-cli/src/v2/cli-runner.d.ts +22 -0
  7. package/dist/{v2 → _types/packages/scanner-cli/src/v2}/commands.d.ts +10 -5
  8. package/dist/{v2 → _types/packages/scanner-cli/src/v2}/contracts.d.ts +53 -9
  9. package/dist/_types/packages/scanner-cli/src/v2/help.d.ts +64 -0
  10. package/dist/_types/packages/scanner-cli/src/v2/metadata-output.d.ts +37 -0
  11. package/dist/_types/packages/scanner-cli/src/v2/preflight-readiness.d.ts +108 -0
  12. package/dist/_types/packages/scanner-cli/src/v2/privacy-prepare.d.ts +39 -0
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.js +26129 -0
  15. package/dist/index.js.map +7 -0
  16. package/dist/main.js +26874 -12830
  17. package/dist/main.js.map +4 -4
  18. package/dist/mcp.js +19357 -7477
  19. package/dist/mcp.js.map +4 -4
  20. package/dist/scan-worker.js +28702 -0
  21. package/dist/scan-worker.js.map +7 -0
  22. package/dist/v2/arguments.d.ts +1 -86
  23. package/dist/v2/arguments.js +220 -21
  24. package/dist/v2/arguments.js.map +3 -3
  25. package/dist/v2/cli-runner.d.ts +1 -28
  26. package/dist/v2/cli-runner.js +19080 -7387
  27. package/dist/v2/cli-runner.js.map +4 -4
  28. package/dist/v2/help.d.ts +1 -27
  29. package/dist/v2/help.js +77 -9
  30. package/dist/v2/help.js.map +2 -2
  31. package/dist/v2/metadata-output.d.ts +1 -37
  32. package/dist/v2/metadata-output.js +20917 -276
  33. package/dist/v2/metadata-output.js.map +4 -4
  34. package/dist/v2/preflight-readiness.d.ts +1 -0
  35. package/dist/v2/preflight-readiness.js +447 -0
  36. package/dist/v2/preflight-readiness.js.map +7 -0
  37. package/dist/v2/privacy-prepare.d.ts +1 -0
  38. package/dist/v2/privacy-prepare.js +232 -0
  39. package/dist/v2/privacy-prepare.js.map +7 -0
  40. package/package.json +82 -67
  41. package/dist/v2/atomic-output.d.ts +0 -34
  42. package/dist/v2/batch-runner.d.ts +0 -44
  43. package/dist/v2/config.d.ts +0 -16
  44. package/dist/v2/exit-reducer.d.ts +0 -23
  45. package/dist/v2/input-read.d.ts +0 -26
  46. package/dist/v2/input-selection.d.ts +0 -38
  47. package/dist/v2/json-output.d.ts +0 -97
  48. package/dist/v2/metadata-validation.d.ts +0 -4
  49. package/dist/v2/ndjson-output.d.ts +0 -3
  50. package/dist/v2/sarif-helpers.d.ts +0 -69
  51. package/dist/v2/sarif-output.d.ts +0 -40
  52. package/dist/v2/table-output.d.ts +0 -2
  53. package/dist/v2/worker-host.d.ts +0 -24
package/README.md CHANGED
@@ -1,214 +1,141 @@
1
- # sfscanner — The n8n-SecureFlow Command-Line Interface & Native AI MCP Server
2
-
3
- > **CLI Executable:** `sfscanner`
4
- > **Native AI MCP Server:** `sfscanner-mcp` (`dist/mcp.js`)
5
- > **Licensing:** MIT for this package's code and scanner tooling. The catalogue dataset has separate Personal / Non-Commercial terms; see the [canonical policy](https://github.com/jitwark/n8n-Secureflow/blob/main/docs/LICENSING.md).
6
-
7
- ---
8
-
9
- ## 1. Overview
10
-
11
- `sfscanner` is a high-performance, deterministic offline command-line scanner and native **Model Context Protocol (MCP)** server for n8n workflows. Built directly on `@hub/scanner-core`, it allows individual developers, DevOps engineers, and autonomous AI coding agents to audit workflow security without uploading workflow JSON to external servers.
12
-
13
- ### Core Highlights
14
- * ⚡ **Sub-15ms Latency:** Audits typical workflows in ~12–15 milliseconds on modern CPUs.
15
- * 🛡️ **Zero Network Telemetry:** Operates 100% offline; zero outbound calls or analytics pings.
16
- * 📊 **Enterprise SARIF 2.1.0:** Generates standard SARIF reports that integrate directly with GitHub Code Scanning, GitLab Security Dashboards, and VS Code.
17
- * 🤖 **Built-In AI MCP Server:** Connects directly to Claude Desktop, Cursor, and agentic workflows to inspect workflows before importing.
18
-
19
- ---
20
-
21
- ## 2. Installation & Quickstart
22
-
23
- ### Personal Use Installation
24
- ```bash
25
- # The repository is private: cloning requires access you have been granted.
26
- git clone https://github.com/jitwark/n8n-community.git
27
- cd n8n-community/community-hub
28
-
29
- # Install dependencies and build CLI & MCP binaries
30
- npm install
31
- npm run build --workspace=sfscanner
32
-
33
- # Link globally for local personal use
34
- npm link --workspace=sfscanner
35
- ```
36
-
37
- `sfscanner` is published on the public npm registry. `private: false` in this package's manifest is a
38
- packaging flag, not an availability claim. To install the tarball instead of the registry copy, use
39
- `npm pack --workspace sfscanner`, or run the workspace build above. v2 inputs must be
40
- selection-root-relative paths; [docs/scanner/cli-v2.md](../../docs/scanner/cli-v2.md) states that rule
41
- and carries a verified Windows example.
42
-
43
- ### Basic Command-Line Usage
44
- ```bash
45
- # Scan a single workflow
46
- sfscanner scan path/to/workflow.json
47
-
48
- # Scan a directory of workflows with SARIF output
49
- sfscanner scan ./workflows --format sarif > results.sarif
50
-
51
- # Scan via standard input (piped from curl or cat)
52
- cat my-workflow.json | sfscanner scan -
53
-
54
- # Inspect admitted security policies
55
- sfscanner rules --format table
56
-
57
- # Explain a specific rule and its remediation
58
- sfscanner explain TAINTED_COMMAND
59
- ```
60
-
61
- ---
62
-
63
- ## 3. CLI Command Reference & Grammar
64
-
65
- ```text
66
- sfscanner --schema v2 scan <file|directory|-> [options]
67
- sfscanner --schema v2 rules [--format json|table]
68
- sfscanner --schema v2 explain <rule-id> [--format json|table]
69
- sfscanner --schema v2 profiles [--format json|table]
70
- sfscanner --schema v2 validate-config <config-file> [--format json|table]
71
- sfscanner --schema v2 version [--format json|table]
72
- ```
73
-
74
- `--schema v2` is **required for `--fail-on`, `--output` and directory scans**. Omitting it
75
- runs only the single-document form: `--fail-on` and `--output` then exit `2`, and a directory
76
- argument exits `3`. Pass it explicitly.
77
-
78
- ### Command Options for `scan`
79
- * `--format <json|ndjson|sarif|table>`: Choose output format (Default: `json`). The CLI does not
80
- detect a terminal, so `table` is never selected for you — pass `--format table` to get it.
81
- * `--fail-on <CRITICAL|HIGH|MEDIUM|LOW|INFO>`: Set exit-code failure threshold (Default: `HIGH`).
82
- * `--profile <beta-default>`: Select scanning profile (Default: `beta-default@2.0.0`).
83
- * `--include <glob>` / `--exclude <glob>`: Filter workflow paths during directory scans.
84
- * `--output <file>`: Atomic write destination using temporary files to prevent partial file corruption.
85
-
86
- ### Supported platforms
87
-
88
- **Node 22 is the only supported line**, and it has only been verified on Windows; Linux and
89
- macOS runs are pending. `engines.node` accepts `>=22 <23`, so the installer admits the 22
90
- series and refuses 23 and 24 outright rather than admitting lines that were never run. Pin
91
- Node 22 in CI until a matrix result exists for another line.
92
-
93
- ---
94
-
95
- ## 4. Exit Code Lattice
96
-
97
- The CLI uses a deterministic exit code lattice to communicate scan results to CI/CD pipelines:
98
-
99
- | Exit Code | Classification | Meaning |
100
- | :---: | :--- | :--- |
101
- | `0` | **CLEAN / SUCCESS** | Scan completed; no findings met or exceeded the `--fail-on` threshold. |
102
- | `1` | **FINDINGS_EXCEEDED** | One or more findings met or exceeded the configured threshold. |
103
- | `2` | **USAGE_OR_CONFIG_ERROR** | Invalid CLI arguments, bad config file, or unknown rule profile. |
104
- | `3` | **INPUT_OR_INDETERMINATE** | Input JSON is malformed, or missing dependencies forced an `INDETERMINATE` state under strict mode. |
105
- | `4` | **INTERNAL_ERROR** | Uncaught scanner error or memory ceiling violation. |
106
- | `130` | **INTERRUPTED** | Execution cancelled via SIGINT (Ctrl+C). |
107
-
108
- ---
109
-
110
- ## 5. Continuous Integration (CI/CD) Integration
111
-
112
- ### GitHub Actions Workflow
113
- Export SARIF 2.1.0 reports directly into the GitHub Repository **Security** tab:
114
-
115
- ```yaml
116
- name: n8n Workflow Security Scan
117
-
118
- on:
119
- push:
120
- paths: ['**.json']
121
- pull_request:
122
-
123
- jobs:
124
- scan:
125
- runs-on: ubuntu-latest
126
- steps:
127
- - name: Checkout Code
128
- uses: actions/checkout@v4
129
-
130
- - name: Setup Node.js
131
- uses: actions/setup-node@v4
132
- with:
133
- node-version: 22
134
-
135
- - name: Install sfscanner
136
- run: |
137
- cd community-hub && npm ci && npm run build --workspace=sfscanner
138
- npm link --workspace=sfscanner
139
-
140
- - name: Run Scan
141
- run: |
142
- sfscanner scan ./workflows --format sarif > sfscanner.sarif
143
-
144
- - name: Upload SARIF to GitHub Security Tab
145
- uses: github/codeql-action/upload-sarif@v3
146
- with:
147
- sarif_file: sfscanner.sarif
148
- ```
149
-
150
- ---
151
-
152
- ## 6. Native AI MCP Server (`sfscanner-mcp`)
153
-
154
- `sfscanner` includes a production-ready, native **Model Context Protocol (MCP)** server (`dist/mcp.js`) running over standard I/O JSON-RPC 2.0. It gives AI coding assistants the power to audit n8n workflows before executing or importing them.
155
-
156
- ```mermaid
157
- graph LR
158
- User["Developer / Operator"] --> Agent["AI Assistant (Claude / Cursor)"]
159
- Agent -->|MCP stdio JSON-RPC| Server["sfscanner-mcp (dist/mcp.js)"]
160
- Server -->|Static In-Memory Scan| Core["@hub/scanner-core Engine"]
161
- Core -->|SARIF / JSON Finding| Server
162
- Server -->|Diagnostic Report| Agent
163
- Agent -->|Safe Workflow Advice| User
164
- ```
165
-
166
- ### Tool Definition
167
- * **Tool Name:** `n8n_scan`
168
- * **Description:** *"Scan local n8n workflow JSON with the admitted deterministic offline v2 profile."*
169
- * **Parameters:**
170
- * `inputs` (array of strings, required): Local workflow file paths.
171
- * `format` (optional string): `'json' | 'ndjson' | 'sarif' | 'table'`.
172
- * `failOn` (optional string): `'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW' | 'INFO'`.
173
-
174
- ### Connecting to Claude Desktop
175
- Add this entry to your `claude_desktop_config.json`:
176
-
177
- ```json
178
- {
179
- "mcpServers": {
180
- "sfscanner": {
181
- "command": "node",
182
- "args": [
183
- "/absolute/path/to/n8n-community/community-hub/packages/scanner-cli/dist/mcp.js"
184
- ]
185
- }
186
- }
187
- }
188
- ```
189
-
190
- ### Connecting to Cursor
191
- Add this entry to your Cursor Settings (`.cursor/mcp.json`):
192
-
193
- ```json
194
- {
195
- "mcpServers": {
196
- "sfscanner": {
197
- "command": "node",
198
- "args": [
199
- "d:/projects/n8n-community/community-hub/packages/scanner-cli/dist/mcp.js"
200
- ]
201
- }
202
- }
203
- }
204
- ```
205
-
206
- ### Example AI Prompting
207
- Once configured, you can prompt your AI agent:
208
- > *"Before we deploy this automation, use the `n8n_scan` tool to check `workflows/lead-sync.json` for prompt injection or leaked credentials."*
209
-
210
- ---
211
-
212
- ## 7. Licensing Terms
213
-
214
- `sfscanner` code and scanner tooling are MIT-licensed; see [`LICENSE`](LICENSE). The aggregated workflow catalogue dataset (`data/`) has separate Personal / Non-Commercial terms and is not included in this package. See the [canonical licensing policy](https://github.com/jitwark/n8n-Secureflow/blob/main/docs/LICENSING.md).
1
+ # sfscanner 🔍
2
+
3
+ **Deterministic, offline security scanning for n8n workflows** — JSON, NDJSON, a table, or SARIF 2.1.0. The workflow never leaves your machine.
4
+
5
+ > **Licensing:** MIT for this package's code and scanner tooling. The catalogue dataset has separate Personal / Non-Commercial terms; see https://github.com/jitwark/sfscanner/blob/main/docs/LICENSING.md.
6
+
7
+ > Release candidate: the supported profile is `beta-default`; experimental hardened analysis is not publicly admitted. Supply-chain opt-in reports canonical advisory state and unknown coverage when no snapshot is admitted. See the [CLI guide](https://github.com/jitwark/sfscanner/blob/main/docs/scanner/cli-v2.md) for supported contracts and limits.
8
+ ```bash
9
+ npx sfscanner scan my-workflow.json
10
+ ```
11
+
12
+ > This package is the scanner. The workflow **catalogue** — 11,464 public n8n workflows, their
13
+ > provenance and how much of each one the scanner could actually read — lives on the website:
14
+ > <https://jitwark.github.io/sfscanner/>.
15
+
16
+ ---
17
+
18
+ ## ⚡ Quickstart
19
+
20
+ ```bash
21
+ # one file, human-readable
22
+ npx sfscanner --schema v2 scan workflow.json --format table
23
+
24
+ # a directory, SARIF for GitHub code scanning
25
+ npx sfscanner --schema v2 scan ./workflows --format sarif > results.sarif
26
+
27
+ # pipe a workflow straight from a clipboard or curl
28
+ cat workflow.json | npx sfscanner scan -
29
+
30
+ # see the rules, then read one in full
31
+ npx sfscanner --schema v2 rules --format table
32
+ npx sfscanner --schema v2 explain N8N_EXECUTE_COMMAND
33
+ ```
34
+
35
+ Node **22** is the only supported line (`engines: >=22 <23`). The CLI is ESM-only and no CommonJS artifact is shipped; `require('sfscanner')` is not supported. Runs have been verified on Windows; Linux and macOS are not yet a verified matrix.
36
+
37
+ ---
38
+
39
+ ## 🧠 What it actually checks
40
+
41
+ Seven admitted rules in the `beta-default` profile. Every row carries a severity, a confidence and a
42
+ CWE: these are deterministic pattern and configuration matches, **not** a safety guarantee, and not a
43
+ verdict about whether a workflow is safe to run.
44
+
45
+ | Rule | Severity | Confidence | CWE |
46
+ | --- | --- | --- | --- |
47
+ | `N8N_EXECUTE_COMMAND` | CRITICAL | HIGH | CWE-78 |
48
+ | `N8N_CODE_NODE` | LOW | HIGH | CWE-94 |
49
+ | `RAW_AUTH_HEADER` | HIGH | MEDIUM | CWE-522, CWE-798 |
50
+ | `RAW_SECRET_INDICATOR` | HIGH | MEDIUM | CWE-798 |
51
+ | `UNAPPROVED_DOMAIN` | MEDIUM | HIGH | — |
52
+ | `UNKNOWN_NODE_PACKAGE` | LOW | MEDIUM | CWE-1357 |
53
+ | `WEBHOOK_EXPOSURE` | MEDIUM | MEDIUM | CWE-306 |
54
+
55
+ The `beta-hardened` profile is **defined but not admitted** — `sfscanner --schema v2 profiles` says
56
+ so, and selecting it fails instead of silently running something weaker.
57
+
58
+ ---
59
+
60
+ ## 📤 Output and exit codes
61
+
62
+ Formats: `json` (default), `ndjson`, `sarif`, `table`. SARIF is 2.1.0 with CWE tags, so GitHub,
63
+ GitLab and VS Code can read it directly.
64
+
65
+ Every one of these is a first-class surface, and none is deprecated: the JSON result, NDJSON
66
+ streaming, SARIF 2.1.0 and the table stay supported for the scanner, while the published dataset
67
+ bundle keeps its NDJSON shards, SQLite database and Excel workbook. Removing a format needs usage or
68
+ cost evidence, an owner decision, migration or export access and explicit documentation — a research
69
+ note is not enough. See [Preflight and handover](../../docs/scanner/preflight-handover.md#preserved-product-formats).
70
+
71
+ | Exit | Meaning |
72
+ | :---: | --- |
73
+ | `0` | Clean — nothing met the `--fail-on` threshold. |
74
+ | `1` | Findings at or above `--fail-on`, or a degraded result under `--require-complete`. |
75
+ | `2` | Usage or configuration error. |
76
+ | `3` | Malformed input, a failed/timed-out input, or an `INDETERMINATE` result — unless a finding at/above `--fail-on` already decided exit 1. |
77
+ | `4` | Internal error or a memory ceiling. |
78
+ | `130` | Interrupted. |
79
+
80
+ `--fail-on <CRITICAL|HIGH|MEDIUM|LOW|INFO>` (Default: `INFO`). `--schema v2` is required for
81
+ directory scans, `--output` and `--fail-on`; without it those are usage errors by design.
82
+
83
+ Optional readiness assessment: `--include-readiness` (default `false`) extends `json`, `ndjson`, or `table` output with offline preflight checks (completeness status, declared credentials, integrations, and subworkflows). SARIF format combined with `--include-readiness` is rejected.
84
+
85
+ ---
86
+
87
+ ## 🤖 MCP server
88
+
89
+ The package ships `sfscanner-mcp` — a stdio JSON-RPC MCP server with **one** tool, `n8n_scan`. It
90
+ scans local workflow files with the same engine and returns the same structured output, so an agent
91
+ can read a workflow before it imports it.
92
+
93
+ ```json
94
+ {
95
+ "mcpServers": {
96
+ "sfscanner": {
97
+ "command": "node",
98
+ "args": ["<npm-root>/sfscanner/dist/mcp.js"]
99
+ }
100
+ }
101
+ }
102
+ ```
103
+
104
+ `<npm-root>` is `npm root -g`. The single tool takes `inputs` (local paths; stdin `-` is refused
105
+ because the transport owns stdin), plus optional `format`, `failOn`, `profile`, `include`, `exclude`.
106
+ Invalid arguments answer JSON-RPC `-32602` without running a scan.
107
+
108
+ ---
109
+
110
+ ## 🛡️ Limits, honestly
111
+
112
+ - Inputs are bounded: 1,536,000 bytes per file by default, 5,000 nodes, 10,000 edges, a 30 s worker
113
+ deadline, and a validated `--limits` document can tighten or raise the byte ceiling.
114
+ - The scan runs in a worker; if the worker cannot be terminated the item is reported `FAILED` rather
115
+ than "probably fine".
116
+ - Node types the scanner does not model are reported as **unknown**, not as safe. Version ranges are
117
+ matched as catalogued; there is no nearest-neighbour guess.
118
+ - Coverage of the published corpus lives on the website, with explicit counts for bodies that are
119
+ missing, source-unavailable, degraded and indeterminate.
120
+
121
+ ---
122
+
123
+ ## 📚 Documentation
124
+
125
+ - [`docs/scanner/cli-v2.md`](../../docs/scanner/cli-v2.md) — v2 admission rules and Windows example
126
+ - [`docs/scanner/limitations.md`](../../docs/scanner/limitations.md) — what the scanner does not do
127
+ - [`docs/scanner/preflight-handover.md`](../../docs/scanner/preflight-handover.md) — offline preflight and handover: prerequisite and target checks, opt-in privacy preparation, preserved output formats, bounded catalogue expansion
128
+ - [`docs/scanner/rule-reference.md`](../../docs/scanner/rule-reference.md) — every rule and remediation
129
+ - [`docs/scanner/migration-v1-v2.md`](../../docs/scanner/migration-v1-v2.md) — v1 remains supported
130
+ - [`docs/LICENSING.md`](../../docs/LICENSING.md) — licence terms
131
+
132
+ v1 (`sfscanner scan file.json`) still works for one input with the `beta-default` profile.
133
+
134
+ ---
135
+
136
+ ## ⚖️ Licence
137
+
138
+ MIT for this package's code and scanner tooling. The catalogue dataset has separate Personal /
139
+ Non-Commercial terms; see https://github.com/jitwark/sfscanner/blob/main/docs/LICENSING.md.
140
+ The dataset is not shipped in this package. A finding tells you what to read before importing a
141
+ workflow; it does not make one safe.