sfscanner 0.1.0 → 0.2.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 CHANGED
@@ -1,214 +1,131 @@
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/n8n-Secureflow/blob/main/docs/LICENSING.md.
6
+
7
+ ```bash
8
+ npx sfscanner scan my-workflow.json
9
+ ```
10
+
11
+ > This package is the scanner. The workflow **catalogue** — 11,464 public n8n workflows, their
12
+ > provenance and how much of each one the scanner could actually read — lives on the website:
13
+ > <https://n8n-enterprise-1.web.app>.
14
+
15
+ ---
16
+
17
+ ## ⚡ Quickstart
18
+
19
+ ```bash
20
+ # one file, human-readable
21
+ npx sfscanner --schema v2 scan workflow.json --format table
22
+
23
+ # a directory, SARIF for GitHub code scanning
24
+ npx sfscanner --schema v2 scan ./workflows --format sarif > results.sarif
25
+
26
+ # pipe a workflow straight from a clipboard or curl
27
+ cat workflow.json | npx sfscanner scan -
28
+
29
+ # see the rules, then read one in full
30
+ npx sfscanner --schema v2 rules --format table
31
+ npx sfscanner --schema v2 explain N8N_EXECUTE_COMMAND
32
+ ```
33
+
34
+ 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.
35
+
36
+ ---
37
+
38
+ ## 🧠 What it actually checks
39
+
40
+ Seven admitted rules in the `beta-default` profile. Every row carries a severity, a confidence and a
41
+ CWE: these are deterministic pattern and configuration matches, **not** a safety guarantee, and not a
42
+ verdict about whether a workflow is safe to run.
43
+
44
+ | Rule | Severity | Confidence | CWE |
45
+ | --- | --- | --- | --- |
46
+ | `N8N_EXECUTE_COMMAND` | CRITICAL | HIGH | CWE-78 |
47
+ | `N8N_CODE_NODE` | LOW | HIGH | CWE-94 |
48
+ | `RAW_AUTH_HEADER` | HIGH | MEDIUM | CWE-522, CWE-798 |
49
+ | `RAW_SECRET_INDICATOR` | HIGH | MEDIUM | CWE-798 |
50
+ | `UNAPPROVED_DOMAIN` | MEDIUM | HIGH | — |
51
+ | `UNKNOWN_NODE_PACKAGE` | LOW | MEDIUM | CWE-1357 |
52
+ | `WEBHOOK_EXPOSURE` | MEDIUM | MEDIUM | CWE-306 |
53
+
54
+ The `beta-hardened` profile is **defined but not admitted** — `sfscanner --schema v2 profiles` says
55
+ so, and selecting it fails instead of silently running something weaker.
56
+
57
+ ---
58
+
59
+ ## 📤 Output and exit codes
60
+
61
+ Formats: `json` (default), `ndjson`, `sarif`, `table`. SARIF is 2.1.0 with CWE tags, so GitHub,
62
+ GitLab and VS Code can read it directly.
63
+
64
+ | Exit | Meaning |
65
+ | :---: | --- |
66
+ | `0` | Clean — nothing met the `--fail-on` threshold. |
67
+ | `1` | Findings at or above `--fail-on`, or a degraded result under `--require-complete`. |
68
+ | `2` | Usage or configuration error. |
69
+ | `3` | Malformed input, a failed/timed-out input, or an `INDETERMINATE` result — unless a finding at/above `--fail-on` already decided exit 1. |
70
+ | `4` | Internal error or a memory ceiling. |
71
+ | `130` | Interrupted. |
72
+
73
+ `--fail-on <CRITICAL|HIGH|MEDIUM|LOW|INFO>` (Default: `INFO`). `--schema v2` is required for
74
+ directory scans, `--output` and `--fail-on`; without it those are usage errors by design.
75
+
76
+ ---
77
+
78
+ ## 🤖 MCP server
79
+
80
+ The package ships `sfscanner-mcp` — a stdio JSON-RPC MCP server with **one** tool, `n8n_scan`. It
81
+ scans local workflow files with the same engine and returns the same structured output, so an agent
82
+ can read a workflow before it imports it.
83
+
84
+ ```json
85
+ {
86
+ "mcpServers": {
87
+ "sfscanner": {
88
+ "command": "node",
89
+ "args": ["<npm-root>/sfscanner/dist/mcp.js"]
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ `<npm-root>` is `npm root -g`. The single tool takes `inputs` (local paths; stdin `-` is refused
96
+ because the transport owns stdin), plus optional `format`, `failOn`, `profile`, `include`, `exclude`.
97
+ Invalid arguments answer JSON-RPC `-32602` without running a scan.
98
+
99
+ ---
100
+
101
+ ## 🛡️ Limits, honestly
102
+
103
+ - Inputs are bounded: 1,536,000 bytes per file by default, 5,000 nodes, 10,000 edges, a 30 s worker
104
+ deadline, and a validated `--limits` document can tighten or raise the byte ceiling.
105
+ - The scan runs in a worker; if the worker cannot be terminated the item is reported `FAILED` rather
106
+ than "probably fine".
107
+ - Node types the scanner does not model are reported as **unknown**, not as safe. Version ranges are
108
+ matched as catalogued; there is no nearest-neighbour guess.
109
+ - Coverage of the published corpus lives on the website, with explicit counts for bodies that are
110
+ missing, source-unavailable, degraded and indeterminate.
111
+
112
+ ---
113
+
114
+ ## 📚 Documentation
115
+
116
+ - [`docs/scanner/cli-v2.md`](../../docs/scanner/cli-v2.md) — v2 admission rules and Windows example
117
+ - [`docs/scanner/limitations.md`](../../docs/scanner/limitations.md) — what the scanner does not do
118
+ - [`docs/scanner/rule-reference.md`](../../docs/scanner/rule-reference.md) — every rule and remediation
119
+ - [`docs/scanner/migration-v1-v2.md`](../../docs/scanner/migration-v1-v2.md) — v1 remains supported
120
+ - [`docs/LICENSING.md`](../../docs/LICENSING.md) — licence terms
121
+
122
+ v1 (`sfscanner scan file.json`) still works for one input with the `beta-default` profile.
123
+
124
+ ---
125
+
126
+ ## ⚖️ Licence
127
+
128
+ MIT for this package's code and scanner tooling. The catalogue dataset has separate Personal /
129
+ Non-Commercial terms; see https://github.com/jitwark/n8n-Secureflow/blob/main/docs/LICENSING.md.
130
+ The dataset is not shipped in this package. A finding tells you what to read before importing a
131
+ workflow; it does not make one safe.
@@ -0,0 +1,4 @@
1
+ export { parseCliArguments } from './v2/arguments.js';
2
+ export { runCliV2, type PublicRunOptionsV2, type PublicRunResultV2, type PublicScanCommandV2, } from './v2/cli-runner.js';
3
+ export { getHelpV2 } from './v2/help.js';
4
+ export { emitMetadataCommandResultV2 } from './v2/metadata-output.js';