@sfdxy/mule-lint 1.20.0 → 1.22.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 (156) hide show
  1. package/README.md +63 -17
  2. package/dist/package.json +1 -1
  3. package/dist/src/core/XPathHelper.d.ts.map +1 -1
  4. package/dist/src/core/XPathHelper.js +8 -0
  5. package/dist/src/core/XPathHelper.js.map +1 -1
  6. package/dist/src/engine/LintEngine.d.ts +22 -0
  7. package/dist/src/engine/LintEngine.d.ts.map +1 -1
  8. package/dist/src/engine/LintEngine.js +105 -18
  9. package/dist/src/engine/LintEngine.js.map +1 -1
  10. package/dist/src/mcp/prompts/index.d.ts +1 -1
  11. package/dist/src/mcp/prompts/index.d.ts.map +1 -1
  12. package/dist/src/mcp/prompts/index.js +62 -1
  13. package/dist/src/mcp/prompts/index.js.map +1 -1
  14. package/dist/src/mcp/resources/index.js +114 -16
  15. package/dist/src/mcp/resources/index.js.map +1 -1
  16. package/dist/src/mcp/tools/getRuleDetails.d.ts.map +1 -1
  17. package/dist/src/mcp/tools/getRuleDetails.js +30 -1
  18. package/dist/src/mcp/tools/getRuleDetails.js.map +1 -1
  19. package/dist/src/rules/api-led/ApikitConsoleProductionRule.d.ts +22 -0
  20. package/dist/src/rules/api-led/ApikitConsoleProductionRule.d.ts.map +1 -0
  21. package/dist/src/rules/api-led/ApikitConsoleProductionRule.js +43 -0
  22. package/dist/src/rules/api-led/ApikitConsoleProductionRule.js.map +1 -0
  23. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.d.ts +24 -0
  24. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.d.ts.map +1 -0
  25. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.js +53 -0
  26. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.js.map +1 -0
  27. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.d.ts +25 -0
  28. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.d.ts.map +1 -0
  29. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.js +59 -0
  30. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.js.map +1 -0
  31. package/dist/src/rules/connector/EventListenerNullGuardRule.d.ts +24 -0
  32. package/dist/src/rules/connector/EventListenerNullGuardRule.d.ts.map +1 -0
  33. package/dist/src/rules/connector/EventListenerNullGuardRule.js +58 -0
  34. package/dist/src/rules/connector/EventListenerNullGuardRule.js.map +1 -0
  35. package/dist/src/rules/connector/ReplayChannelConfigRule.d.ts +23 -0
  36. package/dist/src/rules/connector/ReplayChannelConfigRule.d.ts.map +1 -0
  37. package/dist/src/rules/connector/ReplayChannelConfigRule.js +52 -0
  38. package/dist/src/rules/connector/ReplayChannelConfigRule.js.map +1 -0
  39. package/dist/src/rules/dataweave/DataWeaveRules.d.ts +11 -4
  40. package/dist/src/rules/dataweave/DataWeaveRules.d.ts.map +1 -1
  41. package/dist/src/rules/dataweave/DataWeaveRules.js +20 -20
  42. package/dist/src/rules/dataweave/DataWeaveRules.js.map +1 -1
  43. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.d.ts +25 -0
  44. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.d.ts.map +1 -0
  45. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.js +63 -0
  46. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.js.map +1 -0
  47. package/dist/src/rules/error-handling/CatchAllLastRule.d.ts +24 -0
  48. package/dist/src/rules/error-handling/CatchAllLastRule.d.ts.map +1 -0
  49. package/dist/src/rules/error-handling/CatchAllLastRule.js +65 -0
  50. package/dist/src/rules/error-handling/CatchAllLastRule.js.map +1 -0
  51. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.d.ts +28 -0
  52. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.d.ts.map +1 -0
  53. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.js +70 -0
  54. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.js.map +1 -0
  55. package/dist/src/rules/error-handling/ErrorResponseStructureRule.d.ts +23 -0
  56. package/dist/src/rules/error-handling/ErrorResponseStructureRule.d.ts.map +1 -0
  57. package/dist/src/rules/error-handling/ErrorResponseStructureRule.js +73 -0
  58. package/dist/src/rules/error-handling/ErrorResponseStructureRule.js.map +1 -0
  59. package/dist/src/rules/error-handling/GenericErrorRule.d.ts +15 -3
  60. package/dist/src/rules/error-handling/GenericErrorRule.d.ts.map +1 -1
  61. package/dist/src/rules/error-handling/GenericErrorRule.js +58 -18
  62. package/dist/src/rules/error-handling/GenericErrorRule.js.map +1 -1
  63. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts +14 -15
  64. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts.map +1 -1
  65. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js +59 -38
  66. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js.map +1 -1
  67. package/dist/src/rules/error-handling/TryScopeRule.d.ts +5 -0
  68. package/dist/src/rules/error-handling/TryScopeRule.d.ts.map +1 -1
  69. package/dist/src/rules/error-handling/TryScopeRule.js +30 -7
  70. package/dist/src/rules/error-handling/TryScopeRule.js.map +1 -1
  71. package/dist/src/rules/http/ConnectionIdleTimeoutRule.d.ts +27 -0
  72. package/dist/src/rules/http/ConnectionIdleTimeoutRule.d.ts.map +1 -0
  73. package/dist/src/rules/http/ConnectionIdleTimeoutRule.js +46 -0
  74. package/dist/src/rules/http/ConnectionIdleTimeoutRule.js.map +1 -0
  75. package/dist/src/rules/index.d.ts +1 -1
  76. package/dist/src/rules/index.d.ts.map +1 -1
  77. package/dist/src/rules/index.js +50 -8
  78. package/dist/src/rules/index.js.map +1 -1
  79. package/dist/src/rules/logging/LoggerPayloadRule.d.ts +15 -0
  80. package/dist/src/rules/logging/LoggerPayloadRule.d.ts.map +1 -1
  81. package/dist/src/rules/logging/LoggerPayloadRule.js +48 -4
  82. package/dist/src/rules/logging/LoggerPayloadRule.js.map +1 -1
  83. package/dist/src/rules/operations/FlowRefTargetExistsRule.d.ts +23 -0
  84. package/dist/src/rules/operations/FlowRefTargetExistsRule.d.ts.map +1 -0
  85. package/dist/src/rules/operations/FlowRefTargetExistsRule.js +58 -0
  86. package/dist/src/rules/operations/FlowRefTargetExistsRule.js.map +1 -0
  87. package/dist/src/rules/operations/UnusedFlowRule.d.ts +20 -0
  88. package/dist/src/rules/operations/UnusedFlowRule.d.ts.map +1 -1
  89. package/dist/src/rules/operations/UnusedFlowRule.js +73 -7
  90. package/dist/src/rules/operations/UnusedFlowRule.js.map +1 -1
  91. package/dist/src/rules/operations/UnusedVariableRule.d.ts +31 -0
  92. package/dist/src/rules/operations/UnusedVariableRule.d.ts.map +1 -0
  93. package/dist/src/rules/operations/UnusedVariableRule.js +103 -0
  94. package/dist/src/rules/operations/UnusedVariableRule.js.map +1 -0
  95. package/dist/src/rules/performance/ListenerReconnectForeverRule.d.ts +28 -0
  96. package/dist/src/rules/performance/ListenerReconnectForeverRule.d.ts.map +1 -0
  97. package/dist/src/rules/performance/ListenerReconnectForeverRule.js +56 -0
  98. package/dist/src/rules/performance/ListenerReconnectForeverRule.js.map +1 -0
  99. package/dist/src/rules/performance/ReconnectionStrategyRule.d.ts +7 -4
  100. package/dist/src/rules/performance/ReconnectionStrategyRule.d.ts.map +1 -1
  101. package/dist/src/rules/performance/ReconnectionStrategyRule.js +44 -24
  102. package/dist/src/rules/performance/ReconnectionStrategyRule.js.map +1 -1
  103. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.d.ts +36 -0
  104. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.d.ts.map +1 -0
  105. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.js +124 -0
  106. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.js.map +1 -0
  107. package/dist/src/rules/security/HardcodedCredentialsRule.d.ts +4 -0
  108. package/dist/src/rules/security/HardcodedCredentialsRule.d.ts.map +1 -1
  109. package/dist/src/rules/security/HardcodedCredentialsRule.js +15 -0
  110. package/dist/src/rules/security/HardcodedCredentialsRule.js.map +1 -1
  111. package/dist/src/rules/security/SecurePropertiesEncryptionRule.d.ts +25 -0
  112. package/dist/src/rules/security/SecurePropertiesEncryptionRule.d.ts.map +1 -0
  113. package/dist/src/rules/security/SecurePropertiesEncryptionRule.js +59 -0
  114. package/dist/src/rules/security/SecurePropertiesEncryptionRule.js.map +1 -0
  115. package/dist/src/rules/security/SecurePropertiesKeyRule.d.ts +23 -0
  116. package/dist/src/rules/security/SecurePropertiesKeyRule.d.ts.map +1 -0
  117. package/dist/src/rules/security/SecurePropertiesKeyRule.js +45 -0
  118. package/dist/src/rules/security/SecurePropertiesKeyRule.js.map +1 -0
  119. package/dist/src/rules/security/TlsKeystorePasswordRule.d.ts +25 -0
  120. package/dist/src/rules/security/TlsKeystorePasswordRule.d.ts.map +1 -0
  121. package/dist/src/rules/security/TlsKeystorePasswordRule.js +63 -0
  122. package/dist/src/rules/security/TlsKeystorePasswordRule.js.map +1 -0
  123. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.d.ts +26 -0
  124. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.d.ts.map +1 -0
  125. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.js +61 -0
  126. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.js.map +1 -0
  127. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.d.ts +34 -0
  128. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.d.ts.map +1 -0
  129. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.js +76 -0
  130. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.js.map +1 -0
  131. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.d.ts +25 -0
  132. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.d.ts.map +1 -0
  133. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.js +111 -0
  134. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.js.map +1 -0
  135. package/dist/src/rules/yaml/YamlRules.d.ts +6 -2
  136. package/dist/src/rules/yaml/YamlRules.d.ts.map +1 -1
  137. package/dist/src/rules/yaml/YamlRules.js +15 -11
  138. package/dist/src/rules/yaml/YamlRules.js.map +1 -1
  139. package/dist/src/types/Rule.d.ts +13 -0
  140. package/dist/src/types/Rule.d.ts.map +1 -1
  141. package/docs/README.md +87 -27
  142. package/docs/best-practices/ci-cd.md +135 -0
  143. package/docs/best-practices/connector-patterns.md +253 -0
  144. package/docs/best-practices/dataweave-patterns.md +370 -0
  145. package/docs/best-practices/deployment-2026.md +171 -0
  146. package/docs/best-practices/error-handling.md +277 -0
  147. package/docs/best-practices/event-driven-patterns.md +424 -0
  148. package/docs/best-practices/logging.md +163 -0
  149. package/docs/best-practices/mulesoft-best-practices.md +72 -865
  150. package/docs/best-practices/performance.md +273 -0
  151. package/docs/best-practices/rules-catalog.md +337 -29
  152. package/docs/best-practices/security.md +181 -0
  153. package/docs/best-practices/testing.md +190 -0
  154. package/docs/best-practices/variable-contracts.md +191 -0
  155. package/docs/linter/architecture.md +119 -64
  156. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  # Rules Catalog
