@sentriflow/core 0.3.2 → 0.4.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.
package/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # @sentriflow/core
2
2
 
3
- Core engine for SentriFlow - a network configuration compliance validator.
3
+ Core engine for SentriFlow - a network configuration validator.
4
4
 
5
5
  ## Overview
6
6
 
7
- `@sentriflow/core` provides the fundamental building blocks for parsing and analyzing network device configurations across multiple vendors, checking them against compliance rules—whether industry best practices or your organization's specific requirements.
7
+ `@sentriflow/core` provides the fundamental building blocks for parsing and analyzing network device configurations across multiple vendors, validating them against policy rules—whether industry best practices or your organization's specific requirements.
8
+
9
+ SentriFlow is a validation tool that assesses configuration alignment with policies and standards.
8
10
 
9
11
  ## Installation
10
12
 
@@ -18,7 +20,7 @@ bun add @sentriflow/core
18
20
 
19
21
  - **Multi-vendor support**: Cisco IOS/NX-OS, Juniper JunOS, Arista EOS, Fortinet FortiGate, Palo Alto PAN-OS, and more
20
22
  - **AST-based parsing**: Converts configurations into a vendor-agnostic Abstract Syntax Tree
21
- - **Extensible rule engine**: Define compliance rules for best practices or organization-specific policies
23
+ - **Extensible rule engine**: Define validation rules for best practices or organization-specific policies
22
24
  - **IP/Subnet Extraction**: Extract and deduplicate IP addresses and CIDR subnets from configurations
23
25
  - **GRX2 Loader**: Load and decrypt extended encrypted rule packs for offline usage
24
26
  - **TypeScript native**: Full type safety with comprehensive type definitions
