secufusion-mcp 1.0.5 → 1.0.6

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/README.md +6 -5
  2. package/index.js +45 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -228,6 +228,7 @@ This writes to `.rejected-patterns.json`:
228
228
  | **SPEC** | `.current-task-spec.md` is missing or has unchecked `- [ ]` boxes |
229
229
  | **LINTING** | AST linters (ESLint, Checkstyle) fail in any discovered microservice. Fix natively, do not suppress! (Falls back to regex if no linters exist) |
230
230
  | **SECURITY** | Hardcoded IPs or `uat.*` / `prod.*` / `staging.*` URLs in source or config files |
231
+ | **TENANT ISOLATION** | `*Repository.java` files contain query methods or `@Query` annotations that do NOT include `tenant` filtering |
231
232
  | **FLYWAY** | `@Entity`-annotated Java files exist but no `V*__.sql` Flyway migrations found |
232
233
 
233
234
  **Example — Run checks before PR:**
@@ -517,7 +518,7 @@ Timestamp: 2026-08-26T16:00:00.000Z
517
518
  ## PR Summary
518
519
  - Work Item: #2847
519
520
  - Spec: All acceptance criteria verified ✅
520
- - Guardrails: tenantId scoping, no debug logs, no hardcoded URLs, Flyway covered ✅
521
+ - Guardrails: tenant isolation secured, no debug logs, no hardcoded URLs, Flyway covered ✅
521
522
  - Ready to raise PR 🚀
522
523
 
523
524
  🚫 Rejected Patterns Reminder (1 on record)
@@ -585,7 +586,7 @@ You are an elite Senior Developer and Architect working on the SecuFusion worksp
585
586
 
586
587
  ## Phase 1 — Planning (TRIGGER: user assigns a task or work item)
587
588
  - Do NOT write code immediately. First, call `manage_feature_spec`.
588
- - Determine which microservices are likely affected. Pass a `reference_file_path` to observe exact coding patterns.
589
+ - Determine which microservices are likely affected. Pass a `reference_file_path` from each to observe exact coding patterns.
589
590
  - Pass the user's requirements into `task_description` to generate the workspace-level `.current-task-spec.md` blueprint.
590
591
  - Wait for the spec to be generated before writing any code.
591
592
 
@@ -600,11 +601,11 @@ You are an elite Senior Developer and Architect working on the SecuFusion worksp
600
601
  - Always check `.rejected-patterns.json` implicitly before suggesting architectural choices to ensure you never repeat past mistakes.
601
602
 
602
603
  ## Phase 4 — PR Handoff (TRIGGER: user says "prepare PR", "finish up", or "run checks")
603
- - Call `run_pre_pr_checks` with the Azure DevOps `work_item_id`. The tool will automatically discover all modified microservices in the workspace and run their native linters.
604
- - If the tool throws an error for a specific repository (e.g., missing Flyway SQL migration, or a linter failing due to console logs/bad formatting), YOU MUST navigate to that specific microservice, FIX THE ERROR in the codebase, and run the tool again until the entire workspace passes. Do not suppress linter warnings.
604
+ - Call `run_pre_pr_checks` with the Azure DevOps `work_item_id`. The tool will automatically discover all modified microservices in the workspace and run native linters, database script checks, and strict tenant-isolation scanners.
605
+ - If the tool throws an error for a specific repository (e.g., missing Flyway SQL migration, missing `tenantId` in a query, or a linter failing), YOU MUST navigate to that specific microservice, FIX THE ERROR in the codebase natively, and run the tool again until the entire workspace passes. Do not suppress warnings.
605
606
 
606
607
  ## Guardrails (enforce always, no exceptions)
607
- - All DB queries and event payloads MUST be scoped with `tenantId` unless the spec explicitly notes it as a global/system operation.
608
+ - TENANT SAFETY IS AUTOMATED: The PR Gatekeeper actively scans all `*Repository.java` files. If you write a database query (derived method or `@Query`) that does not explicitly filter by `tenantId` or contain the word `tenant`, the PR will be blocked. Write secure, tenant-isolated queries on your first attempt.
608
609
  - Do not ignore linter errors. AST-level tools (ESLint, Checkstyle/Maven) are the source of truth for hygiene. Fix them natively.
609
610
  - Never hardcode UAT/Prod IPs or URLs. Use environment variables or configuration properties.
610
611
  - If you modify a JPA `@Entity` in any backend repo, you MUST create the corresponding Flyway `.sql` migration script before running PR checks.
package/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * - run_pre_pr_checks : gate PRs via AST-level linters (ESLint / Maven Checkstyle) + structural checks
9
9
  *
10
10
  * Guardrails enforced:
11
- * 1. All DB queries and event payloads must carry tenantId.
11
+ * 1. TENANT SAFETY AUTOMATED: Active scanning of *Repository.java for tenantId scoping.
12
12
  * 2. Code hygiene (console.log, unused vars, formatting) enforced via ESLint / Checkstyle — not regex.
