@vaultcompass/vault-guard-core 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/LICENSE +21 -0
- package/dist/baseline.d.ts +24 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +87 -0
- package/dist/baseline.js.map +1 -0
- package/dist/config-validate.d.ts +13 -0
- package/dist/config-validate.d.ts.map +1 -0
- package/dist/config-validate.js +111 -0
- package/dist/config-validate.js.map +1 -0
- package/dist/config.d.ts +69 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +106 -0
- package/dist/config.js.map +1 -0
- package/dist/diagnostics.d.ts +64 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +59 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/errors.d.ts +63 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +98 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/match-fingerprint.d.ts +7 -0
- package/dist/match-fingerprint.d.ts.map +1 -0
- package/dist/match-fingerprint.js +28 -0
- package/dist/match-fingerprint.js.map +1 -0
- package/dist/scan-output.d.ts +65 -0
- package/dist/scan-output.d.ts.map +1 -0
- package/dist/scan-output.js +140 -0
- package/dist/scan-output.js.map +1 -0
- package/dist/scanners/index.d.ts +5 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +21 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/pre-commit-hook.d.ts +41 -0
- package/dist/scanners/pre-commit-hook.d.ts.map +1 -0
- package/dist/scanners/pre-commit-hook.js +389 -0
- package/dist/scanners/pre-commit-hook.js.map +1 -0
- package/dist/scanners/secret-scanner.d.ts +99 -0
- package/dist/scanners/secret-scanner.d.ts.map +1 -0
- package/dist/scanners/secret-scanner.js +422 -0
- package/dist/scanners/secret-scanner.js.map +1 -0
- package/dist/scanners/token-counter.d.ts +27 -0
- package/dist/scanners/token-counter.d.ts.map +1 -0
- package/dist/scanners/token-counter.js +121 -0
- package/dist/scanners/token-counter.js.map +1 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/entropy.d.ts +17 -0
- package/dist/utils/entropy.d.ts.map +1 -0
- package/dist/utils/entropy.js +35 -0
- package/dist/utils/entropy.js.map +1 -0
- package/dist/utils/file-utils.d.ts +39 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +442 -0
- package/dist/utils/file-utils.js.map +1 -0
- package/dist/utils/git-utils.d.ts +12 -0
- package/dist/utils/git-utils.d.ts.map +1 -0
- package/dist/utils/git-utils.js +55 -0
- package/dist/utils/git-utils.js.map +1 -0
- package/dist/utils/path-severity.d.ts +17 -0
- package/dist/utils/path-severity.d.ts.map +1 -0
- package/dist/utils/path-severity.js +96 -0
- package/dist/utils/path-severity.js.map +1 -0
- package/dist/utils/placeholder.d.ts +53 -0
- package/dist/utils/placeholder.d.ts.map +1 -0
- package/dist/utils/placeholder.js +198 -0
- package/dist/utils/placeholder.js.map +1 -0
- package/dist/utils/regex-safety.d.ts +102 -0
- package/dist/utils/regex-safety.d.ts.map +1 -0
- package/dist/utils/regex-safety.js +193 -0
- package/dist/utils/regex-safety.js.map +1 -0
- package/dist/utils/scan-file.d.ts +29 -0
- package/dist/utils/scan-file.d.ts.map +1 -0
- package/dist/utils/scan-file.js +125 -0
- package/dist/utils/scan-file.js.map +1 -0
- package/package.json +51 -0
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Base error class for Vault Guard errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class VaultGuardError extends Error {
|
|
5
|
+
code: string;
|
|
6
|
+
constructor(message: string, code: string);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown when scanning fails
|
|
10
|
+
*/
|
|
11
|
+
export declare class ScanError extends VaultGuardError {
|
|
12
|
+
filePath?: string | undefined;
|
|
13
|
+
constructor(message: string, filePath?: string | undefined);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Error thrown when file access fails
|
|
17
|
+
*/
|
|
18
|
+
export declare class FileAccessError extends VaultGuardError {
|
|
19
|
+
filePath: string;
|
|
20
|
+
constructor(message: string, filePath: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Error thrown when hook installation fails
|
|
24
|
+
*/
|
|
25
|
+
export declare class HookError extends VaultGuardError {
|
|
26
|
+
operation: 'install' | 'uninstall';
|
|
27
|
+
constructor(message: string, operation: 'install' | 'uninstall');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Error thrown when a `.vault-guard.json` config file cannot be read or parsed.
|
|
31
|
+
*
|
|
32
|
+
* Why this is a distinct error: silently falling back to defaults on a typo'd
|
|
33
|
+
* config file is dangerous for a security tool — the user thinks their
|
|
34
|
+
* `severity_overrides` / `extra_patterns` are honoured when they are not.
|
|
35
|
+
* Callers (CLI, MCP) catch this, print the file path + parser message, and
|
|
36
|
+
* exit non-zero so the user can fix the config rather than ship undetected.
|
|
37
|
+
*
|
|
38
|
+
* @param message - Human-readable parse/read failure explanation.
|
|
39
|
+
* @param filePath - Absolute path to the offending `.vault-guard.json`.
|
|
40
|
+
*/
|
|
41
|
+
export declare class ConfigError extends VaultGuardError {
|
|
42
|
+
readonly filePath: string;
|
|
43
|
+
constructor(message: string, filePath: string);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when git operations fail during a scan.
|
|
47
|
+
*
|
|
48
|
+
* Why this is a hard error: `getGitStagedFilePaths` returning `[]` on
|
|
49
|
+
* git failure would silently produce a "✅ nothing staged" result during
|
|
50
|
+
* pre-commit, allowing secrets to bypass detection without any feedback.
|
|
51
|
+
* Callers should exit 2 and display this message so the user knows whether
|
|
52
|
+
* the ✅ is genuine or git-broken.
|
|
53
|
+
*
|
|
54
|
+
* @param message - Human-readable failure details.
|
|
55
|
+
* @param command - Git command that failed.
|
|
56
|
+
* @param cause - Original thrown error (if available).
|
|
57
|
+
*/
|
|
58
|
+
export declare class GitError extends VaultGuardError {
|
|
59
|
+
readonly command: string;
|
|
60
|
+
readonly cause?: unknown | undefined;
|
|
61
|
+
constructor(message: string, command: string, cause?: unknown | undefined);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACJ,IAAI,EAAE,MAAM;gBAApC,OAAO,EAAE,MAAM,EAAS,IAAI,EAAE,MAAM;CAKjD;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,eAAe;IACR,QAAQ,CAAC,EAAE,MAAM;gBAAzC,OAAO,EAAE,MAAM,EAAS,QAAQ,CAAC,EAAE,MAAM,YAAA;CAItD;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,eAAe;IACd,QAAQ,EAAE,MAAM;gBAAxC,OAAO,EAAE,MAAM,EAAS,QAAQ,EAAE,MAAM;CAIrD;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,eAAe;IACR,SAAS,EAAE,SAAS,GAAG,WAAW;gBAA1D,OAAO,EAAE,MAAM,EAAS,SAAS,EAAE,SAAS,GAAG,WAAW;CAIvE;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,WAAY,SAAQ,eAAe;aACD,QAAQ,EAAE,MAAM;gBAAjD,OAAO,EAAE,MAAM,EAAkB,QAAQ,EAAE,MAAM;CAI9D;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAS,SAAQ,eAAe;aACE,OAAO,EAAE,MAAM;aAAkB,KAAK,CAAC,EAAE,OAAO;gBAAjF,OAAO,EAAE,MAAM,EAAkB,OAAO,EAAE,MAAM,EAAkB,KAAK,CAAC,EAAE,OAAO,YAAA;CAI9F"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GitError = exports.ConfigError = exports.HookError = exports.FileAccessError = exports.ScanError = exports.VaultGuardError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Base error class for Vault Guard errors
|
|
6
|
+
*/
|
|
7
|
+
class VaultGuardError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
constructor(message, code) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = 'VaultGuardError';
|
|
13
|
+
Error.captureStackTrace(this, this.constructor);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.VaultGuardError = VaultGuardError;
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when scanning fails
|
|
19
|
+
*/
|
|
20
|
+
class ScanError extends VaultGuardError {
|
|
21
|
+
filePath;
|
|
22
|
+
constructor(message, filePath) {
|
|
23
|
+
super(message, 'SCAN_ERROR');
|
|
24
|
+
this.filePath = filePath;
|
|
25
|
+
this.name = 'ScanError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.ScanError = ScanError;
|
|
29
|
+
/**
|
|
30
|
+
* Error thrown when file access fails
|
|
31
|
+
*/
|
|
32
|
+
class FileAccessError extends VaultGuardError {
|
|
33
|
+
filePath;
|
|
34
|
+
constructor(message, filePath) {
|
|
35
|
+
super(message, 'FILE_ACCESS_ERROR');
|
|
36
|
+
this.filePath = filePath;
|
|
37
|
+
this.name = 'FileAccessError';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.FileAccessError = FileAccessError;
|
|
41
|
+
/**
|
|
42
|
+
* Error thrown when hook installation fails
|
|
43
|
+
*/
|
|
44
|
+
class HookError extends VaultGuardError {
|
|
45
|
+
operation;
|
|
46
|
+
constructor(message, operation) {
|
|
47
|
+
super(message, 'HOOK_ERROR');
|
|
48
|
+
this.operation = operation;
|
|
49
|
+
this.name = 'HookError';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.HookError = HookError;
|
|
53
|
+
/**
|
|
54
|
+
* Error thrown when a `.vault-guard.json` config file cannot be read or parsed.
|
|
55
|
+
*
|
|
56
|
+
* Why this is a distinct error: silently falling back to defaults on a typo'd
|
|
57
|
+
* config file is dangerous for a security tool — the user thinks their
|
|
58
|
+
* `severity_overrides` / `extra_patterns` are honoured when they are not.
|
|
59
|
+
* Callers (CLI, MCP) catch this, print the file path + parser message, and
|
|
60
|
+
* exit non-zero so the user can fix the config rather than ship undetected.
|
|
61
|
+
*
|
|
62
|
+
* @param message - Human-readable parse/read failure explanation.
|
|
63
|
+
* @param filePath - Absolute path to the offending `.vault-guard.json`.
|
|
64
|
+
*/
|
|
65
|
+
class ConfigError extends VaultGuardError {
|
|
66
|
+
filePath;
|
|
67
|
+
constructor(message, filePath) {
|
|
68
|
+
super(message, 'CONFIG_ERROR');
|
|
69
|
+
this.filePath = filePath;
|
|
70
|
+
this.name = 'ConfigError';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.ConfigError = ConfigError;
|
|
74
|
+
/**
|
|
75
|
+
* Error thrown when git operations fail during a scan.
|
|
76
|
+
*
|
|
77
|
+
* Why this is a hard error: `getGitStagedFilePaths` returning `[]` on
|
|
78
|
+
* git failure would silently produce a "✅ nothing staged" result during
|
|
79
|
+
* pre-commit, allowing secrets to bypass detection without any feedback.
|
|
80
|
+
* Callers should exit 2 and display this message so the user knows whether
|
|
81
|
+
* the ✅ is genuine or git-broken.
|
|
82
|
+
*
|
|
83
|
+
* @param message - Human-readable failure details.
|
|
84
|
+
* @param command - Git command that failed.
|
|
85
|
+
* @param cause - Original thrown error (if available).
|
|
86
|
+
*/
|
|
87
|
+
class GitError extends VaultGuardError {
|
|
88
|
+
command;
|
|
89
|
+
cause;
|
|
90
|
+
constructor(message, command, cause) {
|
|
91
|
+
super(message, 'GIT_ERROR');
|
|
92
|
+
this.command = command;
|
|
93
|
+
this.cause = cause;
|
|
94
|
+
this.name = 'GitError';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.GitError = GitError;
|
|
98
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,eAAgB,SAAQ,KAAK;IACJ;IAApC,YAAY,OAAe,EAAS,IAAY;QAC9C,KAAK,CAAC,OAAO,CAAC,CAAC;QADmB,SAAI,GAAJ,IAAI,CAAQ;QAE9C,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAClD,CAAC;CACF;AAND,0CAMC;AAED;;GAEG;AACH,MAAa,SAAU,SAAQ,eAAe;IACR;IAApC,YAAY,OAAe,EAAS,QAAiB;QACnD,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QADK,aAAQ,GAAR,QAAQ,CAAS;QAEnD,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AALD,8BAKC;AAED;;GAEG;AACH,MAAa,eAAgB,SAAQ,eAAe;IACd;IAApC,YAAY,OAAe,EAAS,QAAgB;QAClD,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;QADF,aAAQ,GAAR,QAAQ,CAAQ;QAElD,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AALD,0CAKC;AAED;;GAEG;AACH,MAAa,SAAU,SAAQ,eAAe;IACR;IAApC,YAAY,OAAe,EAAS,SAAkC;QACpE,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QADK,cAAS,GAAT,SAAS,CAAyB;QAEpE,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AALD,8BAKC;AAED;;;;;;;;;;;GAWG;AACH,MAAa,WAAY,SAAQ,eAAe;IACD;IAA7C,YAAY,OAAe,EAAkB,QAAgB;QAC3D,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QADY,aAAQ,GAAR,QAAQ,CAAQ;QAE3D,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AALD,kCAKC;AAED;;;;;;;;;;;;GAYG;AACH,MAAa,QAAS,SAAQ,eAAe;IACE;IAAiC;IAA9E,YAAY,OAAe,EAAkB,OAAe,EAAkB,KAAe;QAC3F,KAAK,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QADe,YAAO,GAAP,OAAO,CAAQ;QAAkB,UAAK,GAAL,KAAK,CAAU;QAE3F,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF;AALD,4BAKC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './errors';
|
|
3
|
+
export * from './scanners';
|
|
4
|
+
export * from './utils/file-utils';
|
|
5
|
+
export * from './config';
|
|
6
|
+
export * from './config-validate';
|
|
7
|
+
export * from './baseline';
|
|
8
|
+
export { fingerprintForMatch } from './match-fingerprint';
|
|
9
|
+
export * from './scan-output';
|
|
10
|
+
export * from './diagnostics';
|
|
11
|
+
export { shannonEntropy, DEFAULT_ENTROPY_THRESHOLD } from './utils/entropy';
|
|
12
|
+
export { isPlaceholderSecret, isNonSecretConnectionString, isSampleJwt } from './utils/placeholder';
|
|
13
|
+
export { getGitStagedFilePaths, isInsideGitWorkTree } from './utils/git-utils';
|
|
14
|
+
export { validateRegexSafety, validateRegexLength, mapRegexSafetyReasonToDiagnosticCode, mapPatternRejectionReasonToDiagnosticCode, REGEX_REASON_TO_DIAGNOSTIC_CODE, REGEX_MAX_LENGTH, REGEX_MAX_QUANTIFIERS, } from './utils/regex-safety';
|
|
15
|
+
export { scanTextFileAsync, scanTextFileSync } from './utils/scan-file';
|
|
16
|
+
export { applyPathAwareSeverity, isTestFilePath } from './utils/path-severity';
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,2BAA2B,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oCAAoC,EACpC,yCAAyC,EACzC,+BAA+B,EAC/B,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.isTestFilePath = exports.applyPathAwareSeverity = exports.scanTextFileSync = exports.scanTextFileAsync = exports.REGEX_MAX_QUANTIFIERS = exports.REGEX_MAX_LENGTH = exports.REGEX_REASON_TO_DIAGNOSTIC_CODE = exports.mapPatternRejectionReasonToDiagnosticCode = exports.mapRegexSafetyReasonToDiagnosticCode = exports.validateRegexLength = exports.validateRegexSafety = exports.isInsideGitWorkTree = exports.getGitStagedFilePaths = exports.isSampleJwt = exports.isNonSecretConnectionString = exports.isPlaceholderSecret = exports.DEFAULT_ENTROPY_THRESHOLD = exports.shannonEntropy = exports.fingerprintForMatch = void 0;
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
19
|
+
__exportStar(require("./errors"), exports);
|
|
20
|
+
__exportStar(require("./scanners"), exports);
|
|
21
|
+
__exportStar(require("./utils/file-utils"), exports);
|
|
22
|
+
__exportStar(require("./config"), exports);
|
|
23
|
+
__exportStar(require("./config-validate"), exports);
|
|
24
|
+
__exportStar(require("./baseline"), exports);
|
|
25
|
+
var match_fingerprint_1 = require("./match-fingerprint");
|
|
26
|
+
Object.defineProperty(exports, "fingerprintForMatch", { enumerable: true, get: function () { return match_fingerprint_1.fingerprintForMatch; } });
|
|
27
|
+
__exportStar(require("./scan-output"), exports);
|
|
28
|
+
__exportStar(require("./diagnostics"), exports);
|
|
29
|
+
var entropy_1 = require("./utils/entropy");
|
|
30
|
+
Object.defineProperty(exports, "shannonEntropy", { enumerable: true, get: function () { return entropy_1.shannonEntropy; } });
|
|
31
|
+
Object.defineProperty(exports, "DEFAULT_ENTROPY_THRESHOLD", { enumerable: true, get: function () { return entropy_1.DEFAULT_ENTROPY_THRESHOLD; } });
|
|
32
|
+
var placeholder_1 = require("./utils/placeholder");
|
|
33
|
+
Object.defineProperty(exports, "isPlaceholderSecret", { enumerable: true, get: function () { return placeholder_1.isPlaceholderSecret; } });
|
|
34
|
+
Object.defineProperty(exports, "isNonSecretConnectionString", { enumerable: true, get: function () { return placeholder_1.isNonSecretConnectionString; } });
|
|
35
|
+
Object.defineProperty(exports, "isSampleJwt", { enumerable: true, get: function () { return placeholder_1.isSampleJwt; } });
|
|
36
|
+
var git_utils_1 = require("./utils/git-utils");
|
|
37
|
+
Object.defineProperty(exports, "getGitStagedFilePaths", { enumerable: true, get: function () { return git_utils_1.getGitStagedFilePaths; } });
|
|
38
|
+
Object.defineProperty(exports, "isInsideGitWorkTree", { enumerable: true, get: function () { return git_utils_1.isInsideGitWorkTree; } });
|
|
39
|
+
var regex_safety_1 = require("./utils/regex-safety");
|
|
40
|
+
Object.defineProperty(exports, "validateRegexSafety", { enumerable: true, get: function () { return regex_safety_1.validateRegexSafety; } });
|
|
41
|
+
Object.defineProperty(exports, "validateRegexLength", { enumerable: true, get: function () { return regex_safety_1.validateRegexLength; } });
|
|
42
|
+
Object.defineProperty(exports, "mapRegexSafetyReasonToDiagnosticCode", { enumerable: true, get: function () { return regex_safety_1.mapRegexSafetyReasonToDiagnosticCode; } });
|
|
43
|
+
Object.defineProperty(exports, "mapPatternRejectionReasonToDiagnosticCode", { enumerable: true, get: function () { return regex_safety_1.mapPatternRejectionReasonToDiagnosticCode; } });
|
|
44
|
+
Object.defineProperty(exports, "REGEX_REASON_TO_DIAGNOSTIC_CODE", { enumerable: true, get: function () { return regex_safety_1.REGEX_REASON_TO_DIAGNOSTIC_CODE; } });
|
|
45
|
+
Object.defineProperty(exports, "REGEX_MAX_LENGTH", { enumerable: true, get: function () { return regex_safety_1.REGEX_MAX_LENGTH; } });
|
|
46
|
+
Object.defineProperty(exports, "REGEX_MAX_QUANTIFIERS", { enumerable: true, get: function () { return regex_safety_1.REGEX_MAX_QUANTIFIERS; } });
|
|
47
|
+
var scan_file_1 = require("./utils/scan-file");
|
|
48
|
+
Object.defineProperty(exports, "scanTextFileAsync", { enumerable: true, get: function () { return scan_file_1.scanTextFileAsync; } });
|
|
49
|
+
Object.defineProperty(exports, "scanTextFileSync", { enumerable: true, get: function () { return scan_file_1.scanTextFileSync; } });
|
|
50
|
+
var path_severity_1 = require("./utils/path-severity");
|
|
51
|
+
Object.defineProperty(exports, "applyPathAwareSeverity", { enumerable: true, get: function () { return path_severity_1.applyPathAwareSeverity; } });
|
|
52
|
+
Object.defineProperty(exports, "isTestFilePath", { enumerable: true, get: function () { return path_severity_1.isTestFilePath; } });
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,2CAAyB;AACzB,6CAA2B;AAC3B,qDAAmC;AACnC,2CAAyB;AACzB,oDAAkC;AAClC,6CAA2B;AAC3B,yDAA0D;AAAjD,wHAAA,mBAAmB,OAAA;AAC5B,gDAA8B;AAC9B,gDAA8B;AAC9B,2CAA4E;AAAnE,yGAAA,cAAc,OAAA;AAAE,oHAAA,yBAAyB,OAAA;AAClD,mDAAoG;AAA3F,kHAAA,mBAAmB,OAAA;AAAE,0HAAA,2BAA2B,OAAA;AAAE,0GAAA,WAAW,OAAA;AACtE,+CAA+E;AAAtE,kHAAA,qBAAqB,OAAA;AAAE,gHAAA,mBAAmB,OAAA;AACnD,qDAQ8B;AAP5B,mHAAA,mBAAmB,OAAA;AACnB,mHAAA,mBAAmB,OAAA;AACnB,oIAAA,oCAAoC,OAAA;AACpC,yIAAA,yCAAyC,OAAA;AACzC,+HAAA,+BAA+B,OAAA;AAC/B,gHAAA,gBAAgB,OAAA;AAChB,qHAAA,qBAAqB,OAAA;AAGvB,+CAAwE;AAA/D,8GAAA,iBAAiB,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAC5C,uDAA+E;AAAtE,uHAAA,sBAAsB,OAAA;AAAE,+GAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SecretMatch } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Stable fingerprint for a match location + rule id (no raw secret material).
|
|
4
|
+
* Same inputs always yield the same hex digest (SHA-256).
|
|
5
|
+
*/
|
|
6
|
+
export declare function fingerprintForMatch(cwd: string | null, fileAbs: string, m: SecretMatch): string;
|
|
7
|
+
//# sourceMappingURL=match-fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match-fingerprint.d.ts","sourceRoot":"","sources":["../src/match-fingerprint.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAU3C;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,MAAM,CAI/F"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.fingerprintForMatch = fingerprintForMatch;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
function relativeFingerprintKey(file, cwd) {
|
|
10
|
+
if (cwd === null)
|
|
11
|
+
return file.split(path_1.default.sep).join('/');
|
|
12
|
+
if (!path_1.default.isAbsolute(file))
|
|
13
|
+
return file.split(path_1.default.sep).join('/');
|
|
14
|
+
const rel = path_1.default.relative(cwd, file);
|
|
15
|
+
if (rel.startsWith('..') || path_1.default.isAbsolute(rel))
|
|
16
|
+
return file.split(path_1.default.sep).join('/');
|
|
17
|
+
return (rel || '.').split(path_1.default.sep).join('/');
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Stable fingerprint for a match location + rule id (no raw secret material).
|
|
21
|
+
* Same inputs always yield the same hex digest (SHA-256).
|
|
22
|
+
*/
|
|
23
|
+
function fingerprintForMatch(cwd, fileAbs, m) {
|
|
24
|
+
const relKey = relativeFingerprintKey(fileAbs, cwd);
|
|
25
|
+
const payload = `${relKey}|${m.type}|${m.line}|${m.column}|${m.matchLength}`;
|
|
26
|
+
return (0, crypto_1.createHash)('sha256').update(payload, 'utf8').digest('hex');
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=match-fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"match-fingerprint.js","sourceRoot":"","sources":["../src/match-fingerprint.ts"],"names":[],"mappings":";;;;;AAgBA,kDAIC;AApBD,gDAAwB;AACxB,mCAAoC;AAGpC,SAAS,sBAAsB,CAAC,IAAY,EAAE,GAAkB;IAC9D,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxD,IAAI,CAAC,cAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,cAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACrC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,cAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC;AAED;;;GAGG;AACH,SAAgB,mBAAmB,CAAC,GAAkB,EAAE,OAAe,EAAE,CAAc;IACrF,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,GAAG,MAAM,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7E,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SecretMatch } from './types';
|
|
2
|
+
import type { Diagnostic } from './diagnostics';
|
|
3
|
+
/** One file's scan outcome — shared by CLI, MCP, and SARIF/JSON formatters. */
|
|
4
|
+
export interface FileScanResult {
|
|
5
|
+
file: string;
|
|
6
|
+
matches: SecretMatch[];
|
|
7
|
+
}
|
|
8
|
+
/** Optional machine-readable scan run metadata (JSON + SARIF driver properties). */
|
|
9
|
+
export interface JsonRunMetadata {
|
|
10
|
+
duration_ms: number;
|
|
11
|
+
/** Files opened and scanned for secrets (excludes skipped binaries). */
|
|
12
|
+
files_scanned: number;
|
|
13
|
+
/** Total bytes read from disk for those scans (capped at per-file read limit when streaming). */
|
|
14
|
+
bytes_scanned: number;
|
|
15
|
+
/** Active regex rules after config (built-ins minus "off", plus accepted extra_patterns). */
|
|
16
|
+
patterns_active: number;
|
|
17
|
+
diagnostics_count?: number;
|
|
18
|
+
/** Matches removed because they appeared in `.vault-guard.baseline.json`. */
|
|
19
|
+
baseline_suppressed?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface JsonOutput {
|
|
22
|
+
version: string;
|
|
23
|
+
scannedAt: string;
|
|
24
|
+
summary: {
|
|
25
|
+
files: number;
|
|
26
|
+
secrets: number;
|
|
27
|
+
};
|
|
28
|
+
/** Present when the caller passes {@link FormatOptions.run}. */
|
|
29
|
+
run?: JsonRunMetadata;
|
|
30
|
+
results: Array<{
|
|
31
|
+
file: string;
|
|
32
|
+
matches: Array<{
|
|
33
|
+
type: string;
|
|
34
|
+
severity: string;
|
|
35
|
+
line: number;
|
|
36
|
+
column: number;
|
|
37
|
+
/** Redacted form, e.g. `sk-a…(37c)`. Never the raw secret. */
|
|
38
|
+
value: string;
|
|
39
|
+
/** SHA-256 hex of `relPath|type|line|column|matchLength` for baselines (no raw secret). */
|
|
40
|
+
fingerprint: string;
|
|
41
|
+
}>;
|
|
42
|
+
}>;
|
|
43
|
+
/** Non-fatal scan warnings (skipped files, rejected patterns, git issues). */
|
|
44
|
+
diagnostics?: Array<{
|
|
45
|
+
code: string;
|
|
46
|
+
severity: string;
|
|
47
|
+
ctx: Record<string, unknown>;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
export interface FormatOptions {
|
|
51
|
+
/**
|
|
52
|
+
* Base directory to render `file` paths relative to.
|
|
53
|
+
* Defaults to `process.cwd()`. Files outside this root are kept absolute.
|
|
54
|
+
* Pass `null` to skip relativization entirely.
|
|
55
|
+
*/
|
|
56
|
+
cwd?: string | null;
|
|
57
|
+
/** Non-fatal diagnostics to include in structured output. */
|
|
58
|
+
diagnostics?: Diagnostic[];
|
|
59
|
+
/** Scan timing / coverage stats for JSON and SARIF `runs[].properties`. */
|
|
60
|
+
run?: JsonRunMetadata;
|
|
61
|
+
}
|
|
62
|
+
export declare function formatJson(results: FileScanResult[], opts?: FormatOptions): string;
|
|
63
|
+
/** SARIF 2.1.0 — compatible with GitHub Code Scanning (upload-sarif action). */
|
|
64
|
+
export declare function formatSarif(results: FileScanResult[], opts?: FormatOptions): string;
|
|
65
|
+
//# sourceMappingURL=scan-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-output.d.ts","sourceRoot":"","sources":["../src/scan-output.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAGhD,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,iGAAiG;IACjG,aAAa,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5C,gEAAgE;IAChE,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,KAAK,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,QAAQ,EAAE,MAAM,CAAC;YACjB,IAAI,EAAE,MAAM,CAAC;YACb,MAAM,EAAE,MAAM,CAAC;YACf,8DAA8D;YAC9D,KAAK,EAAE,MAAM,CAAC;YACd,2FAA2F;YAC3F,WAAW,EAAE,MAAM,CAAC;SACrB,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,8EAA8E;IAC9E,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC9B,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,6DAA6D;IAC7D,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,2EAA2E;IAC3E,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAmBD,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CA8BtF;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,EAAE,EAAE,IAAI,GAAE,aAAkB,GAAG,MAAM,CAuFvF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.formatJson = formatJson;
|
|
7
|
+
exports.formatSarif = formatSarif;
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const match_fingerprint_1 = require("./match-fingerprint");
|
|
10
|
+
/**
|
|
11
|
+
* Normalize a file path for output: cwd-relative when inside `cwd`, absolute
|
|
12
|
+
* otherwise (so we never emit `../../..` traversals).
|
|
13
|
+
*
|
|
14
|
+
* Why this matters: absolute paths in JSON / SARIF leak the developer's home
|
|
15
|
+
* directory and OS username when the output is shared (PR comments, GitHub
|
|
16
|
+
* Code Scanning UI, support tickets, screenshots).
|
|
17
|
+
*/
|
|
18
|
+
function normalizeFilePath(file, cwd) {
|
|
19
|
+
if (cwd === null)
|
|
20
|
+
return file;
|
|
21
|
+
const base = cwd ?? process.cwd();
|
|
22
|
+
if (!path_1.default.isAbsolute(file))
|
|
23
|
+
return file;
|
|
24
|
+
const rel = path_1.default.relative(base, file);
|
|
25
|
+
if (rel.startsWith('..') || path_1.default.isAbsolute(rel))
|
|
26
|
+
return file;
|
|
27
|
+
return rel || '.';
|
|
28
|
+
}
|
|
29
|
+
function formatJson(results, opts = {}) {
|
|
30
|
+
const fpCwd = opts.cwd === undefined ? process.cwd() : opts.cwd;
|
|
31
|
+
const output = {
|
|
32
|
+
version: '1',
|
|
33
|
+
scannedAt: new Date().toISOString(),
|
|
34
|
+
summary: {
|
|
35
|
+
files: results.length,
|
|
36
|
+
secrets: results.reduce((n, r) => n + r.matches.length, 0),
|
|
37
|
+
},
|
|
38
|
+
...(opts.run ? { run: opts.run } : {}),
|
|
39
|
+
results: results.map(({ file, matches }) => ({
|
|
40
|
+
file: normalizeFilePath(file, opts.cwd),
|
|
41
|
+
matches: matches.map(m => ({
|
|
42
|
+
type: m.type,
|
|
43
|
+
severity: m.severity,
|
|
44
|
+
line: m.line,
|
|
45
|
+
column: m.column,
|
|
46
|
+
value: m.value,
|
|
47
|
+
fingerprint: (0, match_fingerprint_1.fingerprintForMatch)(fpCwd, file, m),
|
|
48
|
+
})),
|
|
49
|
+
})),
|
|
50
|
+
};
|
|
51
|
+
if (opts.diagnostics && opts.diagnostics.length > 0) {
|
|
52
|
+
output.diagnostics = opts.diagnostics.map(d => ({
|
|
53
|
+
code: d.code,
|
|
54
|
+
severity: d.severity,
|
|
55
|
+
ctx: d.ctx,
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
return JSON.stringify(output, null, 2);
|
|
59
|
+
}
|
|
60
|
+
/** SARIF 2.1.0 — compatible with GitHub Code Scanning (upload-sarif action). */
|
|
61
|
+
function formatSarif(results, opts = {}) {
|
|
62
|
+
const rules = [
|
|
63
|
+
...new Set(results.flatMap(r => r.matches.map(m => m.type))),
|
|
64
|
+
].map(id => ({
|
|
65
|
+
id,
|
|
66
|
+
name: id
|
|
67
|
+
.split(/[-_]/)
|
|
68
|
+
.map(p => p.charAt(0).toUpperCase() + p.slice(1))
|
|
69
|
+
.join(''),
|
|
70
|
+
shortDescription: { text: `Secret detected: ${id}` },
|
|
71
|
+
helpUri: `https://github.com/vaultcompasshq/vault-guard/blob/main/docs/rules/${id}.md`,
|
|
72
|
+
properties: { tags: ['security', 'secrets'] },
|
|
73
|
+
}));
|
|
74
|
+
const sarifResults = results.flatMap(({ file, matches }) => matches.map(m => ({
|
|
75
|
+
ruleId: m.type,
|
|
76
|
+
level: m.severity === 'critical' ? 'error' : m.severity === 'high' ? 'warning' : 'note',
|
|
77
|
+
// Intentionally do NOT include the masked value here. Reviewers have the
|
|
78
|
+
// exact byte region (startLine/startColumn/endColumn) and the rule id;
|
|
79
|
+
// the masked prefix adds no signal and grows the leak surface area.
|
|
80
|
+
message: { text: `Possible secret of type '${m.type}'` },
|
|
81
|
+
locations: [
|
|
82
|
+
{
|
|
83
|
+
physicalLocation: {
|
|
84
|
+
artifactLocation: { uri: normalizeFilePath(file, opts.cwd), uriBaseId: '%SRCROOT%' },
|
|
85
|
+
region: {
|
|
86
|
+
startLine: m.line,
|
|
87
|
+
startColumn: m.column + 1,
|
|
88
|
+
endColumn: m.column + m.matchLength + 1,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
})));
|
|
94
|
+
// Diagnostics are emitted as SARIF notifications (tool/driver/notifications)
|
|
95
|
+
// so they appear in the GitHub Code Scanning UI as tool warnings rather than
|
|
96
|
+
// results. This keeps the results array clean for triage.
|
|
97
|
+
const notifications = opts.diagnostics && opts.diagnostics.length > 0
|
|
98
|
+
? opts.diagnostics.map(d => ({
|
|
99
|
+
id: d.code,
|
|
100
|
+
level: d.severity === 'error' ? 'error' : 'warning',
|
|
101
|
+
message: { text: `${d.code}: ${JSON.stringify(d.ctx)}` },
|
|
102
|
+
}))
|
|
103
|
+
: undefined;
|
|
104
|
+
const runProps = opts.run !== undefined
|
|
105
|
+
? {
|
|
106
|
+
vault_guard_run: {
|
|
107
|
+
duration_ms: opts.run.duration_ms,
|
|
108
|
+
files_scanned: opts.run.files_scanned,
|
|
109
|
+
bytes_scanned: opts.run.bytes_scanned,
|
|
110
|
+
patterns_active: opts.run.patterns_active,
|
|
111
|
+
...(opts.run.diagnostics_count !== undefined
|
|
112
|
+
? { diagnostics_count: opts.run.diagnostics_count }
|
|
113
|
+
: {}),
|
|
114
|
+
...(opts.run.baseline_suppressed !== undefined
|
|
115
|
+
? { baseline_suppressed: opts.run.baseline_suppressed }
|
|
116
|
+
: {}),
|
|
117
|
+
},
|
|
118
|
+
}
|
|
119
|
+
: undefined;
|
|
120
|
+
const sarif = {
|
|
121
|
+
$schema: 'https://json.schemastore.org/sarif-2.1.0',
|
|
122
|
+
version: '2.1.0',
|
|
123
|
+
runs: [
|
|
124
|
+
{
|
|
125
|
+
...(runProps ? { properties: runProps } : {}),
|
|
126
|
+
tool: {
|
|
127
|
+
driver: {
|
|
128
|
+
name: 'vault-guard',
|
|
129
|
+
informationUri: 'https://github.com/vaultcompasshq/vault-guard',
|
|
130
|
+
rules,
|
|
131
|
+
...(notifications ? { notifications } : {}),
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
results: sarifResults,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
return JSON.stringify(sarif, null, 2);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=scan-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan-output.js","sourceRoot":"","sources":["../src/scan-output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanners/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("../types"), exports);
|
|
18
|
+
__exportStar(require("./secret-scanner"), exports);
|
|
19
|
+
__exportStar(require("./token-counter"), exports);
|
|
20
|
+
__exportStar(require("./pre-commit-hook"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanners/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,mDAAiC;AACjC,kDAAgC;AAChC,oDAAkC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type HookManager = 'native' | 'husky' | 'lefthook' | 'precommit';
|
|
2
|
+
export interface InstallHookOptions {
|
|
3
|
+
manager?: HookManager;
|
|
4
|
+
/** Working directory (git repo root). Defaults to `process.cwd()`. */
|
|
5
|
+
cwd?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class PreCommitHook {
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the directory where Git expects the \`pre-commit\` executable.
|
|
10
|
+
* Honors \`core.hooksPath\` (local then global). Relative paths are resolved
|
|
11
|
+
* against the **.git** directory, per Git documentation.
|
|
12
|
+
*/
|
|
13
|
+
getEffectiveHooksDir(cwd: string): {
|
|
14
|
+
hooksDir: string;
|
|
15
|
+
viaHooksPath: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Absolute path to the \`pre-commit\` hook file for the given manager.
|
|
19
|
+
*/
|
|
20
|
+
getPreCommitHookPath(cwd: string, manager?: HookManager): string;
|
|
21
|
+
install(options?: InstallHookOptions): {
|
|
22
|
+
success: boolean;
|
|
23
|
+
message: string;
|
|
24
|
+
hookPath?: string;
|
|
25
|
+
};
|
|
26
|
+
uninstall(options?: InstallHookOptions): {
|
|
27
|
+
success: boolean;
|
|
28
|
+
message: string;
|
|
29
|
+
};
|
|
30
|
+
isInstalled(options?: InstallHookOptions): boolean;
|
|
31
|
+
private installNative;
|
|
32
|
+
private uninstallNative;
|
|
33
|
+
private installHusky;
|
|
34
|
+
private uninstallHusky;
|
|
35
|
+
private installLefthook;
|
|
36
|
+
private uninstallLefthook;
|
|
37
|
+
private installPreCommitFramework;
|
|
38
|
+
private uninstallPreCommitFramework;
|
|
39
|
+
private resolveGitDir;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=pre-commit-hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-commit-hook.d.ts","sourceRoot":"","sources":["../../src/scanners/pre-commit-hook.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAExE,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAqED,qBAAa,aAAa;IACxB;;;;OAIG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE;IA4B9E;;OAEG;IACH,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAsB,GAAG,MAAM;IAO1E,OAAO,CAAC,OAAO,GAAE,kBAAuB,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE;IAsBnG,SAAS,CAAC,OAAO,GAAE,kBAAuB,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAsBlF,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO;IActD,OAAO,CAAC,aAAa;IAiCrB,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,YAAY;IAqCpB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,eAAe;IA2BvB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,yBAAyB;IA4BjC,OAAO,CAAC,2BAA2B;IAyBnC,OAAO,CAAC,aAAa;CAYtB"}
|