@@ -173,9 +175,13 @@ try {
173
175
  ## Related Packages
174
176
 
175
177
  - [`@sentriflow/cli`](https://github.com/sentriflow/sentriflow/tree/main/packages/cli) - Command-line interface
176
- - [`@sentriflow/rules-default`](https://github.com/sentriflow/sentriflow/tree/main/packages/rules-default) - Default compliance rules
178
+ - [`@sentriflow/rules-default`](https://github.com/sentriflow/sentriflow/tree/main/packages/rules-default) - Default validation rules
177
179
  - [`@sentriflow/rule-helpers`](https://github.com/sentriflow/sentriflow/tree/main/packages/rule-helpers) - Helper functions for rule development
178
180
 
181
+ ## Disclaimer
182
+
183
+ SentriFlow provides automated configuration validation. Validation results do not constitute compliance certification.
184
+
179
185
  ## License
180
186
 
181
187
  Apache-2.0
package/package.json CHANGED
@@ -1,65 +1,65 @@
1
- {
2
- "name": "@sentriflow/core",
3
- "version": "0.3.2",
4
- "description": "SentriFlow core engine for network configuration validation",
5
- "license": "Apache-2.0",
6
- "module": "src/index.ts",
7
- "type": "module",
8
- "exports": {
9
- ".": "./src/index.ts",
10
- "./grx2-loader": "./src/grx2-loader/index.ts",
11
- "./helpers": "./src/helpers/index.ts",
12
- "./helpers/common": "./src/helpers/common/index.ts",
13
- "./helpers/arista": "./src/helpers/arista/index.ts",
14
- "./helpers/aruba": "./src/helpers/aruba/index.ts",
15
- "./helpers/cisco": "./src/helpers/cisco/index.ts",
16
- "./helpers/cumulus": "./src/helpers/cumulus/index.ts",
17
- "./helpers/extreme": "./src/helpers/extreme/index.ts",
18
- "./helpers/fortinet": "./src/helpers/fortinet/index.ts",
19
- "./helpers/huawei": "./src/helpers/huawei/index.ts",
20
- "./helpers/juniper": "./src/helpers/juniper/index.ts",
21
- "./helpers/mikrotik": "./src/helpers/mikrotik/index.ts",
22
- "./helpers/nokia": "./src/helpers/nokia/index.ts",
23
- "./helpers/paloalto": "./src/helpers/paloalto/index.ts",
24
- "./helpers/vyos": "./src/helpers/vyos/index.ts"
25
- },
26
- "repository": {
27
- "type": "git",
28
- "url": "git+https://github.com/sentriflow/sentriflow.git",
29
- "directory": "packages/core"
30
- },
31
- "homepage": "https://github.com/sentriflow/sentriflow#readme",
32
- "bugs": {
33
- "url": "https://github.com/sentriflow/sentriflow/issues"
34
- },
35
- "keywords": [
36
- "network",
37
- "configuration",
38
- "validation",
39
- "security",
40
- "cisco",
41
- "juniper",
42
- "arista",
43
- "firewall",
44
- "linter",
45
- "helpers"
46
- ],
47
- "files": [
48
- "src",
49
- "LICENSE",
50
- "README.md"
51
- ],
52
- "publishConfig": {
53
- "access": "public"
54
- },
55
- "dependencies": {
56
- "node-machine-id": "^1.1.12"
57
- },
58
- "devDependencies": {
59
- "bun-types": "latest",
60
- "@types/node": "^20.0.0"
61
- },
62
- "peerDependencies": {
63
- "typescript": "^5.0.0"
64
- }
65
- }
1
+ {
2
+ "name": "@sentriflow/core",
3
+ "version": "0.4.1",
4
+ "description": "SentriFlow core engine for network configuration validation",
5
+ "license": "Apache-2.0",
6
+ "module": "src/index.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": "./src/index.ts",
10
+ "./grx2-loader": "./src/grx2-loader/index.ts",
11
+ "./helpers": "./src/helpers/index.ts",
12
+ "./helpers/common": "./src/helpers/common/index.ts",
13
+ "./helpers/arista": "./src/helpers/arista/index.ts",
14
+ "./helpers/aruba": "./src/helpers/aruba/index.ts",
15
+ "./helpers/cisco": "./src/helpers/cisco/index.ts",
16
+ "./helpers/cumulus": "./src/helpers/cumulus/index.ts",
17
+ "./helpers/extreme": "./src/helpers/extreme/index.ts",
18
+ "./helpers/fortinet": "./src/helpers/fortinet/index.ts",
19
+ "./helpers/huawei": "./src/helpers/huawei/index.ts",
20
+ "./helpers/juniper": "./src/helpers/juniper/index.ts",
21
+ "./helpers/mikrotik": "./src/helpers/mikrotik/index.ts",
22
+ "./helpers/nokia": "./src/helpers/nokia/index.ts",
23
+ "./helpers/paloalto": "./src/helpers/paloalto/index.ts",
24
+ "./helpers/vyos": "./src/helpers/vyos/index.ts"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/sentriflow/sentriflow.git",
29
+ "directory": "packages/core"
30
+ },
31
+ "homepage": "https://github.com/sentriflow/sentriflow#readme",
32
+ "bugs": {
33
+ "url": "https://github.com/sentriflow/sentriflow/issues"
34
+ },
35
+ "keywords": [
36
+ "network",
37
+ "configuration",
38
+ "validation",
39
+ "security",
40
+ "cisco",
41
+ "juniper",
42
+ "arista",
43
+ "firewall",
44
+ "linter",
45
+ "helpers"
46
+ ],
47
+ "files": [
48
+ "src",
49
+ "LICENSE",
50
+ "README.md"
51
+ ],
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "dependencies": {
56
+ "node-machine-id": "^1.1.12"
57
+ },
58
+ "devDependencies": {
59
+ "bun-types": "latest",
60
+ "@types/node": "^20.0.0"
61
+ },
62
+ "peerDependencies": {
63
+ "typescript": "^5.0.0"
64
+ }
65
+ }
@@ -358,9 +358,8 @@ export async function loadExtendedPack(
358
358
  machineId: string,
359
359
  debug?: (msg: string) => void
360
360
  ): Promise<RulePack> {
361
- debug?.(`[GRX2Loader] Loading pack: ${filePath}`);
362
- debug?.(`[GRX2Loader] License key length: ${licenseKey.length}, first 20 chars: ${licenseKey.substring(0, 20)}...`);
363
- debug?.(`[GRX2Loader] Machine ID: "${machineId}" (length: ${machineId.length})`);
361
+ debug?.(`[GRX2Loader] Loading pack: ${filePath}`);
362
+ debug?.(`[GRX2Loader] Machine ID: "${machineId}" (length: ${machineId.length})`);
364
363
 
365
364
  // Read pack file
366
365
  const data = await readFile(filePath);
@@ -31,7 +31,9 @@ export {
31
31
  GRX2_KDF_PBKDF2,
32
32
  GRX2_KEY_TYPE_TMK,
33
33
  GRX2_KEY_TYPE_CTMK,
34
+ SENTRIFLOW_HOME,
34
35
  DEFAULT_PACKS_DIRECTORY,
36
+ DEFAULT_RULES_DIRECTORY,
35
37
  CACHE_DIRECTORY,
36
38
  } from './types';
37
39
 
@@ -25,7 +25,7 @@ export interface LicensePayload {
25
25
  sub: string;
26
26
 
27
27
  /** Customer tier */
28
- tier: 'community' | 'professional' | 'enterprise';
28
+ tier: 'basic' | 'professional' | 'enterprise';
29
29
 
30
30
  /** Entitled feed IDs */
31
31
  feeds: string[];
@@ -274,8 +274,14 @@ export const GRX2_KEY_TYPE_TMK = 1;
274
274
  /** CTMK key type */
275
275
  export const GRX2_KEY_TYPE_CTMK = 2;
276
276
 
277
+ /** Base SentriFlow home directory (platform-aware: ~/.sentriflow or %USERPROFILE%\.sentriflow) */
278
+ export const SENTRIFLOW_HOME = join(homedir(), '.sentriflow');
279
+
277
280
  /** Default packs directory (platform-aware) */
278
- export const DEFAULT_PACKS_DIRECTORY = join(homedir(), '.sentriflow', 'packs');
281
+ export const DEFAULT_PACKS_DIRECTORY = join(SENTRIFLOW_HOME, 'packs');
282
+
283
+ /** Default custom rules directory (platform-aware) */
284
+ export const DEFAULT_RULES_DIRECTORY = join(SENTRIFLOW_HOME, 'rules');
279
285
 
280
286
  /** Cache directory (for downloaded packs, platform-aware) */
281
- export const CACHE_DIRECTORY = join(homedir(), '.sentriflow', 'cache');
287
+ export const CACHE_DIRECTORY = join(SENTRIFLOW_HOME, 'cache');
@@ -10,6 +10,7 @@ import {
10
10
  includesIgnoreCase,
11
11
  startsWithIgnoreCase,
12
12
  parseInteger,
13
+ findParentSection,
13
14
  } from '../common/helpers';
14
15
 
15
16
  // Re-export common helpers for convenience
@@ -214,6 +215,24 @@ export const hasWeakUsernamePassword = (node: ConfigNode): boolean => {
214
215
  return false;
215
216
  };
216
217
 
218
+ /**
219
+ * Check if password is under a line configuration section (vty, console, aux).
220
+ * Line passwords cannot be encrypted in Cisco IOS - they only support plaintext.
221
+ * Security for these should be enforced via AAA authentication instead.
222
+ *
223
+ * @param ast The full AST (array of ConfigNode)
224
+ * @param node The password node to check
225
+ * @returns true if the password is under a line vty/console/aux section
226
+ */
227
+ export const isLineConfigPassword = (ast: ConfigNode[], node: ConfigNode): boolean => {
228
+ const parent = findParentSection(ast, node);
229
+ if (!parent) return false;
230
+ const parentId = parent.id.toLowerCase();
231
+ return parentId.startsWith('line vty') ||
232
+ parentId.startsWith('line console') ||
233
+ parentId.startsWith('line aux');
234
+ };
235
+
217
236
  /**
218
237
  * Get SSH version from configuration
219
238
  */
@@ -8,4 +8,5 @@ export {
8
8
  hasChildCommand,
9
9
  getChildCommand,
10
10
  getChildCommands,
11
+ findParentSection,
11
12
  } from '../common/helpers';
@@ -202,6 +202,35 @@ export const isShutdown = (node: ConfigNode): boolean => {
202
202
  });
203
203
  };
204
204
 
205
+ /**
206
+ * Find the parent section of a node in the AST.
207
+ * Traverses the AST to locate the parent section containing the target node.
208
+ * Useful for context-aware rules that need to check parent context.
209
+ *
210
+ * @param ast The full AST (array of ConfigNode)
211
+ * @param targetNode The node to find the parent for
212
+ * @returns The parent section node, or undefined if not found
213
+ */
214
+ export const findParentSection = (
215
+ ast: ConfigNode[],
216
+ targetNode: ConfigNode
217
+ ): ConfigNode | undefined => {
218
+ for (const node of ast) {
219
+ if (node.type === 'section') {
220
+ // Check if target is a direct child (by line number match)
221
+ if (node.children.some(child =>
222
+ child.loc.startLine === targetNode.loc.startLine
223
+ )) {
224
+ return node;
225
+ }
226
+ // Recurse into children
227
+ const found = findParentSection(node.children, targetNode);
228
+ if (found) return found;
229
+ }
230
+ }
231
+ return undefined;
232
+ };
233
+
205
234
  /**
206
235
  * Check if a node is an actual interface definition (not a reference or sub-command).
207
236
  * Interface definitions are top-level sections that define physical/logical interfaces.
@@ -39,7 +39,7 @@ export interface PackProviderLicenseStatus {
39
39
  isValid: boolean;
40
40
 
41
41
  /** License tier */
42
- tier: 'community' | 'professional' | 'enterprise' | string;
42
+ tier: 'basic' | 'professional' | 'enterprise' | string;
43
43
 
44
44
  /** List of entitled feed/pack IDs */
45
45
  entitledFeeds: string[];