13
13
  * 3. No hardcoded UAT/Prod IPs or environment URLs.
14
14
  * 4. Every modified JPA @Entity must have a matching Flyway SQL migration.
@@ -246,6 +246,31 @@ function findProjectRoots(dir, depth = 0) {
246
246
  }
247
247
  return [...new Set(roots)];
248
248
  }
249
+ // ── Automated Tenant Isolation Scanner ────────────────────────────────────────
250
+ function checkTenantIsolation(rootDir) {
251
+ const violations = [];
252
+ const files = walkDir(rootDir, [".java"]).filter(f => f.endsWith("Repository.java"));
253
+ const queryMethodRegex = /\b(?:find|get|read|query|search|stream|count|exists|delete|remove)(?:All)?By[A-Z0-9]/;
254
+ const atQueryRegex = /@Query\s*\(/;
255
+ for (const file of files) {
256
+ const content = readFileSafe(file);
257
+ if (!content)
258
+ continue;
259
+ const lines = content.split("\n");
260
+ for (let i = 0; i < lines.length; i++) {
261
+ const line = lines[i];
262
+ if (queryMethodRegex.test(line) || atQueryRegex.test(line)) {
263
+ // Look at current line and the next to handle simple wrapping
264
+ const combinedContext = line + (lines[i + 1] || "");
265
+ if (!/tenant/i.test(combinedContext)) {
266
+ violations.push(`Missing tenant isolation in ${path.relative(rootDir, file)}:${i + 1} — query lacks 'tenantId':\n` +
267
+ ` ${line.trim()}`);
268
+ }
269
+ }
270
+ }
271
+ }
272
+ return violations;
273
+ }
249
274
  function checkFlywayMigrations(rootDir) {
250
275
  const warnings = [];
251
276
  const javaFiles = walkDir(rootDir, [".java"]);
@@ -464,9 +489,9 @@ server.tool("log_rejected_pattern", "Record a coding pattern that was rejected b
464
489
  });
465
490
  // ─── Tool 3: run_pre_pr_checks ───────────────────────────────────────────────
466
491
  server.tool("run_pre_pr_checks", "Run all SecuFusion pre-PR guardrail checks across the workspace. " +
467
- "Automatically discovers modified microservices and runs their native linters (ESLint, Maven Checkstyle). " +
468
- "Also validates: spec checkboxes, hardcoded IPs/URLs, and Flyway migration coverage for JPA entities. " +
469
- "Linter errors must be fixed natively — do not suppress warnings to pass the gate. " +
492
+ "Automatically discovers modified microservices and runs native linters, database script checks, and strict tenant-isolation scanners. " +
493
+ "Validates: spec checkboxes, hardcoded IPs/URLs, tenantId in Repositories, and Flyway migration coverage for JPA entities. " +
494
+ "Linter/isolation errors must be fixed natively — do not suppress warnings to pass the gate. " +
470
495
  "MUST pass with zero errors before a PR is raised.", {
471
496
  work_item_id: z
472
497
  .string()
@@ -479,6 +504,7 @@ server.tool("run_pre_pr_checks", "Run all SecuFusion pre-PR guardrail checks acr
479
504
  .array(z.enum([
480
505
  "spec_boxes",
481
506
  "console_logs",
507
+ "tenant_isolation",
482
508
  "hardcoded_urls",
483
509
  "flyway_migrations",
484
510
  ]))
@@ -556,7 +582,21 @@ server.tool("run_pre_pr_checks", "Run all SecuFusion pre-PR guardrail checks acr
556
582
  else {
557
583
  warnings.push("⚠️ [LINTING] Linter check SKIPPED (manually bypassed).");
558
584
  }
559
- // ── 3. Hardcoded URL check (regex — no AST equivalent needed here) ───────
585
+ // ── 3. Tenant Isolation Scanner ──────────────────────────────────────────
586
+ if (!skip_checks.includes("tenant_isolation")) {
587
+ const tenantViolations = checkTenantIsolation(scanRoot);
588
+ if (tenantViolations.length > 0) {
589
+ errors.push(`❌ [SECURITY] Tenant Isolation Failed: Found ${tenantViolations.length} query method(s) in *Repository.java without tenant scoping:\n` +
590
+ tenantViolations.map((v) => ` • ${v}`).join("\n"));
591
+ }
592
+ else {
593
+ passed.push("✅ [SECURITY] Tenant isolation active: All database queries correctly scoped with tenantId.");
594
+ }
595
+ }
596
+ else {
597
+ warnings.push("⚠️ [SECURITY] Tenant isolation check SKIPPED (manually bypassed).");
598
+ }
599
+ // ── 4. Hardcoded URL check (regex) ───────────────────────────────────────
560
600
  if (!skip_checks.includes("hardcoded_urls")) {
561
601
  const urlViolations = checkHardcodedUrls(scanRoot);
562
602
  if (urlViolations.length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secufusion-mcp",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "type": "module",
5
5
  "description": "SecuFusion MCP server - developer workflow tooling with guardrails",
6
6
  "main": "index.js",