guardrail-security 1.0.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/dist/attack-surface/analyzer.d.ts +50 -0
- package/dist/attack-surface/analyzer.d.ts.map +1 -0
- package/dist/attack-surface/analyzer.js +83 -0
- package/dist/attack-surface/index.d.ts +5 -0
- package/dist/attack-surface/index.d.ts.map +1 -0
- package/dist/attack-surface/index.js +20 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/languages/index.d.ts +21 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +78 -0
- package/dist/languages/java-analyzer.d.ts +72 -0
- package/dist/languages/java-analyzer.d.ts.map +1 -0
- package/dist/languages/java-analyzer.js +417 -0
- package/dist/languages/python-analyzer.d.ts +70 -0
- package/dist/languages/python-analyzer.d.ts.map +1 -0
- package/dist/languages/python-analyzer.js +425 -0
- package/dist/license/compatibility-matrix.d.ts +28 -0
- package/dist/license/compatibility-matrix.d.ts.map +1 -0
- package/dist/license/compatibility-matrix.js +323 -0
- package/dist/license/engine.d.ts +77 -0
- package/dist/license/engine.d.ts.map +1 -0
- package/dist/license/engine.js +264 -0
- package/dist/license/index.d.ts +6 -0
- package/dist/license/index.d.ts.map +1 -0
- package/dist/license/index.js +21 -0
- package/dist/sbom/generator.d.ts +108 -0
- package/dist/sbom/generator.d.ts.map +1 -0
- package/dist/sbom/generator.js +271 -0
- package/dist/sbom/index.d.ts +5 -0
- package/dist/sbom/index.d.ts.map +1 -0
- package/dist/sbom/index.js +20 -0
- package/dist/secrets/guardian.d.ts +113 -0
- package/dist/secrets/guardian.d.ts.map +1 -0
- package/dist/secrets/guardian.js +334 -0
- package/dist/secrets/index.d.ts +10 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +30 -0
- package/dist/secrets/patterns.d.ts +42 -0
- package/dist/secrets/patterns.d.ts.map +1 -0
- package/dist/secrets/patterns.js +165 -0
- package/dist/secrets/pre-commit.d.ts +39 -0
- package/dist/secrets/pre-commit.d.ts.map +1 -0
- package/dist/secrets/pre-commit.js +127 -0
- package/dist/secrets/vault-integration.d.ts +83 -0
- package/dist/secrets/vault-integration.d.ts.map +1 -0
- package/dist/secrets/vault-integration.js +295 -0
- package/dist/secrets/vault-providers.d.ts +110 -0
- package/dist/secrets/vault-providers.d.ts.map +1 -0
- package/dist/secrets/vault-providers.js +417 -0
- package/dist/supply-chain/detector.d.ts +80 -0
- package/dist/supply-chain/detector.d.ts.map +1 -0
- package/dist/supply-chain/detector.js +168 -0
- package/dist/supply-chain/index.d.ts +11 -0
- package/dist/supply-chain/index.d.ts.map +1 -0
- package/dist/supply-chain/index.js +26 -0
- package/dist/supply-chain/malicious-db.d.ts +41 -0
- package/dist/supply-chain/malicious-db.d.ts.map +1 -0
- package/dist/supply-chain/malicious-db.js +82 -0
- package/dist/supply-chain/script-analyzer.d.ts +54 -0
- package/dist/supply-chain/script-analyzer.d.ts.map +1 -0
- package/dist/supply-chain/script-analyzer.js +160 -0
- package/dist/supply-chain/typosquat.d.ts +58 -0
- package/dist/supply-chain/typosquat.d.ts.map +1 -0
- package/dist/supply-chain/typosquat.js +257 -0
- package/dist/supply-chain/vulnerability-db.d.ts +114 -0
- package/dist/supply-chain/vulnerability-db.d.ts.map +1 -0
- package/dist/supply-chain/vulnerability-db.js +310 -0
- package/package.json +34 -0
- package/src/__tests__/license/engine.test.ts +250 -0
- package/src/__tests__/supply-chain/typosquat.test.ts +191 -0
- package/src/attack-surface/analyzer.ts +152 -0
- package/src/attack-surface/index.ts +5 -0
- package/src/index.ts +21 -0
- package/src/languages/index.ts +91 -0
- package/src/languages/java-analyzer.ts +490 -0
- package/src/languages/python-analyzer.ts +498 -0
- package/src/license/compatibility-matrix.ts +366 -0
- package/src/license/engine.ts +345 -0
- package/src/license/index.ts +6 -0
- package/src/sbom/generator.ts +355 -0
- package/src/sbom/index.ts +5 -0
- package/src/secrets/guardian.ts +448 -0
- package/src/secrets/index.ts +10 -0
- package/src/secrets/patterns.ts +186 -0
- package/src/secrets/pre-commit.ts +158 -0
- package/src/secrets/vault-integration.ts +360 -0
- package/src/secrets/vault-providers.ts +446 -0
- package/src/supply-chain/detector.ts +252 -0
- package/src/supply-chain/index.ts +11 -0
- package/src/supply-chain/malicious-db.ts +103 -0
- package/src/supply-chain/script-analyzer.ts +194 -0
- package/src/supply-chain/typosquat.ts +302 -0
- package/src/supply-chain/vulnerability-db.ts +386 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* License Compliance Engine
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./compatibility-matrix"), exports);
|
|
21
|
+
__exportStar(require("./engine"), exports);
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SBOM (Software Bill of Materials) Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates SBOMs in CycloneDX and SPDX formats for compliance and security
|
|
5
|
+
*/
|
|
6
|
+
export type SBOMFormat = 'cyclonedx' | 'spdx' | 'json';
|
|
7
|
+
export interface SBOMComponent {
|
|
8
|
+
type: 'library' | 'framework' | 'application' | 'file' | 'container';
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
purl?: string;
|
|
12
|
+
licenses: string[];
|
|
13
|
+
hashes?: {
|
|
14
|
+
algorithm: string;
|
|
15
|
+
content: string;
|
|
16
|
+
}[];
|
|
17
|
+
description?: string;
|
|
18
|
+
author?: string;
|
|
19
|
+
supplier?: string;
|
|
20
|
+
externalReferences?: {
|
|
21
|
+
type: string;
|
|
22
|
+
url: string;
|
|
23
|
+
}[];
|
|
24
|
+
}
|
|
25
|
+
export interface SBOMDependency {
|
|
26
|
+
ref: string;
|
|
27
|
+
dependsOn: string[];
|
|
28
|
+
}
|
|
29
|
+
export interface SBOM {
|
|
30
|
+
format: SBOMFormat;
|
|
31
|
+
specVersion: string;
|
|
32
|
+
serialNumber: string;
|
|
33
|
+
version: number;
|
|
34
|
+
metadata: {
|
|
35
|
+
timestamp: string;
|
|
36
|
+
tools: {
|
|
37
|
+
vendor: string;
|
|
38
|
+
name: string;
|
|
39
|
+
version: string;
|
|
40
|
+
}[];
|
|
41
|
+
component: {
|
|
42
|
+
type: string;
|
|
43
|
+
name: string;
|
|
44
|
+
version: string;
|
|
45
|
+
};
|
|
46
|
+
authors?: {
|
|
47
|
+
name: string;
|
|
48
|
+
email?: string;
|
|
49
|
+
}[];
|
|
50
|
+
};
|
|
51
|
+
components: SBOMComponent[];
|
|
52
|
+
dependencies: SBOMDependency[];
|
|
53
|
+
}
|
|
54
|
+
export interface SBOMGeneratorOptions {
|
|
55
|
+
format: SBOMFormat;
|
|
56
|
+
includeDevDependencies?: boolean;
|
|
57
|
+
includeLicenses?: boolean;
|
|
58
|
+
includeHashes?: boolean;
|
|
59
|
+
outputPath?: string;
|
|
60
|
+
}
|
|
61
|
+
export declare class SBOMGenerator {
|
|
62
|
+
private readonly toolInfo;
|
|
63
|
+
/**
|
|
64
|
+
* Generate SBOM for a project
|
|
65
|
+
*/
|
|
66
|
+
generate(projectPath: string, options: SBOMGeneratorOptions): Promise<SBOM>;
|
|
67
|
+
/**
|
|
68
|
+
* Extract components from package.json
|
|
69
|
+
*/
|
|
70
|
+
private extractComponents;
|
|
71
|
+
/**
|
|
72
|
+
* Build dependency graph
|
|
73
|
+
*/
|
|
74
|
+
private buildDependencyGraph;
|
|
75
|
+
/**
|
|
76
|
+
* Get license for a package
|
|
77
|
+
*/
|
|
78
|
+
private getLicenseForPackage;
|
|
79
|
+
/**
|
|
80
|
+
* Hash content
|
|
81
|
+
*/
|
|
82
|
+
private hashContent;
|
|
83
|
+
/**
|
|
84
|
+
* Generate UUID
|
|
85
|
+
*/
|
|
86
|
+
private generateUUID;
|
|
87
|
+
/**
|
|
88
|
+
* Write SBOM to file
|
|
89
|
+
*/
|
|
90
|
+
private writeSBOM;
|
|
91
|
+
/**
|
|
92
|
+
* Convert to CycloneDX JSON format
|
|
93
|
+
*/
|
|
94
|
+
toCycloneDXJSON(sbom: SBOM): string;
|
|
95
|
+
/**
|
|
96
|
+
* Convert to SPDX JSON format
|
|
97
|
+
*/
|
|
98
|
+
toSPDXJSON(sbom: SBOM): string;
|
|
99
|
+
/**
|
|
100
|
+
* Validate SBOM structure
|
|
101
|
+
*/
|
|
102
|
+
validateSBOM(sbom: SBOM): {
|
|
103
|
+
valid: boolean;
|
|
104
|
+
errors: string[];
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export declare const sbomGenerator: SBOMGenerator;
|
|
108
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/sbom/generator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,aAAa,GAAG,MAAM,GAAG,WAAW,CAAC;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC3D,SAAS,EAAE;YACT,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,OAAO,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC9C,CAAC;IACF,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,YAAY,EAAE,cAAc,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAIvB;IAEF;;OAEG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCjF;;OAEG;YACW,iBAAiB;IAiD/B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqB5B;;OAEG;YACW,oBAAoB;IAelC;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;YACW,SAAS;IAiBvB;;OAEG;IACH,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IAsCnC;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;IA2C9B;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;CAyB/D;AAGD,eAAO,MAAM,aAAa,eAAsB,CAAC"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SBOM (Software Bill of Materials) Generator
|
|
4
|
+
*
|
|
5
|
+
* Generates SBOMs in CycloneDX and SPDX formats for compliance and security
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.sbomGenerator = exports.SBOMGenerator = void 0;
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const crypto_1 = require("crypto");
|
|
12
|
+
class SBOMGenerator {
|
|
13
|
+
toolInfo = {
|
|
14
|
+
vendor: 'Guardrail AI',
|
|
15
|
+
name: 'Guardrail-sbom-generator',
|
|
16
|
+
version: '1.0.0',
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Generate SBOM for a project
|
|
20
|
+
*/
|
|
21
|
+
async generate(projectPath, options) {
|
|
22
|
+
const packageJsonPath = (0, path_1.join)(projectPath, 'package.json');
|
|
23
|
+
if (!(0, fs_1.existsSync)(packageJsonPath)) {
|
|
24
|
+
throw new Error('package.json not found in project path');
|
|
25
|
+
}
|
|
26
|
+
const packageJson = JSON.parse((0, fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
27
|
+
const components = await this.extractComponents(projectPath, packageJson, options);
|
|
28
|
+
const dependencies = this.buildDependencyGraph(packageJson, options);
|
|
29
|
+
const sbom = {
|
|
30
|
+
format: options.format,
|
|
31
|
+
specVersion: options.format === 'cyclonedx' ? '1.5' : '2.3',
|
|
32
|
+
serialNumber: `urn:uuid:${this.generateUUID()}`,
|
|
33
|
+
version: 1,
|
|
34
|
+
metadata: {
|
|
35
|
+
timestamp: new Date().toISOString(),
|
|
36
|
+
tools: [this.toolInfo],
|
|
37
|
+
component: {
|
|
38
|
+
type: 'application',
|
|
39
|
+
name: packageJson.name || 'unknown',
|
|
40
|
+
version: packageJson.version || '0.0.0',
|
|
41
|
+
},
|
|
42
|
+
authors: packageJson.author ? [{ name: packageJson.author }] : undefined,
|
|
43
|
+
},
|
|
44
|
+
components,
|
|
45
|
+
dependencies,
|
|
46
|
+
};
|
|
47
|
+
if (options.outputPath) {
|
|
48
|
+
await this.writeSBOM(sbom, options.outputPath, options.format);
|
|
49
|
+
}
|
|
50
|
+
return sbom;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Extract components from package.json
|
|
54
|
+
*/
|
|
55
|
+
async extractComponents(projectPath, packageJson, options) {
|
|
56
|
+
const components = [];
|
|
57
|
+
const deps = { ...packageJson.dependencies };
|
|
58
|
+
if (options.includeDevDependencies) {
|
|
59
|
+
Object.assign(deps, packageJson.devDependencies);
|
|
60
|
+
}
|
|
61
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
62
|
+
const versionStr = String(version).replace(/^[\^~]/, '');
|
|
63
|
+
const component = {
|
|
64
|
+
type: 'library',
|
|
65
|
+
name,
|
|
66
|
+
version: versionStr,
|
|
67
|
+
purl: `pkg:npm/${name}@${versionStr}`,
|
|
68
|
+
licenses: [],
|
|
69
|
+
};
|
|
70
|
+
// Try to get license info
|
|
71
|
+
if (options.includeLicenses) {
|
|
72
|
+
const license = await this.getLicenseForPackage(projectPath, name);
|
|
73
|
+
if (license) {
|
|
74
|
+
component.licenses = [license];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Generate hashes if requested
|
|
78
|
+
if (options.includeHashes) {
|
|
79
|
+
const packagePath = (0, path_1.join)(projectPath, 'node_modules', name, 'package.json');
|
|
80
|
+
if ((0, fs_1.existsSync)(packagePath)) {
|
|
81
|
+
const content = (0, fs_1.readFileSync)(packagePath, 'utf-8');
|
|
82
|
+
component.hashes = [
|
|
83
|
+
{ algorithm: 'SHA-256', content: this.hashContent(content, 'sha256') },
|
|
84
|
+
{ algorithm: 'SHA-512', content: this.hashContent(content, 'sha512') },
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
components.push(component);
|
|
89
|
+
}
|
|
90
|
+
return components;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Build dependency graph
|
|
94
|
+
*/
|
|
95
|
+
buildDependencyGraph(packageJson, options) {
|
|
96
|
+
const dependencies = [];
|
|
97
|
+
const rootRef = `pkg:npm/${packageJson.name}@${packageJson.version}`;
|
|
98
|
+
const deps = Object.keys(packageJson.dependencies || {});
|
|
99
|
+
const devDeps = options.includeDevDependencies
|
|
100
|
+
? Object.keys(packageJson.devDependencies || {})
|
|
101
|
+
: [];
|
|
102
|
+
// Root dependency
|
|
103
|
+
dependencies.push({
|
|
104
|
+
ref: rootRef,
|
|
105
|
+
dependsOn: [...deps, ...devDeps].map(name => {
|
|
106
|
+
const version = packageJson.dependencies?.[name] || packageJson.devDependencies?.[name];
|
|
107
|
+
return `pkg:npm/${name}@${String(version).replace(/^[\^~]/, '')}`;
|
|
108
|
+
}),
|
|
109
|
+
});
|
|
110
|
+
return dependencies;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Get license for a package
|
|
114
|
+
*/
|
|
115
|
+
async getLicenseForPackage(projectPath, packageName) {
|
|
116
|
+
const packagePath = (0, path_1.join)(projectPath, 'node_modules', packageName, 'package.json');
|
|
117
|
+
if ((0, fs_1.existsSync)(packagePath)) {
|
|
118
|
+
try {
|
|
119
|
+
const pkgJson = JSON.parse((0, fs_1.readFileSync)(packagePath, 'utf-8'));
|
|
120
|
+
return pkgJson.license || null;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Hash content
|
|
130
|
+
*/
|
|
131
|
+
hashContent(content, algorithm) {
|
|
132
|
+
return (0, crypto_1.createHash)(algorithm).update(content).digest('hex');
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Generate UUID
|
|
136
|
+
*/
|
|
137
|
+
generateUUID() {
|
|
138
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
139
|
+
const r = Math.random() * 16 | 0;
|
|
140
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
141
|
+
return v.toString(16);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Write SBOM to file
|
|
146
|
+
*/
|
|
147
|
+
async writeSBOM(sbom, outputPath, format) {
|
|
148
|
+
let content;
|
|
149
|
+
switch (format) {
|
|
150
|
+
case 'cyclonedx':
|
|
151
|
+
content = this.toCycloneDXJSON(sbom);
|
|
152
|
+
break;
|
|
153
|
+
case 'spdx':
|
|
154
|
+
content = this.toSPDXJSON(sbom);
|
|
155
|
+
break;
|
|
156
|
+
default:
|
|
157
|
+
content = JSON.stringify(sbom, null, 2);
|
|
158
|
+
}
|
|
159
|
+
(0, fs_1.writeFileSync)(outputPath, content, 'utf-8');
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Convert to CycloneDX JSON format
|
|
163
|
+
*/
|
|
164
|
+
toCycloneDXJSON(sbom) {
|
|
165
|
+
const cyclonedx = {
|
|
166
|
+
bomFormat: 'CycloneDX',
|
|
167
|
+
specVersion: '1.5',
|
|
168
|
+
serialNumber: sbom.serialNumber,
|
|
169
|
+
version: sbom.version,
|
|
170
|
+
metadata: {
|
|
171
|
+
timestamp: sbom.metadata.timestamp,
|
|
172
|
+
tools: sbom.metadata.tools.map(t => ({
|
|
173
|
+
vendor: t.vendor,
|
|
174
|
+
name: t.name,
|
|
175
|
+
version: t.version,
|
|
176
|
+
})),
|
|
177
|
+
component: {
|
|
178
|
+
type: sbom.metadata.component.type,
|
|
179
|
+
name: sbom.metadata.component.name,
|
|
180
|
+
version: sbom.metadata.component.version,
|
|
181
|
+
'bom-ref': `pkg:npm/${sbom.metadata.component.name}@${sbom.metadata.component.version}`,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
components: sbom.components.map(c => ({
|
|
185
|
+
type: c.type,
|
|
186
|
+
name: c.name,
|
|
187
|
+
version: c.version,
|
|
188
|
+
purl: c.purl,
|
|
189
|
+
'bom-ref': c.purl,
|
|
190
|
+
licenses: c.licenses.map(l => ({ license: { id: l } })),
|
|
191
|
+
hashes: c.hashes?.map(h => ({ alg: h.algorithm, content: h.content })),
|
|
192
|
+
})),
|
|
193
|
+
dependencies: sbom.dependencies.map(d => ({
|
|
194
|
+
ref: d.ref,
|
|
195
|
+
dependsOn: d.dependsOn,
|
|
196
|
+
})),
|
|
197
|
+
};
|
|
198
|
+
return JSON.stringify(cyclonedx, null, 2);
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Convert to SPDX JSON format
|
|
202
|
+
*/
|
|
203
|
+
toSPDXJSON(sbom) {
|
|
204
|
+
const spdx = {
|
|
205
|
+
spdxVersion: 'SPDX-2.3',
|
|
206
|
+
dataLicense: 'CC0-1.0',
|
|
207
|
+
SPDXID: 'SPDXRef-DOCUMENT',
|
|
208
|
+
name: sbom.metadata.component.name,
|
|
209
|
+
documentNamespace: `https://Guardrail.ai/sbom/${sbom.serialNumber}`,
|
|
210
|
+
creationInfo: {
|
|
211
|
+
created: sbom.metadata.timestamp,
|
|
212
|
+
creators: [`Tool: ${sbom.metadata.tools[0]?.name}-${sbom.metadata.tools[0]?.version}`],
|
|
213
|
+
},
|
|
214
|
+
packages: sbom.components.map((c, i) => ({
|
|
215
|
+
SPDXID: `SPDXRef-Package-${i}`,
|
|
216
|
+
name: c.name,
|
|
217
|
+
versionInfo: c.version,
|
|
218
|
+
downloadLocation: `https://registry.npmjs.org/${c.name}/-/${c.name}-${c.version}.tgz`,
|
|
219
|
+
filesAnalyzed: false,
|
|
220
|
+
licenseConcluded: c.licenses[0] || 'NOASSERTION',
|
|
221
|
+
licenseDeclared: c.licenses[0] || 'NOASSERTION',
|
|
222
|
+
copyrightText: 'NOASSERTION',
|
|
223
|
+
externalRefs: c.purl ? [{
|
|
224
|
+
referenceCategory: 'PACKAGE-MANAGER',
|
|
225
|
+
referenceType: 'purl',
|
|
226
|
+
referenceLocator: c.purl,
|
|
227
|
+
}] : [],
|
|
228
|
+
})),
|
|
229
|
+
relationships: [
|
|
230
|
+
{
|
|
231
|
+
spdxElementId: 'SPDXRef-DOCUMENT',
|
|
232
|
+
relatedSpdxElement: 'SPDXRef-Package-0',
|
|
233
|
+
relationshipType: 'DESCRIBES',
|
|
234
|
+
},
|
|
235
|
+
...sbom.components.slice(1).map((_, i) => ({
|
|
236
|
+
spdxElementId: 'SPDXRef-Package-0',
|
|
237
|
+
relatedSpdxElement: `SPDXRef-Package-${i + 1}`,
|
|
238
|
+
relationshipType: 'DEPENDS_ON',
|
|
239
|
+
})),
|
|
240
|
+
],
|
|
241
|
+
};
|
|
242
|
+
return JSON.stringify(spdx, null, 2);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Validate SBOM structure
|
|
246
|
+
*/
|
|
247
|
+
validateSBOM(sbom) {
|
|
248
|
+
const errors = [];
|
|
249
|
+
if (!sbom.metadata?.component?.name) {
|
|
250
|
+
errors.push('Missing component name in metadata');
|
|
251
|
+
}
|
|
252
|
+
if (!sbom.components || sbom.components.length === 0) {
|
|
253
|
+
errors.push('No components found in SBOM');
|
|
254
|
+
}
|
|
255
|
+
for (const component of sbom.components) {
|
|
256
|
+
if (!component.name) {
|
|
257
|
+
errors.push('Component missing name');
|
|
258
|
+
}
|
|
259
|
+
if (!component.version) {
|
|
260
|
+
errors.push(`Component ${component.name} missing version`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
valid: errors.length === 0,
|
|
265
|
+
errors,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
exports.SBOMGenerator = SBOMGenerator;
|
|
270
|
+
// Export singleton
|
|
271
|
+
exports.sbomGenerator = new SBOMGenerator();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sbom/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SBOM (Software Bill of Materials) Module
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./generator"), exports);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
export declare enum SecretType {
|
|
2
|
+
API_KEY = "api_key",
|
|
3
|
+
PASSWORD = "password",
|
|
4
|
+
TOKEN = "token",
|
|
5
|
+
CERTIFICATE = "certificate",
|
|
6
|
+
PRIVATE_KEY = "private_key",
|
|
7
|
+
DATABASE_URL = "database_url",
|
|
8
|
+
JWT_SECRET = "jwt_secret",
|
|
9
|
+
AWS_ACCESS_KEY = "aws_access_key",
|
|
10
|
+
OTHER = "other",
|
|
11
|
+
AWS_SECRET_KEY = "aws_secret_key",
|
|
12
|
+
GITHUB_TOKEN = "github_token",
|
|
13
|
+
GOOGLE_API_KEY = "google_api_key",
|
|
14
|
+
STRIPE_KEY = "stripe_key",
|
|
15
|
+
JWT_TOKEN = "jwt_token",
|
|
16
|
+
SLACK_TOKEN = "slack_token",
|
|
17
|
+
API_KEY_GENERIC = "api_key_generic",
|
|
18
|
+
PASSWORD_GENERIC = "password_generic"
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Secret detection result
|
|
22
|
+
*/
|
|
23
|
+
export interface SecretDetection {
|
|
24
|
+
id?: string;
|
|
25
|
+
filePath: string;
|
|
26
|
+
secretType: SecretType;
|
|
27
|
+
maskedValue: string;
|
|
28
|
+
location: {
|
|
29
|
+
line: number;
|
|
30
|
+
column: number;
|
|
31
|
+
snippet: string;
|
|
32
|
+
};
|
|
33
|
+
confidence: number;
|
|
34
|
+
entropy: number;
|
|
35
|
+
isTest: boolean;
|
|
36
|
+
isRevoked: boolean;
|
|
37
|
+
recommendation: {
|
|
38
|
+
action: 'remove' | 'move_to_env' | 'use_vault' | 'revoke_and_rotate';
|
|
39
|
+
reason: string;
|
|
40
|
+
remediation: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Scan options
|
|
45
|
+
*/
|
|
46
|
+
export interface ScanOptions {
|
|
47
|
+
excludeTests?: boolean;
|
|
48
|
+
minConfidence?: number;
|
|
49
|
+
excludePatterns?: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Project scan report
|
|
53
|
+
*/
|
|
54
|
+
export interface ProjectScanReport {
|
|
55
|
+
projectId: string;
|
|
56
|
+
totalFiles: number;
|
|
57
|
+
scannedFiles: number;
|
|
58
|
+
detections: SecretDetection[];
|
|
59
|
+
summary: {
|
|
60
|
+
totalSecrets: number;
|
|
61
|
+
byType: Record<string, number>;
|
|
62
|
+
byRisk: {
|
|
63
|
+
high: number;
|
|
64
|
+
medium: number;
|
|
65
|
+
low: number;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Secrets & Credential Guardian
|
|
71
|
+
*
|
|
72
|
+
* Detects exposed secrets and credentials in code
|
|
73
|
+
*/
|
|
74
|
+
export declare class SecretsGuardian {
|
|
75
|
+
/**
|
|
76
|
+
* Scan content for secrets
|
|
77
|
+
*/
|
|
78
|
+
scanContent(content: string, filePath: string, options?: ScanOptions): Promise<SecretDetection[]>;
|
|
79
|
+
/**
|
|
80
|
+
* Scan entire project
|
|
81
|
+
*/
|
|
82
|
+
scanProject(projectPath: string, projectId: string, options?: ScanOptions): Promise<ProjectScanReport>;
|
|
83
|
+
/**
|
|
84
|
+
* Calculate entropy for randomness detection
|
|
85
|
+
*/
|
|
86
|
+
private calculateEntropy;
|
|
87
|
+
/**
|
|
88
|
+
* Check if likely test/example value
|
|
89
|
+
*/
|
|
90
|
+
private isTestValue;
|
|
91
|
+
/**
|
|
92
|
+
* Check for false positives
|
|
93
|
+
*/
|
|
94
|
+
private isFalsePositive;
|
|
95
|
+
/**
|
|
96
|
+
* Calculate confidence score
|
|
97
|
+
*/
|
|
98
|
+
private calculateConfidence;
|
|
99
|
+
/**
|
|
100
|
+
* Mask secret for safe logging
|
|
101
|
+
*/
|
|
102
|
+
private maskValue;
|
|
103
|
+
/**
|
|
104
|
+
* Generate recommendation
|
|
105
|
+
*/
|
|
106
|
+
private generateRecommendation;
|
|
107
|
+
/**
|
|
108
|
+
* Get project secrets report
|
|
109
|
+
*/
|
|
110
|
+
getProjectReport(projectId: string): Promise<SecretDetection[]>;
|
|
111
|
+
}
|
|
112
|
+
export declare const secretsGuardian: SecretsGuardian;
|
|
113
|
+
//# sourceMappingURL=guardian.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guardian.d.ts","sourceRoot":"","sources":["../../src/secrets/guardian.ts"],"names":[],"mappings":"AAQA,oBAAY,UAAU;IACpB,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,cAAc,mBAAmB;IACjC,KAAK,UAAU;IACf,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;IAC7B,cAAc,mBAAmB;IACjC,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,WAAW,gBAAgB;IAC3B,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;CACtC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,cAAc,EAAE;QACd,MAAM,EAAE,QAAQ,GAAG,aAAa,GAAG,WAAW,GAAG,mBAAmB,CAAC;QACrE,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,OAAO,EAAE;QACP,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;KACvD,CAAC;CACH;AAED;;;;GAIG;AACH,qBAAa,eAAe;IAC1B;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,eAAe,EAAE,CAAC;IAoF7B;;OAEG;IACG,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC;IAgF7B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;OAEG;IACH,OAAO,CAAC,WAAW;IAyBnB;;OAEG;IACH,OAAO,CAAC,eAAe;IAsCvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgC3B;;OAEG;IACH,OAAO,CAAC,SAAS;IAIjB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAwC9B;;OAEG;IACG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAoBtE;AAGD,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
|