2
2
 
3
- > **Version:** 3.0.0
4
- > **Total Rules:** 56 implemented across 14 categories
5
- > **Last Updated:** February 2026
3
+ > **Version:** 1.21.0
4
+ > **Total Rules:** 82 implemented across 16 categories
5
+ > **Last Updated:** April 2026
6
6
 
7
7
  ---
8
8
 
@@ -22,6 +22,7 @@
22
22
  - [YAML Rules](#yaml-rules)
23
23
  - [DataWeave Rules](#dataweave-rules)
24
24
  - [API-Led Rules](#api-led-rules)
25
+ - [Connector Rules](#connector-rules)
25
26
  - [Operations & Hygiene Rules](#operations--hygiene-rules)
26
27
  - [Governance Rules](#governance-rules)
27
28
  - [Experimental Rules](#experimental-rules)
@@ -30,24 +31,25 @@
30
31
 
31
32
  ## Rule Categories
32
33
 
33
- | Family | Prefix | Count | Description |
34
- | -------------- | ------------------------------------------ | ----- | ---------------------------------------------- |
35
- | Error Handling | MULE-001/003/005/007/009, ERR-001 | 6 | Error handler configuration and best practices |
36
- | Naming | MULE-002/101/102 | 3 | Naming conventions for flows and variables |
37
- | Security | MULE-004/201/202, SEC-002/003/004/006 | 7 | Security vulnerabilities, TLS, rate limiting |
38
- | Logging | MULE-006/301/303, LOG-001/004, HYG-001 | 6 | Logging standards, structured logging, hygiene |
39
- | HTTP | MULE-401/402/403 | 3 | HTTP configuration and headers |
40
- | Performance | MULE-501/502/503, PERF-002, RES-001 | 5 | Performance anti-patterns and resilience |
41
- | Documentation | MULE-601/604, DOC-001 | 3 | Documentation requirements |
42
- | Standards | MULE-008/010/701, OPS-001/002/003, API-005 | 7 | Coding standards and operations |
43
- | Complexity | MULE-801 | 1 | Code complexity |
44
- | Structure | MULE-802/803/804 | 3 | Project structure |
45
- | YAML | YAML-001/003/004 | 3 | YAML configuration validation |
46
- | DataWeave | DW-001/002/003/004 | 4 | DataWeave file validation |
47
- | API-Led | API-001/002/003/004 | 4 | API-Led connectivity patterns |
48
- | Governance | PROJ-001/002 | 2 | POM and Git hygiene |
49
- | Code Hygiene | HYG-002/003 | 2 | Commented code and unused flows |
50
- | Experimental | EXP-001/002/003 | 3 | Beta rules for evaluation |
34
+ | Family | Prefix | Count | Description |
35
+ | -------------- | ------------------------------------------------------------ | ----- | ---------------------------------------------- |
36
+ | Error Handling | MULE-001/003/005/007/009, ERR-001–004 | 9 | Error handler configuration and best practices |
37
+ | Naming | MULE-002/101/102 | 3 | Naming conventions for flows and variables |
38
+ | Security | MULE-004/201/202, SEC-002004/006–010 | 11 | Security vulnerabilities, TLS, credentials |
39
+ | Logging | MULE-006/301/303, LOG-001/004, HYG-001 | 6 | Logging standards, structured logging, hygiene |
40
+ | HTTP | MULE-401/402/403, HTTP-004 | 4 | HTTP configuration and headers |
41
+ | Performance | MULE-501/502/503, PERF-002, RES-001/002 | 6 | Performance anti-patterns and resilience |
42
+ | Documentation | MULE-601/604, DOC-001 | 3 | Documentation requirements |
43
+ | Standards | MULE-008/010/701, OPS-001003, API-005, CFG-001/002, STD-001 | 10 | Coding standards and operations |
44
+ | Complexity | MULE-801 | 1 | Code complexity |
45
+ | Structure | MULE-802/803/804 | 3 | Project structure |
46
+ | YAML | YAML-001/003/004 | 3 | YAML configuration validation |
47
+ | DataWeave | DW-001/002/003/004/005 | 5 | DataWeave file validation |
48
+ | API-Led | API-001–004/006–008 | 7 | API-Led connectivity patterns |
49
+ | Connectors | SF-001/002 | 2 | Salesforce and event connector rules |
50
+ | Governance | PROJ-001/002 | 2 | POM and Git hygiene |
51
+ | Code Hygiene | HYG-002–005 | 4 | Commented code, unused flows/variables |
52
+ | Experimental | EXP-001/002/003 | 3 | Beta rules for evaluation |
51
53
 
52
54
  ### MULE Category ID Ranges
53
55
 
@@ -180,6 +182,8 @@ The DWL file at `src/main/resources/dwl/error-response.dwl` will be checked for
180
182
 
181
183
  **Why This Matters:** Catching `ANY` can mask important errors and make debugging difficult.
182
184
 
185
+ > **Note (v1.21):** The rule now skips `type="ANY"` when it is the **last** `on-error` block in the chain. Using `type="ANY"` as a catch-all fallback (returning HTTP 500) is an accepted MuleSoft pattern per accelerator best practices.
186
+
183
187
  ---
184
188
 
185
189
  ### ERR-001: Try Scope Best Practice
@@ -219,6 +223,73 @@ The DWL file at `src/main/resources/dwl/error-response.dwl` will be checked for
219
223
 
220
224
  ---
221
225
 
226
+ ### ERR-002: Error Handler Type Coverage
227
+
228
+ | Property | Value |
229
+ | -------------- | -------------- |
230
+ | **Severity** | Warning |
231
+ | **Category** | Error Handling |
232
+ | **Issue Type** | Bug |
233
+ | **Fixable** | No |
234
+
235
+ **Description:** APIKit-based flows should handle common HTTP error types. Error handlers should cover at least the standard set: `APIKIT:BAD_REQUEST`, `APIKIT:NOT_FOUND`, `APIKIT:METHOD_NOT_ALLOWED`, and `APIKIT:NOT_ACCEPTABLE`.
236
+
237
+ **Example:**
238
+
239
+ ```xml
240
+ <!-- ✅ Good - covers common error types -->
241
+ <error-handler>
242
+ <on-error-propagate type="APIKIT:BAD_REQUEST">...</on-error-propagate>
243
+ <on-error-propagate type="APIKIT:NOT_FOUND">...</on-error-propagate>
244
+ <on-error-propagate type="APIKIT:METHOD_NOT_ALLOWED">...</on-error-propagate>
245
+ <on-error-propagate type="ANY">...</on-error-propagate>
246
+ </error-handler>
247
+ ```
248
+
249
+ ---
250
+
251
+ ### ERR-003: Error Response Structure
252
+
253
+ | Property | Value |
254
+ | -------------- | -------------- |
255
+ | **Severity** | Warning |
256
+ | **Category** | Error Handling |
257
+ | **Issue Type** | Bug |
258
+ | **Fixable** | No |
259
+
260
+ **Description:** Error handlers should set both an `httpStatus` variable and a response body (via `set-payload` or `ee:set-payload`). Missing either results in incomplete error responses to API consumers.
261
+
262
+ ---
263
+
264
+ ### ERR-004: Catch-All Must Be Last
265
+
266
+ | Property | Value |
267
+ | -------------- | -------------- |
268
+ | **Severity** | Error |
269
+ | **Category** | Error Handling |
270
+ | **Issue Type** | Bug |
271
+ | **Fixable** | No |
272
+
273
+ **Description:** An `on-error-propagate` or `on-error-continue` with `type="ANY"` must be the **last** handler in the `error-handler` block. Placing it before specific error type handlers would shadow those handlers.
274
+
275
+ **Example:**
276
+
277
+ ````xml
278
+ <!-- ❌ Bad - ANY shadows subsequent handlers -->
279
+ <error-handler>
280
+ <on-error-propagate type="ANY">...</on-error-propagate>
281
+ <on-error-propagate type="HTTP:CONNECTIVITY">...</on-error-propagate>
282
+ </error-handler>
283
+
284
+ <!-- ✅ Good - ANY is last -->
285
+ <error-handler>
286
+ <on-error-propagate type="HTTP:CONNECTIVITY">...</on-error-propagate>
287
+ <on-error-propagate type="ANY">...</on-error-propagate>
288
+ </error-handler>
289
+ ```
290
+
291
+ ---
292
+
222
293
  ## Naming Rules
223
294
 
224
295
  > **Best Practice**: Consistent naming conventions improve readability and maintainability. Use kebab-case for flows and camelCase for variables.
@@ -243,7 +314,7 @@ The DWL file at `src/main/resources/dwl/error-response.dwl` will be checked for
243
314
  <!-- ❌ Bad -->
244
315
  <flow name="processOrder">
245
316
  <sub-flow name="validateInput">
246
- ```
317
+ ````
247
318
 
248
319
  **Options:**
249
320
 
@@ -428,6 +499,68 @@ The DWL file at `src/main/resources/dwl/error-response.dwl` will be checked for
428
499
 
429
500
  ---
430
501
 
502
+ ### SEC-007: Connector Credentials Secured
503
+
504
+ | Property | Value |
505
+ | -------------- | ------------- |
506
+ | **Severity** | Error |
507
+ | **Category** | Security |
508
+ | **Issue Type** | Vulnerability |
509
+ | **Fixable** | No |
510
+
511
+ **Description:** Connector configurations (Salesforce, Database, HTTP, etc.) must use `${secure::...}` property placeholders for credential attributes like `username`, `password`, `clientId`, and `clientSecret`. Plain `${...}` placeholders are accepted but `${secure::...}` is recommended.
512
+
513
+ ---
514
+
515
+ ### SEC-008: Secure Properties Key
516
+
517
+ | Property | Value |
518
+ | -------------- | ------------- |
519
+ | **Severity** | Error |
520
+ | **Category** | Security |
521
+ | **Issue Type** | Vulnerability |
522
+ | **Fixable** | No |
523
+
524
+ **Description:** The `secure-properties:config` element's encryption `key` attribute must use a property placeholder (`${...}`), not a hardcoded value. Hardcoding the encryption key defeats the purpose of encrypted properties.
525
+
526
+ **Example:**
527
+
528
+ ```xml
529
+ <!-- ❌ Bad - hardcoded key -->
530
+ <secure-properties:config key="mySecretKey123" file="secure.yaml"/>
531
+
532
+ <!-- ✅ Good - externalized key -->
533
+ <secure-properties:config key="${mule.key}" file="secure.yaml"/>
534
+ ```
535
+
536
+ ---
537
+
538
+ ### SEC-009: TLS Keystore Password
539
+
540
+ | Property | Value |
541
+ | -------------- | ------------- |
542
+ | **Severity** | Error |
543
+ | **Category** | Security |
544
+ | **Issue Type** | Vulnerability |
545
+ | **Fixable** | No |
546
+
547
+ **Description:** TLS keystore and truststore passwords must use secure property placeholders, not hardcoded values.
548
+
549
+ ---
550
+
551
+ ### SEC-010: Secure Properties Encryption
552
+
553
+ | Property | Value |
554
+ | -------------- | ------------- |
555
+ | **Severity** | Warning |
556
+ | **Category** | Security |
557
+ | **Issue Type** | Vulnerability |
558
+ | **Fixable** | No |
559
+
560
+ **Description:** Secure properties configuration should use a strong encryption algorithm. DES is considered weak; AES or Blowfish are recommended.
561
+
562
+ ---
563
+
431
564
  ## Logging Rules
432
565
 
433
566
  > **Best Practice**: Use structured logging with categories. Never log full payloads in production - they may contain PII or be excessively large.
@@ -688,12 +821,14 @@ When headers are set via a DataWeave expression (patterns B/C) but `Content-Type
688
821
 
689
822
  **Description:** Connectors should have reconnection strategies configured for resilience.
690
823
 
691
- **Checked Connectors:** HTTP Request, HTTP Listener, JMS, AMQP, SFTP, FTP, VM, Database
824
+ **Checked Connectors:** HTTP Request, HTTP Listener, JMS, AMQP, SFTP, FTP, VM, Database, Salesforce
825
+
826
+ > **Note (v1.21):** The rule now differentiates between listener and request configurations. Listeners are recommended to use `reconnect-forever`, while requests should use bounded reconnect with `count` and `frequency`.
692
827
 
693
828
  **Example:**
694
829
 
695
830
  ```xml
696
- <!-- ✅ Good -->
831
+ <!-- ✅ Good - bounded reconnect for requests -->
697
832
  <http:request-config name="API_Config">
698
833
  <http:request-connection>
699
834
  <reconnection>
@@ -701,10 +836,31 @@ When headers are set via a DataWeave expression (patterns B/C) but `Content-Type
701
836
  </reconnection>
702
837
  </http:request-connection>
703
838
  </http:request-config>
839
+
840
+ <!-- ✅ Good - reconnect-forever for listeners -->
841
+ <http:listener-config name="Listener_Config">
842
+ <http:listener-connection>
843
+ <reconnection>
844
+ <reconnect-forever frequency="5000"/>
845
+ </reconnection>
846
+ </http:listener-connection>
847
+ </http:listener-config>
704
848
  ```
705
849
 
706
850
  ---
707
851
 
852
+ ### RES-002: Listener Reconnect-Forever
853
+
854
+ | Property | Value |
855
+ | ------------ | ----------- |
856
+ | **Severity** | Warning |
857
+ | **Category** | Performance |
858
+ | **Fixable** | No |
859
+
860
+ **Description:** Listener connectors (HTTP Listener, JMS, AMQP, VM) should use `reconnect-forever` strategy rather than bounded reconnection. Listeners are critical entry points — if they stop reconnecting after N attempts, the application becomes unreachable.
861
+
862
+ ---
863
+
708
864
  ## Documentation Rules
709
865
 
710
866
  > **Best Practice**: Well-documented flows are easier to maintain. Use meaningful names that describe business purpose.
@@ -880,6 +1036,42 @@ When headers are set via a DataWeave expression (patterns B/C) but `Content-Type
880
1036
 
881
1037
  ---
882
1038
 
1039
+ ### CFG-001: Config Properties Ordering
1040
+
1041
+ | Property | Value |
1042
+ | ------------ | --------- |
1043
+ | **Severity** | Info |
1044
+ | **Category** | Standards |
1045
+ | **Fixable** | No |
1046
+
1047
+ **Description:** Configuration property elements (`secure-properties:config`, `configuration-properties`, HTTP configs) should follow a consistent ordering at the top of Mule configuration files. This improves readability and makes it easier to locate configurations.
1048
+
1049
+ ---
1050
+
1051
+ ### CFG-002: Missing Env Properties Declaration
1052
+
1053
+ | Property | Value |
1054
+ | ------------ | --------- |
1055
+ | **Severity** | Warning |
1056
+ | **Category** | Standards |
1057
+ | **Fixable** | No |
1058
+
1059
+ **Description:** Property placeholders referenced in XML files (`${property.name}`) should have corresponding entries in the project's YAML configuration files. Detects potential runtime failures from missing property definitions.
1060
+
1061
+ ---
1062
+
1063
+ ### STD-001: APIKit Route Variable Consistency
1064
+
1065
+ | Property | Value |
1066
+ | ------------ | --------- |
1067
+ | **Severity** | Info |
1068
+ | **Category** | Standards |
1069
+ | **Fixable** | No |
1070
+
1071
+ **Description:** APIKit route implementation flows should use consistent variable naming patterns. For example, if some routes set `httpStatus` and others set `http_status`, this rule flags the inconsistency.
1072
+
1073
+ ---
1074
+
883
1075
  ## Complexity Rules
884
1076
 
885
1077
  > **Best Practice**: Keep cyclomatic complexity below 10. Extract complex logic into sub-flows.
@@ -1149,6 +1341,18 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1149
1341
 
1150
1342
  ---
1151
1343
 
1344
+ ### DW-005: Duplicate Transform Logic
1345
+
1346
+ | Property | Value |
1347
+ | ------------ | --------- |
1348
+ | **Severity** | Warning |
1349
+ | **Category** | DataWeave |
1350
+ | **Fixable** | No |
1351
+
1352
+ **Description:** Detects duplicated DataWeave transform expressions within a single file. If the same `ee:set-payload` or `ee:set-variable` CDATA content appears multiple times, this suggests extracting it into a reusable `.dwl` module.
1353
+
1354
+ ---
1355
+
1152
1356
  ## API-Led Rules
1153
1357
 
1154
1358
  > **Best Practice**: Follow API-Led Connectivity architecture with clear layer separation:
@@ -1209,6 +1413,80 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1209
1413
 
1210
1414
  ---
1211
1415
 
1416
+ ### API-006: APIKit Main Flow Structure
1417
+
1418
+ | Property | Value |
1419
+ | ------------ | ------- |
1420
+ | **Severity** | Warning |
1421
+ | **Category** | API-Led |
1422
+ | **Fixable** | No |
1423
+
1424
+ **Description:** APIKit main flow (the flow containing the `apikit:router`) should follow the standard structure: HTTP listener followed by APIKit router, with an error handler referencing the APIKit error handler.
1425
+
1426
+ ---
1427
+
1428
+ ### API-007: APIKit Status Code Variable
1429
+
1430
+ | Property | Value |
1431
+ | ------------ | ------- |
1432
+ | **Severity** | Warning |
1433
+ | **Category** | API-Led |
1434
+ | **Fixable** | No |
1435
+
1436
+ **Description:** APIKit route implementation flows (e.g., `get:\resource:api-config`) should set an `httpStatus` variable to ensure correct HTTP response codes are returned.
1437
+
1438
+ ---
1439
+
1440
+ ### API-008: APIKit Console in Production
1441
+
1442
+ | Property | Value |
1443
+ | ------------ | ------- |
1444
+ | **Severity** | Warning |
1445
+ | **Category** | API-Led |
1446
+ | **Fixable** | No |
1447
+
1448
+ **Description:** The APIKit console endpoint (`apikit:console`) should be disabled or removed in production configurations. Exposing the console in production is a security risk.
1449
+
1450
+ ---
1451
+
1452
+ ## Connector Rules
1453
+
1454
+ ### SF-001: Salesforce Replay Channel Config
1455
+
1456
+ | Property | Value |
1457
+ | ------------ | --------- |
1458
+ | **Severity** | Warning |
1459
+ | **Category** | Connector |
1460
+ | **Fixable** | No |
1461
+
1462
+ **Description:** Salesforce Streaming and Platform Event subscriptions should configure a replay channel with proper `replayOption` and `resumeOffset` settings to avoid missing events after restarts.
1463
+
1464
+ ---
1465
+
1466
+ ### SF-002: Event Listener Null Guard
1467
+
1468
+ | Property | Value |
1469
+ | ------------ | --------- |
1470
+ | **Severity** | Warning |
1471
+ | **Category** | Connector |
1472
+ | **Fixable** | No |
1473
+
1474
+ **Description:** Event-driven listeners (Salesforce CDC, JMS, Anypoint MQ, etc.) should guard against null payloads. A null check or validation step should occur early in the flow to prevent `NullPointerException` in downstream processing.
1475
+
1476
+ ---
1477
+
1478
+ ### HTTP-004: Connection Idle Timeout
1479
+
1480
+ | Property | Value |
1481
+ | ------------ | ------- |
1482
+ | **Severity** | Warning |
1483
+ | **Category** | HTTP |
1484
+ | **Fixable** | No |
1485
+
1486
+ **Description:** HTTP request configurations should set `connectionIdleTimeout` to release idle connections and prevent resource exhaustion under load.
1487
+
1488
+ ---
1489
+
1212
1490
  ## Operations & Hygiene Rules
1213
1491
 
1214
1492
  ### HYG-002: Commented Code Detection
@@ -1244,6 +1522,36 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1244
1522
  - **Flows without triggers**: Flows that have no HTTP listener, scheduler, or VM listener and aren't referenced are flagged.
1245
1523
  - **Exclusions**: Flows matching common external patterns (`-main`, `-api`, `api-`, `-console`, `-error-handler`, `global`) are excluded.
1246
1524
 
1525
+ > **Note (v1.21):** The rule now also recognizes APIKit-generated flows (e.g., `get:\resource:api-config`) and flows with external triggers (Salesforce CDC, JMS, AMQP, VM, Anypoint MQ, Kafka, and 14+ connector patterns).
1526
+
1527
+ ---
1528
+
1529
+ ### HYG-004: Flow-Ref Target Exists
1530
+
1531
+ | Property | Value |
1532
+ | ------------ | --------- |
1533
+ | **Severity** | Error |
1534
+ | **Category** | Standards |
1535
+ | **Fixable** | No |
1536
+
1537
+ **Description:** Every `<flow-ref name="...">` must point to an existing flow or sub-flow in the project. This rule uses cross-file validation via the `allFlowNames` set populated during the engine's pre-scan phase.
1538
+
1539
+ **Why This Matters:** Broken flow references cause runtime errors. Catching them during static analysis prevents deployment failures.
1540
+
1541
+ ---
1542
+
1543
+ ### HYG-005: Unused Variable Detection
1544
+
1545
+ | Property | Value |
1546
+ | ------------ | --------- |
1547
+ | **Severity** | Warning |
1548
+ | **Category** | Standards |
1549
+ | **Fixable** | No |
1550
+
1551
+ **Description:** Detects `set-variable` values that are never referenced elsewhere in the project (via `vars.variableName`, `#[vars.variableName]`, or `variableName` in DataWeave expressions).
1552
+
1553
+ **Best Practice:** Remove unused variables to reduce clutter and improve maintainability.
1554
+
1247
1555
  ---
1248
1556
 
1249
1557
  ## Governance Rules
@@ -1322,11 +1630,11 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1322
1630
 
1323
1631
  ## Rule Priority Matrix
1324
1632
 
1325
- | Severity | Count | Rules |
1326
- | -------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1327
- | Error | 10 | MULE-001, 003, 004, 201, 202, SEC-002, SEC-006, LOG-004, DW-004, YAML-004, PROJ-001 |
1328
- | Warning | 25 | MULE-002, 005, 006, 007, 008, 009, 101, 102, 301, 303, 401, 402, 403, 502, 503, 604, 701, 801, 802, 803, 804, SEC-003, SEC-004, PERF-002, RES-001, OPS-002, OPS-003, HYG-001, HYG-003, API-004, PROJ-002 |
1329
- | Info | 21 | MULE-010, 501, 601, YAML-001, 003, DW-001, 002, 003, API-001, 002, 003, 005, EXP-001, 002, 003, ERR-001, LOG-001, OPS-001, DOC-001, HYG-002 |
1633
+ | Severity | Count | Rules |
1634
+ | -------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1635
+ | Error | 14 | MULE-001, 003, 004, 201, 202, SEC-002, SEC-006, SEC-007, SEC-008, SEC-009, LOG-004, DW-004, YAML-004, ERR-004, HYG-004, PROJ-001 |
1636
+ | Warning | 37 | MULE-002, 005, 006, 007, 008, 009, 101, 102, 301, 303, 401, 402, 403, 502, 503, 604, 701, 801, 802, 803, 804, SEC-003, SEC-004, SEC-010, PERF-002, RES-001, RES-002, OPS-002, OPS-003, HYG-001, HYG-003, HYG-005, API-004, API-006, API-007, API-008, ERR-002, ERR-003, SF-001, SF-002, HTTP-004, CFG-002, DW-005, PROJ-002 |
1637
+ | Info | 27 | MULE-010, 501, 601, YAML-001, 003, DW-001, 002, 003, API-001, 002, 003, 005, EXP-001, 002, 003, ERR-001, LOG-001, OPS-001, DOC-001, HYG-002, CFG-001, STD-001 |
1330
1638
 
1331
1639
  ---
1332
1640
 
@@ -0,0 +1,181 @@
1
+ # Security Best Practices
2
+
3
+ > **Applies to:** All
4
+ > **Related Rules:** `MULE-004` · `MULE-201` · `MULE-202` · `SEC-002` – `SEC-010` · `YAML-004` · `LOG-004`
5
+ > **Last Updated:** April 2026
6
+
7
+ ## When to Read This
8
+
9
+ Read this when handling credentials, configuring TLS, securing API endpoints, or reviewing a project for security compliance.
10
+
11
+ ---
12
+
13
+ ## Key Principles
14
+
15
+ 1. **Never hardcode secrets** — use `${secure::...}` property placeholders
16
+ 2. **Never hardcode URLs** — all hosts, ports, and paths go in YAML config
17
+ 3. **Encrypt sensitive properties** — AES/CBC with externalized key
18
+ 4. **Use TLS 1.2+ only** — TLS 1.0/1.1 and SSLv3 are deprecated
19
+ 5. **Shift-left security** — validate security in design phase, not after deployment
20
+
21
+ ---
22
+
23
+ ## Patterns
24
+
25
+ ### Pattern 1: Secure Properties Configuration
26
+
27
+ ```xml
28
+ <!-- Load secure properties with externalized encryption key -->
29
+ <secure-properties:config name="Secure_Properties_Config"
30
+ file="config/secure-${mule.env}.yaml"
31
+ key="${secure.key}">
32
+ <secure-properties:encrypt algorithm="AES" mode="CBC"/>
33
+ </secure-properties:config>
34
+ ```
35
+
36
+ ```yaml
37
+ # config/secure-dev.yaml (encrypted values)
38
+ salesforce:
39
+ jwt:
40
+ consumerKey: '![encrypted-value]'
41
+ storePassword: '![encrypted-value]'
42
+ ```
43
+
44
+ **Rules:**
45
+
46
+ - `key` attribute MUST be a property placeholder (`${secure.key}`) — never hardcoded
47
+ - Use `AES` or `Blowfish` — `DES` is considered weak
48
+ - Encrypt using Anypoint Secure Properties Tool with runtime property `secure.key`
49
+
50
+ ### Pattern 2: Connector Credential Security
51
+
52
+ ```xml
53
+ <!-- ❌ Bad — plaintext credentials -->
54
+ <http:request-config username="admin" password="secret123"/>
55
+
56
+ <!-- ❌ Bad — non-secure property -->
57
+ <http:request-config username="${api.username}" password="${api.password}"/>
58
+
59
+ <!-- ✅ Good — secure property reference -->
60
+ <http:request-config
61
+ username="${api.username}"
62
+ password="${secure::api.password}"/>
63
+ ```
64
+
65
+ Credential attributes that must use `${secure::...}`:
66
+
67
+ - `password`, `storePassword`
68
+ - `clientId`, `clientSecret`, `consumerKey`, `consumerSecret`
69
+ - `token`, `tokenSecret`, `tokenId`
70
+
71
+ ### Pattern 3: TLS Configuration
72
+
73
+ ```xml
74
+ <!-- ❌ Bad — insecure TLS -->
75
+ <tls:context name="Insecure_TLS">
76
+ <tls:trust-store insecure="true"/>
77
+ </tls:context>
78
+
79
+ <!-- ❌ Bad — deprecated protocol -->
80
+ <tls:context enabledProtocols="TLSv1.1,TLSv1.2">
81
+
82
+ <!-- ✅ Good — proper certificate validation -->
83
+ <tls:context name="Secure_TLS" enabledProtocols="TLSv1.2,TLSv1.3">
84
+ <tls:trust-store path="${tls.truststore.path}"
85
+ password="${secure::tls.truststore.password}"/>
86
+ </tls:context>
87
+ ```
88
+
89
+ ### Pattern 4: Never Log Sensitive Data
90
+
91
+ ```xml
92
+ <!-- ❌ Bad — logs sensitive values -->
93
+ <logger message="#['Token: ' ++ vars.accessToken]"/>
94
+ <logger message="#[payload]"/> <!-- May contain PII -->
95
+
96
+ <!-- ✅ Good — logs only identifiers -->
97
+ <logger message="#['Auth successful for user: ' ++ vars.userId]"/>
98
+ <logger message="#['Processing order: ' ++ payload.orderId]"/>
99
+ ```
100
+
101
+ **Detected patterns** (flagged by `SEC-006` and `LOG-004`):
102
+ `encrypt.*key`, `password`, `credentials`, `api_key`, `secret.*key`, `accessToken`, `SSN`, `creditCard`
103
+
104
+ ### Pattern 5: API Rate Limiting
105
+
106
+ For CloudHub-deployed APIs, rate limiting is applied via **API Manager policies** — not inline XML:
107
+
108
+ ```yaml
109
+ # dev.yaml — populate for API Manager autodiscovery
110
+ api:
111
+ id: '12345678' # API Manager API instance ID
112
+ ```
113
+
114
+ For self-managed deployments, configure inline:
115
+
116
+ ```xml
117
+ <throttling:config name="Rate_Limit_Config" maxRequestsPerPeriod="100" timePeriodInMilliseconds="60000"/>
118
+ ```
119
+
120
+ ### Pattern 6: Input Validation
121
+
122
+ ```xml
123
+ <!-- ✅ Good — validate incoming payload against schema -->
124
+ <flow name="post:\orders:api-config">
125
+ <json:validate-schema schema="schemas/order-request.json"/>
126
+ <!-- Process only after validation passes -->
127
+ </flow>
128
+ ```
129
+
130
+ For APIs using APIKit with RAML, schema validation is handled by the APIKit router based on the RAML type definitions.
131
+
132
+ ---
133
+
134
+ ## Zero-Trust API Architecture (2026+)
135
+
136
+ Modern MuleSoft deployments follow Zero-Trust principles:
137
+
138
+ | Layer | Control | Implementation |
139
+ | ----------------- | ------------------------------------ | ---------------------------------------- |
140
+ | **Network** | mTLS between services | TLS context with client certificates |
141
+ | **Identity** | OAuth 2.0 / JWT verified per request | API Manager policies + Flex Gateway |
142
+ | **Authorization** | Scoped permissions per API consumer | Client ID enforcement + scope validation |
143
+ | **Data** | Encrypt at rest and in transit | Secure properties + TLS 1.3 |
144
+ | **Observability** | Audit all access | Correlation IDs + structured logging |
145
+
146
+ ---
147
+
148
+ ## Environment Property Separation
149
+
150
+ ```
151
+ config/
152
+ ├── global.yaml # Shared defaults (timeouts, paths)
153
+ ├── dev.yaml # Dev-specific non-sensitive config
154
+ ├── prod.yaml # Prod-specific non-sensitive config
155
+ ├── secure-dev.yaml # Dev encrypted credentials
156
+ └── secure-prod.yaml # Prod encrypted credentials
157
+ ```
158
+
159
+ **Never store:**
160
+
161
+ - Plaintext passwords in any YAML file
162
+ - API keys or tokens in non-secure YAML files
163
+ - Encryption keys inline in XML
164
+
165
+ ---
166
+
167
+ ## Checklist
168
+
169
+ - [ ] All credentials use `${secure::...}` property placeholders
170
+ - [ ] Secure properties encryption key is externalized (`${secure.key}`)
171
+ - [ ] Encryption algorithm is AES or Blowfish (not DES)
172
+ - [ ] TLS contexts use TLSv1.2+ only — no SSLv3, TLSv1.0, TLSv1.1
173
+ - [ ] No `insecure="true"` on trust-stores
174
+ - [ ] No hardcoded URLs, hosts, or ports in XML
175
+ - [ ] No sensitive data in logger messages
176
+ - [ ] Input validation configured for all POST/PUT/PATCH endpoints
177
+ - [ ] API Manager `api.id` populated in environment YAML
178
+
179
+ ---
180
+
181
+ **See also:** [Connector Patterns](connector-patterns.md) · [Logging](logging.md) · [Configuration Management](variable-contracts.md)