@securitychecks/cli 0.1.1-rc.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/LICENSE +87 -0
- package/README.md +207 -0
- package/bin/scheck.js +17 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7254 -0
- package/dist/index.js.map +1 -0
- package/dist/lib.d.ts +908 -0
- package/dist/lib.js +2187 -0
- package/dist/lib.js.map +1 -0
- package/package.json +67 -0
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1,908 @@
|
|
|
1
|
+
import { AuditResult, Finding, CollectorArtifact, Severity, CheckResult, Artifact } from '@securitychecks/collector';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Audit API - Programmatic interface for running the staff check
|
|
5
|
+
*
|
|
6
|
+
* This module provides the core audit functionality that can be used by:
|
|
7
|
+
* - CLI commands
|
|
8
|
+
* - MCP server
|
|
9
|
+
* - Programmatic integration
|
|
10
|
+
*
|
|
11
|
+
* SECURITY NOTE: All audit functions require cloud API authentication.
|
|
12
|
+
* Detection logic runs server-side to protect IP.
|
|
13
|
+
* See: docs/POST_MORTEM_001_ENGINE_EXPOSURE.md
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
interface AuditOptions {
|
|
17
|
+
/** Target path to audit (default: current directory) */
|
|
18
|
+
targetPath?: string;
|
|
19
|
+
/** Only run specific invariant checks by ID */
|
|
20
|
+
only?: string[];
|
|
21
|
+
/** Skip specific invariant checks by ID */
|
|
22
|
+
skip?: string[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Run the full staff check audit
|
|
26
|
+
*
|
|
27
|
+
* This is the main programmatic API for running the staff check.
|
|
28
|
+
* It performs two steps:
|
|
29
|
+
* 1. Collect artifacts from the target codebase (facts)
|
|
30
|
+
* 2. Send to cloud API for evaluation (findings)
|
|
31
|
+
*
|
|
32
|
+
* SECURITY: Detection logic runs server-side to protect IP.
|
|
33
|
+
* An API key is required. Get one at https://securitychecks.ai/dashboard/settings/api-keys
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { audit } from '@securitychecks/cli';
|
|
38
|
+
*
|
|
39
|
+
* // Requires SECURITYCHECKS_API_KEY environment variable
|
|
40
|
+
* const result = await audit({
|
|
41
|
+
* targetPath: '/path/to/codebase',
|
|
42
|
+
* only: ['WEBHOOK.IDEMPOTENT'],
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* console.log(result.summary);
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
declare function audit(options?: AuditOptions): Promise<AuditResult>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Schema Version Compatibility
|
|
52
|
+
*
|
|
53
|
+
* Ensures CLI can consume artifacts from compatible collector versions.
|
|
54
|
+
*
|
|
55
|
+
* The schema version follows semver:
|
|
56
|
+
* - MAJOR: Breaking changes (fields removed, types changed)
|
|
57
|
+
* - MINOR: Additive changes (new optional fields)
|
|
58
|
+
* - PATCH: Bug fixes, clarifications
|
|
59
|
+
*
|
|
60
|
+
* CLI declares a supported range, collector emits current version.
|
|
61
|
+
*/
|
|
62
|
+
/**
|
|
63
|
+
* The schema version range this CLI version supports.
|
|
64
|
+
*
|
|
65
|
+
* Format: "^MAJOR.MINOR.x" - compatible with any version that has:
|
|
66
|
+
* - Same MAJOR version (no breaking changes)
|
|
67
|
+
* - Same or higher MINOR version (may have new optional fields)
|
|
68
|
+
*
|
|
69
|
+
* When updating:
|
|
70
|
+
* - Bump MINOR when CLI starts using new optional fields
|
|
71
|
+
* - Bump MAJOR when CLI requires breaking schema changes
|
|
72
|
+
*/
|
|
73
|
+
declare const SUPPORTED_SCHEMA_RANGE: {
|
|
74
|
+
minMajor: number;
|
|
75
|
+
minMinor: number;
|
|
76
|
+
maxMajor: number;
|
|
77
|
+
};
|
|
78
|
+
interface SchemaValidationResult {
|
|
79
|
+
valid: boolean;
|
|
80
|
+
artifactVersion: string;
|
|
81
|
+
currentVersion: string;
|
|
82
|
+
error?: string;
|
|
83
|
+
remediation?: string;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Validate that an artifact's schema version is compatible with this CLI.
|
|
87
|
+
*
|
|
88
|
+
* Compatibility rules:
|
|
89
|
+
* - Artifact MAJOR must equal CLI's supported MAJOR (breaking changes)
|
|
90
|
+
* - Artifact MINOR must be >= CLI's minMinor (additive features)
|
|
91
|
+
* - Pre-1.0.0 artifacts (missing schemaVersion) are assumed "1.0.0"
|
|
92
|
+
*/
|
|
93
|
+
declare function validateSchemaVersion(artifactSchemaVersion?: string): SchemaValidationResult;
|
|
94
|
+
/**
|
|
95
|
+
* Get the current collector schema version
|
|
96
|
+
*/
|
|
97
|
+
declare function getCurrentSchemaVersion(): string;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Deterministic Error Codes for SecurityChecks CLI
|
|
101
|
+
*
|
|
102
|
+
* Format: SC_<CATEGORY>_<NUMBER>
|
|
103
|
+
*
|
|
104
|
+
* Categories:
|
|
105
|
+
* - CONFIG: Configuration errors
|
|
106
|
+
* - PARSE: Parsing/syntax errors
|
|
107
|
+
* - CHECK: Checker execution errors
|
|
108
|
+
* - IO: File system / network errors
|
|
109
|
+
* - CLI: Command line argument errors
|
|
110
|
+
*/
|
|
111
|
+
declare const ErrorCodes: {
|
|
112
|
+
readonly CONFIG_NOT_FOUND: "SC_CONFIG_001";
|
|
113
|
+
readonly CONFIG_INVALID: "SC_CONFIG_002";
|
|
114
|
+
readonly CONFIG_SCHEMA_ERROR: "SC_CONFIG_003";
|
|
115
|
+
readonly PARSE_TYPESCRIPT_ERROR: "SC_PARSE_101";
|
|
116
|
+
readonly PARSE_FILE_NOT_FOUND: "SC_PARSE_102";
|
|
117
|
+
readonly PARSE_UNSUPPORTED_SYNTAX: "SC_PARSE_103";
|
|
118
|
+
readonly CHECK_EXECUTION_ERROR: "SC_CHECK_201";
|
|
119
|
+
readonly CHECK_TIMEOUT: "SC_CHECK_202";
|
|
120
|
+
readonly CHECK_INVARIANT_NOT_FOUND: "SC_CHECK_203";
|
|
121
|
+
readonly IO_READ_ERROR: "SC_IO_301";
|
|
122
|
+
readonly IO_WRITE_ERROR: "SC_IO_302";
|
|
123
|
+
readonly IO_PERMISSION_DENIED: "SC_IO_303";
|
|
124
|
+
readonly IO_PATH_NOT_FOUND: "SC_IO_304";
|
|
125
|
+
readonly CLI_INVALID_ARGUMENT: "SC_CLI_401";
|
|
126
|
+
readonly CLI_MISSING_ARGUMENT: "SC_CLI_402";
|
|
127
|
+
readonly CLI_UNKNOWN_COMMAND: "SC_CLI_403";
|
|
128
|
+
readonly ARTIFACT_NOT_FOUND: "SC_ARTIFACT_501";
|
|
129
|
+
readonly ARTIFACT_INVALID: "SC_ARTIFACT_502";
|
|
130
|
+
readonly ARTIFACT_VERSION_MISMATCH: "SC_ARTIFACT_503";
|
|
131
|
+
readonly CLOUD_AUTH_FAILED: "SC_CLOUD_601";
|
|
132
|
+
readonly CLOUD_PERMISSION_DENIED: "SC_CLOUD_602";
|
|
133
|
+
readonly CLOUD_NOT_FOUND: "SC_CLOUD_603";
|
|
134
|
+
readonly CLOUD_RATE_LIMITED: "SC_CLOUD_604";
|
|
135
|
+
readonly CLOUD_API_ERROR: "SC_CLOUD_605";
|
|
136
|
+
readonly CLOUD_NETWORK_ERROR: "SC_CLOUD_606";
|
|
137
|
+
readonly CLOUD_INVALID_API_KEY: "SC_CLOUD_607";
|
|
138
|
+
readonly AUTH_REQUIRED: "SC_CLOUD_608";
|
|
139
|
+
readonly OFFLINE_NOT_SUPPORTED: "SC_CLOUD_609";
|
|
140
|
+
};
|
|
141
|
+
type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];
|
|
142
|
+
/**
|
|
143
|
+
* User-friendly error messages for each error code
|
|
144
|
+
*/
|
|
145
|
+
declare const ErrorMessages: Record<ErrorCode, string>;
|
|
146
|
+
/**
|
|
147
|
+
* Remediation guidance for each error code
|
|
148
|
+
* Helps users understand what to do when they encounter an error.
|
|
149
|
+
*/
|
|
150
|
+
declare const ErrorRemediation: Record<ErrorCode, string>;
|
|
151
|
+
/**
|
|
152
|
+
* Structured CLI Error with deterministic error code
|
|
153
|
+
*/
|
|
154
|
+
declare class CLIError extends Error {
|
|
155
|
+
readonly code: ErrorCode;
|
|
156
|
+
readonly details?: unknown;
|
|
157
|
+
readonly cause?: Error;
|
|
158
|
+
constructor(code: ErrorCode, message?: string, options?: {
|
|
159
|
+
details?: unknown;
|
|
160
|
+
cause?: Error;
|
|
161
|
+
});
|
|
162
|
+
/**
|
|
163
|
+
* Get remediation guidance for this error
|
|
164
|
+
*/
|
|
165
|
+
getRemediation(): string;
|
|
166
|
+
/**
|
|
167
|
+
* Format error for user display
|
|
168
|
+
*/
|
|
169
|
+
toUserString(verbose?: boolean): string;
|
|
170
|
+
/**
|
|
171
|
+
* Format error with remediation for user display
|
|
172
|
+
*/
|
|
173
|
+
toUserStringWithRemediation(): string;
|
|
174
|
+
/**
|
|
175
|
+
* Format error for JSON output
|
|
176
|
+
*/
|
|
177
|
+
toJSON(): Record<string, unknown>;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Check if an error is a CLIError
|
|
181
|
+
*/
|
|
182
|
+
declare function isCLIError(error: unknown): error is CLIError;
|
|
183
|
+
/**
|
|
184
|
+
* Wrap an unknown error in a CLIError
|
|
185
|
+
*/
|
|
186
|
+
declare function wrapError(error: unknown, code: ErrorCode, message?: string): CLIError;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* CI Environment Detection
|
|
190
|
+
*
|
|
191
|
+
* Detects CI/CD environment and extracts relevant context
|
|
192
|
+
* (branch, commit SHA, PR number) for proper scan association.
|
|
193
|
+
*/
|
|
194
|
+
interface CIContext {
|
|
195
|
+
/** CI provider name */
|
|
196
|
+
provider: 'github-actions' | 'gitlab-ci' | 'circleci' | 'jenkins' | 'unknown';
|
|
197
|
+
/** Git branch name */
|
|
198
|
+
branch?: string;
|
|
199
|
+
/** Git commit SHA */
|
|
200
|
+
commitSha?: string;
|
|
201
|
+
/** Pull/Merge request number */
|
|
202
|
+
prNumber?: number;
|
|
203
|
+
/** Repository name (owner/repo) */
|
|
204
|
+
repository?: string;
|
|
205
|
+
/** Whether this is a PR/MR event */
|
|
206
|
+
isPullRequest: boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Cloud Evaluation Client
|
|
211
|
+
*
|
|
212
|
+
* Sends artifacts to the cloud API for async server-side evaluation.
|
|
213
|
+
* Artifacts are stored in R2 and processed by Fly.io workers.
|
|
214
|
+
*
|
|
215
|
+
* Architecture:
|
|
216
|
+
* 1. CLI collects artifact locally (code never leaves)
|
|
217
|
+
* 2. Artifact sent to /api/v1/evaluate, stored in R2
|
|
218
|
+
* 3. Server queues QStash job for Fly.io worker
|
|
219
|
+
* 4. CLI polls /api/v1/scans/{id} until complete
|
|
220
|
+
* 5. Findings returned to CLI for display
|
|
221
|
+
*/
|
|
222
|
+
|
|
223
|
+
interface CloudEvaluateOptions {
|
|
224
|
+
/** API key for authentication */
|
|
225
|
+
apiKey: string;
|
|
226
|
+
/** Cloud API base URL */
|
|
227
|
+
baseUrl: string;
|
|
228
|
+
/** Specific invariants to run (default: all) */
|
|
229
|
+
invariants?: string[];
|
|
230
|
+
/** Invariants to skip */
|
|
231
|
+
skip?: string[];
|
|
232
|
+
/** Minimum severity to return */
|
|
233
|
+
severity?: 'P0' | 'P1' | 'P2';
|
|
234
|
+
/** Project slug for scan association */
|
|
235
|
+
projectSlug?: string;
|
|
236
|
+
/** Timeout in ms (default: 300000 = 5 min) */
|
|
237
|
+
timeout?: number;
|
|
238
|
+
/** Poll interval in ms (default: 2000 = 2s) */
|
|
239
|
+
pollInterval?: number;
|
|
240
|
+
/** Progress callback */
|
|
241
|
+
onProgress?: EvaluationProgressCallback;
|
|
242
|
+
/** CI context (auto-detected if not provided) */
|
|
243
|
+
ciContext?: CIContext | null;
|
|
244
|
+
}
|
|
245
|
+
interface CloudEvaluateResult {
|
|
246
|
+
findings: Finding[];
|
|
247
|
+
stats: {
|
|
248
|
+
invariantsRun: number;
|
|
249
|
+
patternsRun: number;
|
|
250
|
+
findingsCount: number;
|
|
251
|
+
executionMs: number;
|
|
252
|
+
};
|
|
253
|
+
usage: {
|
|
254
|
+
scansUsed: number;
|
|
255
|
+
scansRemaining: number;
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/** Scan status from API */
|
|
259
|
+
type ScanStatus = 'PENDING' | 'RUNNING' | 'COMPLETED' | 'FAILED' | 'CANCELLED';
|
|
260
|
+
/** Progress callback for evaluation */
|
|
261
|
+
type EvaluationProgressCallback = (info: {
|
|
262
|
+
status: ScanStatus;
|
|
263
|
+
message?: string;
|
|
264
|
+
}) => void;
|
|
265
|
+
/**
|
|
266
|
+
* Check if cloud evaluation is available
|
|
267
|
+
*/
|
|
268
|
+
declare function isCloudEvalAvailable(apiKey?: string): boolean;
|
|
269
|
+
/**
|
|
270
|
+
* Evaluate artifact via cloud API (async with polling)
|
|
271
|
+
*
|
|
272
|
+
* @param artifact The artifact to evaluate
|
|
273
|
+
* @param options Evaluation options
|
|
274
|
+
* @throws Error if evaluation fails or times out
|
|
275
|
+
*/
|
|
276
|
+
declare function evaluateCloud(artifact: CollectorArtifact, options: CloudEvaluateOptions): Promise<CloudEvaluateResult>;
|
|
277
|
+
/**
|
|
278
|
+
* Check cloud API health
|
|
279
|
+
*/
|
|
280
|
+
declare function checkCloudHealth(baseUrl: string): Promise<boolean>;
|
|
281
|
+
/**
|
|
282
|
+
* Get available invariants from cloud API
|
|
283
|
+
*/
|
|
284
|
+
declare function getCloudInvariants(baseUrl: string, apiKey: string): Promise<Array<{
|
|
285
|
+
id: string;
|
|
286
|
+
name: string;
|
|
287
|
+
description: string;
|
|
288
|
+
severity: string;
|
|
289
|
+
}>>;
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Stable Finding ID Generation
|
|
293
|
+
*
|
|
294
|
+
* Generates deterministic, stable IDs for findings that survive:
|
|
295
|
+
* - Re-runs
|
|
296
|
+
* - Ordering changes
|
|
297
|
+
* - Remediation/message tweaks
|
|
298
|
+
* - Minor code refactors
|
|
299
|
+
*
|
|
300
|
+
* IDs are NOT stable across:
|
|
301
|
+
* - Moving code to different files
|
|
302
|
+
* - Renaming functions (these are legitimately different anchors)
|
|
303
|
+
*
|
|
304
|
+
* Format: `${invariantId}:${hash}` (e.g., WEBHOOK.IDEMPOTENT:9c31f0a2b4d1)
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Extract the identity payload for a finding.
|
|
309
|
+
* This is what gets hashed to produce the findingId.
|
|
310
|
+
*/
|
|
311
|
+
declare function extractIdentityPayload(finding: Finding): Record<string, string>;
|
|
312
|
+
/**
|
|
313
|
+
* Generate a stable findingId for a finding.
|
|
314
|
+
*
|
|
315
|
+
* @example
|
|
316
|
+
* const id = generateFindingId(finding);
|
|
317
|
+
* // "WEBHOOK.IDEMPOTENT:9c31f0a2b4d1"
|
|
318
|
+
*/
|
|
319
|
+
declare function generateFindingId(finding: Finding): string;
|
|
320
|
+
/**
|
|
321
|
+
* Add findingId to a finding (mutates the finding).
|
|
322
|
+
* Returns the same finding for chaining.
|
|
323
|
+
*/
|
|
324
|
+
declare function attachFindingId<T extends Finding>(finding: T): T & {
|
|
325
|
+
findingId: string;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* Add findingIds to all findings in a list.
|
|
329
|
+
*/
|
|
330
|
+
declare function attachFindingIds<T extends Finding>(findings: T[]): (T & {
|
|
331
|
+
findingId: string;
|
|
332
|
+
})[];
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Baseline and Waiver Schema Versions
|
|
336
|
+
*
|
|
337
|
+
* These versions are CLI-level (separate from collector artifact schema).
|
|
338
|
+
* Bump these when the storage format changes.
|
|
339
|
+
*/
|
|
340
|
+
declare const BASELINE_SCHEMA_VERSION = "1.0.0";
|
|
341
|
+
declare const WAIVER_SCHEMA_VERSION = "1.1.0";
|
|
342
|
+
declare const WAIVER_REASON_KEYS: readonly ["false_positive", "acceptable_risk", "will_fix_later", "not_applicable", "other"];
|
|
343
|
+
type WaiverReasonKey = typeof WAIVER_REASON_KEYS[number];
|
|
344
|
+
/**
|
|
345
|
+
* A baseline entry represents a known finding that should not fail CI.
|
|
346
|
+
* Baselines are used to adopt scheck incrementally on existing codebases.
|
|
347
|
+
*/
|
|
348
|
+
interface BaselineEntry {
|
|
349
|
+
/** Stable finding ID (invariantId:hash) */
|
|
350
|
+
findingId: string;
|
|
351
|
+
/** The invariant this finding belongs to */
|
|
352
|
+
invariantId: string;
|
|
353
|
+
/** File where the finding was detected */
|
|
354
|
+
file: string;
|
|
355
|
+
/** Symbol (function/class name) if available */
|
|
356
|
+
symbol?: string;
|
|
357
|
+
/** When this was first added to baseline */
|
|
358
|
+
createdAt: string;
|
|
359
|
+
/** When this was last seen in a run */
|
|
360
|
+
lastSeenAt: string;
|
|
361
|
+
/** Optional notes explaining why this is baselined */
|
|
362
|
+
notes?: string;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* The baseline file format.
|
|
366
|
+
*/
|
|
367
|
+
interface BaselineFile {
|
|
368
|
+
/** Schema version for baseline file format */
|
|
369
|
+
schemaVersion: string;
|
|
370
|
+
/** CLI version that generated this file */
|
|
371
|
+
toolVersion: string;
|
|
372
|
+
/** Collector schema version used when generating findings */
|
|
373
|
+
collectorSchemaVersion?: string;
|
|
374
|
+
/** Tool identifier (e.g., "@securitychecks/cli@0.1.0") */
|
|
375
|
+
generatedBy: string;
|
|
376
|
+
/** When the baseline was last updated (UTC ISO date) */
|
|
377
|
+
updatedAt: string;
|
|
378
|
+
/** Baseline entries keyed by findingId for O(1) lookup */
|
|
379
|
+
entries: Record<string, BaselineEntry>;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* A waiver temporarily suppresses a finding.
|
|
383
|
+
* Unlike baselines, waivers expire and require explicit justification.
|
|
384
|
+
*/
|
|
385
|
+
interface WaiverEntry {
|
|
386
|
+
/** Stable finding ID (invariantId:hash) */
|
|
387
|
+
findingId: string;
|
|
388
|
+
/** The invariant this waiver applies to */
|
|
389
|
+
invariantId: string;
|
|
390
|
+
/** File where the finding was detected */
|
|
391
|
+
file: string;
|
|
392
|
+
/** Symbol (function/class name) if available */
|
|
393
|
+
symbol?: string;
|
|
394
|
+
/** Structured waiver reason (optional; aligns with web UI) */
|
|
395
|
+
reasonKey?: WaiverReasonKey;
|
|
396
|
+
/** Why this is being waived (required) */
|
|
397
|
+
reason: string;
|
|
398
|
+
/** Who created the waiver */
|
|
399
|
+
owner: string;
|
|
400
|
+
/** When the waiver expires (ISO date) */
|
|
401
|
+
expiresAt: string;
|
|
402
|
+
/** When the waiver was created */
|
|
403
|
+
createdAt: string;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* The waiver file format.
|
|
407
|
+
*/
|
|
408
|
+
interface WaiverFile {
|
|
409
|
+
/** Schema version for waiver file format */
|
|
410
|
+
schemaVersion: string;
|
|
411
|
+
/** CLI version that generated this file */
|
|
412
|
+
toolVersion: string;
|
|
413
|
+
/** Tool identifier (e.g., "@securitychecks/cli@0.1.0") */
|
|
414
|
+
generatedBy: string;
|
|
415
|
+
/** When the waiver file was last updated (UTC ISO date) */
|
|
416
|
+
updatedAt: string;
|
|
417
|
+
/** Waiver entries keyed by findingId */
|
|
418
|
+
entries: Record<string, WaiverEntry>;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Baseline and Waiver Storage
|
|
423
|
+
*
|
|
424
|
+
* Handles loading, saving, and managing baseline/waiver files.
|
|
425
|
+
* Files are stored in `.scheck/` directory.
|
|
426
|
+
*/
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Load the baseline file, creating an empty one if it doesn't exist.
|
|
430
|
+
*/
|
|
431
|
+
declare function loadBaseline(rootPath: string): Promise<BaselineFile>;
|
|
432
|
+
/**
|
|
433
|
+
* Save the baseline file with deterministic ordering.
|
|
434
|
+
*/
|
|
435
|
+
declare function saveBaseline(rootPath: string, baseline: BaselineFile, collectorSchemaVersion?: string): Promise<void>;
|
|
436
|
+
/**
|
|
437
|
+
* Add findings to the baseline.
|
|
438
|
+
* Returns the number of new entries added.
|
|
439
|
+
*/
|
|
440
|
+
declare function addToBaseline(baseline: BaselineFile, findings: Finding[], notes?: string): number;
|
|
441
|
+
/**
|
|
442
|
+
* Check if a finding is in the baseline.
|
|
443
|
+
*/
|
|
444
|
+
declare function isInBaseline(baseline: BaselineFile, finding: Finding): boolean;
|
|
445
|
+
/**
|
|
446
|
+
* Remove stale entries that haven't been seen in a certain number of days.
|
|
447
|
+
* Returns the number of entries removed.
|
|
448
|
+
*/
|
|
449
|
+
declare function pruneBaseline(baseline: BaselineFile, staleDays?: number): number;
|
|
450
|
+
/**
|
|
451
|
+
* Load the waiver file, creating an empty one if it doesn't exist.
|
|
452
|
+
*/
|
|
453
|
+
declare function loadWaivers(rootPath: string): Promise<WaiverFile>;
|
|
454
|
+
/**
|
|
455
|
+
* Save the waiver file with deterministic ordering.
|
|
456
|
+
*/
|
|
457
|
+
declare function saveWaivers(rootPath: string, waivers: WaiverFile): Promise<void>;
|
|
458
|
+
/**
|
|
459
|
+
* Add a waiver for a finding.
|
|
460
|
+
*/
|
|
461
|
+
declare function addWaiver(waivers: WaiverFile, finding: Finding, options: {
|
|
462
|
+
reason: string;
|
|
463
|
+
reasonKey?: WaiverEntry['reasonKey'];
|
|
464
|
+
owner: string;
|
|
465
|
+
expiresInDays: number;
|
|
466
|
+
}): WaiverEntry;
|
|
467
|
+
/**
|
|
468
|
+
* Check if a finding has a valid (non-expired) waiver.
|
|
469
|
+
* Returns the waiver if valid, undefined if expired or not found.
|
|
470
|
+
*/
|
|
471
|
+
declare function getValidWaiver(waivers: WaiverFile, finding: Finding): WaiverEntry | undefined;
|
|
472
|
+
/**
|
|
473
|
+
* Remove expired waivers from the file.
|
|
474
|
+
* Returns the number of waivers removed.
|
|
475
|
+
*/
|
|
476
|
+
declare function pruneExpiredWaivers(waivers: WaiverFile): number;
|
|
477
|
+
/**
|
|
478
|
+
* Get all waivers that are about to expire (within N days).
|
|
479
|
+
*/
|
|
480
|
+
declare function getExpiringWaivers(waivers: WaiverFile, withinDays?: number): WaiverEntry[];
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Baseline and Waiver Matching
|
|
484
|
+
*
|
|
485
|
+
* Applies baselines and waivers to findings, categorizing them for CI decisions.
|
|
486
|
+
*/
|
|
487
|
+
|
|
488
|
+
/**
|
|
489
|
+
* A finding with its baseline/waiver status resolved.
|
|
490
|
+
*/
|
|
491
|
+
interface CategorizedFinding extends Finding {
|
|
492
|
+
findingId: string;
|
|
493
|
+
/** Whether this finding is in the baseline */
|
|
494
|
+
isBaselined: boolean;
|
|
495
|
+
/** Active waiver if present */
|
|
496
|
+
waiver?: WaiverEntry;
|
|
497
|
+
/** Whether this finding should fail CI */
|
|
498
|
+
shouldFail: boolean;
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Result of categorizing findings.
|
|
502
|
+
*/
|
|
503
|
+
interface CategorizationResult {
|
|
504
|
+
/** All findings with status */
|
|
505
|
+
all: CategorizedFinding[];
|
|
506
|
+
/** New findings not in baseline (may fail CI) */
|
|
507
|
+
new: CategorizedFinding[];
|
|
508
|
+
/** Findings in baseline (won't fail CI) */
|
|
509
|
+
baselined: CategorizedFinding[];
|
|
510
|
+
/** Findings with active waivers (won't fail CI) */
|
|
511
|
+
waived: CategorizedFinding[];
|
|
512
|
+
/** Summary counts */
|
|
513
|
+
counts: {
|
|
514
|
+
total: number;
|
|
515
|
+
new: number;
|
|
516
|
+
baselined: number;
|
|
517
|
+
waived: number;
|
|
518
|
+
willFail: number;
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Categorize findings against baseline and waivers.
|
|
523
|
+
*
|
|
524
|
+
* @param findings - Raw findings from checkers
|
|
525
|
+
* @param baseline - Loaded baseline file
|
|
526
|
+
* @param waivers - Loaded waiver file
|
|
527
|
+
* @param failSeverities - Which severities should fail CI (default: P0, P1)
|
|
528
|
+
*/
|
|
529
|
+
declare function categorizeFindings(findings: Finding[], baseline: BaselineFile, waivers: WaiverFile, failSeverities?: Severity[]): CategorizationResult;
|
|
530
|
+
/**
|
|
531
|
+
* Determine CI exit status based on categorized findings.
|
|
532
|
+
*
|
|
533
|
+
* @returns 0 for success, 1 for failure
|
|
534
|
+
*/
|
|
535
|
+
declare function getCIExitCode(result: CategorizationResult): number;
|
|
536
|
+
/**
|
|
537
|
+
* Get a summary message for CI output.
|
|
538
|
+
*/
|
|
539
|
+
declare function getCISummary(result: CategorizationResult): string;
|
|
540
|
+
/**
|
|
541
|
+
* Detect and handle findingId collisions.
|
|
542
|
+
* Returns findings with unique IDs (appending :a, :b, etc. if needed).
|
|
543
|
+
*
|
|
544
|
+
* This is a defensive measure - collisions should be extremely rare with
|
|
545
|
+
* 12 hex chars of SHA-256, but we define the behavior explicitly.
|
|
546
|
+
*/
|
|
547
|
+
declare function resolveCollisions(findings: Finding[]): (Finding & {
|
|
548
|
+
findingId: string;
|
|
549
|
+
})[];
|
|
550
|
+
/**
|
|
551
|
+
* Check if there are any findingId collisions in a set of findings.
|
|
552
|
+
* Returns true if collisions exist.
|
|
553
|
+
*/
|
|
554
|
+
declare function hasCollisions(findings: Finding[]): boolean;
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* Finding Correlation Engine
|
|
558
|
+
*
|
|
559
|
+
* Correlates findings across invariants to detect compounding risks.
|
|
560
|
+
* Multiple findings on the same code path often compound each other,
|
|
561
|
+
* creating worse outcomes than the sum of their parts.
|
|
562
|
+
*
|
|
563
|
+
* Key concepts:
|
|
564
|
+
* - Correlated findings: Multiple findings sharing a code path
|
|
565
|
+
* - Compounding risk: Combined severity is higher than individual
|
|
566
|
+
* - Attack path: Narrative of how findings chain together
|
|
567
|
+
*
|
|
568
|
+
* Example:
|
|
569
|
+
* Route: POST /api/webhooks/stripe
|
|
570
|
+
* ├── WEBHOOK.IDEMPOTENT: ✗ No idempotency check
|
|
571
|
+
* ├── TRANSACTION.POST_COMMIT: ✗ Email inside transaction
|
|
572
|
+
* └── Combined: If replayed, sends duplicate emails AND inconsistent DB
|
|
573
|
+
*/
|
|
574
|
+
|
|
575
|
+
interface CorrelatedFinding {
|
|
576
|
+
/** The primary finding (highest severity) */
|
|
577
|
+
primary: Finding;
|
|
578
|
+
/** Related findings on the same code path */
|
|
579
|
+
related: Finding[];
|
|
580
|
+
/** Shared context between findings */
|
|
581
|
+
sharedContext: SharedContext;
|
|
582
|
+
/** How the findings compound each other */
|
|
583
|
+
compoundingEffect: CompoundingEffect;
|
|
584
|
+
/** Adjusted severity based on correlation */
|
|
585
|
+
adjustedSeverity: Severity;
|
|
586
|
+
/** Attack path narrative */
|
|
587
|
+
attackPath?: AttackPath;
|
|
588
|
+
}
|
|
589
|
+
interface SharedContext {
|
|
590
|
+
/** Common file */
|
|
591
|
+
file?: string;
|
|
592
|
+
/** Common function */
|
|
593
|
+
functionName?: string;
|
|
594
|
+
/** Common route (if applicable) */
|
|
595
|
+
route?: string;
|
|
596
|
+
/** Shared call chain */
|
|
597
|
+
callChain?: string[];
|
|
598
|
+
/** Number of findings in this correlation */
|
|
599
|
+
findingCount: number;
|
|
600
|
+
}
|
|
601
|
+
interface CompoundingEffect {
|
|
602
|
+
/** Description of how findings compound */
|
|
603
|
+
description: string;
|
|
604
|
+
/** Risk multiplier (1.0 = no change, 2.0 = double risk) */
|
|
605
|
+
riskMultiplier: number;
|
|
606
|
+
/** Signals explaining the compounding */
|
|
607
|
+
signals: string[];
|
|
608
|
+
}
|
|
609
|
+
interface AttackPath {
|
|
610
|
+
/** Title of the attack path */
|
|
611
|
+
title: string;
|
|
612
|
+
/** Step-by-step narrative */
|
|
613
|
+
steps: AttackStep[];
|
|
614
|
+
/** Overall exploitability */
|
|
615
|
+
exploitability: 'easy' | 'medium' | 'hard';
|
|
616
|
+
/** Impact level */
|
|
617
|
+
impact: 'low' | 'medium' | 'high' | 'critical';
|
|
618
|
+
/** Time window (if applicable) */
|
|
619
|
+
timeWindow?: string;
|
|
620
|
+
}
|
|
621
|
+
interface AttackStep {
|
|
622
|
+
/** Step number */
|
|
623
|
+
step: number;
|
|
624
|
+
/** Description of this step */
|
|
625
|
+
description: string;
|
|
626
|
+
/** Which finding enables this step */
|
|
627
|
+
invariantId: string;
|
|
628
|
+
/** File/line reference */
|
|
629
|
+
location?: {
|
|
630
|
+
file: string;
|
|
631
|
+
line: number;
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
interface CorrelationResult {
|
|
635
|
+
/** All correlated finding groups */
|
|
636
|
+
correlations: CorrelatedFinding[];
|
|
637
|
+
/** Statistics */
|
|
638
|
+
stats: {
|
|
639
|
+
totalFindings: number;
|
|
640
|
+
correlatedFindings: number;
|
|
641
|
+
correlationGroups: number;
|
|
642
|
+
severityEscalations: number;
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Correlate findings to detect compounding risks
|
|
647
|
+
*/
|
|
648
|
+
declare function correlateFindings(results: CheckResult[], artifact: Artifact): CorrelationResult;
|
|
649
|
+
/**
|
|
650
|
+
* Format a correlated finding for display
|
|
651
|
+
*/
|
|
652
|
+
declare function formatCorrelatedFinding(correlation: CorrelatedFinding): string;
|
|
653
|
+
/**
|
|
654
|
+
* Format correlation statistics
|
|
655
|
+
*/
|
|
656
|
+
declare function formatCorrelationStats(result: CorrelationResult): string;
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Correlation Telemetry
|
|
660
|
+
*
|
|
661
|
+
* Reports correlation data to the SecurityChecks SaaS.
|
|
662
|
+
* This builds the data moat around which invariant combinations
|
|
663
|
+
* actually compound risk in production codebases.
|
|
664
|
+
*/
|
|
665
|
+
|
|
666
|
+
interface CorrelationTelemetryConfig {
|
|
667
|
+
enabled: boolean;
|
|
668
|
+
endpoint?: string;
|
|
669
|
+
apiKey?: string;
|
|
670
|
+
timeout?: number;
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Report correlation results to the SaaS
|
|
674
|
+
*/
|
|
675
|
+
declare function reportCorrelations(result: CorrelationResult, config: CorrelationTelemetryConfig, framework?: string): Promise<{
|
|
676
|
+
success: boolean;
|
|
677
|
+
stored?: number;
|
|
678
|
+
errors?: number;
|
|
679
|
+
}>;
|
|
680
|
+
/**
|
|
681
|
+
* Report feedback on a correlation (user marking as accurate/inaccurate)
|
|
682
|
+
*/
|
|
683
|
+
declare function reportCorrelationFeedback(requestId: string, wasAccurate: boolean, reason?: string, config?: CorrelationTelemetryConfig): Promise<boolean>;
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Anonymous Telemetry
|
|
687
|
+
*
|
|
688
|
+
* Reports aggregate scan statistics to the SecurityChecks SaaS.
|
|
689
|
+
* NO source code, NO file paths, NO PII - just patterns and numbers.
|
|
690
|
+
*
|
|
691
|
+
* This data powers:
|
|
692
|
+
* - Framework-specific calibration
|
|
693
|
+
* - Pattern effectiveness tracking
|
|
694
|
+
* - Invariant impact analysis
|
|
695
|
+
*/
|
|
696
|
+
|
|
697
|
+
interface TelemetryConfig {
|
|
698
|
+
enabled: boolean;
|
|
699
|
+
endpoint?: string;
|
|
700
|
+
apiKey?: string;
|
|
701
|
+
timeout?: number;
|
|
702
|
+
}
|
|
703
|
+
interface ScanTelemetry {
|
|
704
|
+
scanId: string;
|
|
705
|
+
codebase: {
|
|
706
|
+
filesScanned: number;
|
|
707
|
+
servicesCount: number;
|
|
708
|
+
linesOfCode?: number;
|
|
709
|
+
};
|
|
710
|
+
frameworks: string[];
|
|
711
|
+
findings: {
|
|
712
|
+
byInvariant: Record<string, number>;
|
|
713
|
+
byPriority: {
|
|
714
|
+
P0: number;
|
|
715
|
+
P1: number;
|
|
716
|
+
P2: number;
|
|
717
|
+
};
|
|
718
|
+
total: number;
|
|
719
|
+
};
|
|
720
|
+
correlation?: {
|
|
721
|
+
groups: number;
|
|
722
|
+
escalations: number;
|
|
723
|
+
correlatedFindings: number;
|
|
724
|
+
};
|
|
725
|
+
calibration?: {
|
|
726
|
+
calibrated: number;
|
|
727
|
+
suppressed: number;
|
|
728
|
+
};
|
|
729
|
+
patterns?: {
|
|
730
|
+
applied: number;
|
|
731
|
+
findings: number;
|
|
732
|
+
};
|
|
733
|
+
meta: {
|
|
734
|
+
duration?: number;
|
|
735
|
+
clientVersion: string;
|
|
736
|
+
mode?: 'ci' | 'manual' | 'watch';
|
|
737
|
+
ciProvider?: string;
|
|
738
|
+
};
|
|
739
|
+
baseline?: {
|
|
740
|
+
size: number;
|
|
741
|
+
waivers: number;
|
|
742
|
+
newFindings: number;
|
|
743
|
+
};
|
|
744
|
+
feedback?: {
|
|
745
|
+
waivedCount: number;
|
|
746
|
+
waiverReasons: Record<string, number>;
|
|
747
|
+
baselinedCount: number;
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Build telemetry data from scan results
|
|
752
|
+
*/
|
|
753
|
+
declare function buildTelemetry(result: AuditResult, options: {
|
|
754
|
+
filesScanned: number;
|
|
755
|
+
frameworks: string[];
|
|
756
|
+
correlation?: CorrelationResult;
|
|
757
|
+
categorization?: CategorizationResult;
|
|
758
|
+
calibratedCount?: number;
|
|
759
|
+
suppressedCount?: number;
|
|
760
|
+
patternsApplied?: number;
|
|
761
|
+
patternFindings?: number;
|
|
762
|
+
mode?: 'ci' | 'manual' | 'watch';
|
|
763
|
+
baselineSize?: number;
|
|
764
|
+
waiversCount?: number;
|
|
765
|
+
}): ScanTelemetry;
|
|
766
|
+
/**
|
|
767
|
+
* Report telemetry to the SaaS
|
|
768
|
+
*/
|
|
769
|
+
declare function reportTelemetry(telemetry: ScanTelemetry, config: TelemetryConfig): Promise<boolean>;
|
|
770
|
+
/**
|
|
771
|
+
* Check if telemetry is opt-out
|
|
772
|
+
*/
|
|
773
|
+
declare function isTelemetryDisabled(): boolean;
|
|
774
|
+
|
|
775
|
+
/**
|
|
776
|
+
* Calibration API Client
|
|
777
|
+
*
|
|
778
|
+
* "The SaaS advises. The local tool decides."
|
|
779
|
+
*
|
|
780
|
+
* This module handles communication with the SecurityChecks Calibration API.
|
|
781
|
+
* The API provides confidence tuning based on aggregate data from many codebases.
|
|
782
|
+
*
|
|
783
|
+
* Key principles:
|
|
784
|
+
* - No source code is ever sent (only patterns and metadata)
|
|
785
|
+
* - API suggestions are advisory only
|
|
786
|
+
* - Local tool retains veto power via minConfidence threshold
|
|
787
|
+
* - Fails safely to local-only mode on network errors
|
|
788
|
+
*/
|
|
789
|
+
|
|
790
|
+
interface AggregateCalibrationConfig {
|
|
791
|
+
enabled: boolean;
|
|
792
|
+
endpoint?: string;
|
|
793
|
+
apiKey?: string;
|
|
794
|
+
timeout?: number;
|
|
795
|
+
cacheEnabled?: boolean;
|
|
796
|
+
}
|
|
797
|
+
interface FrameworkBaseline {
|
|
798
|
+
framework: string;
|
|
799
|
+
avgFindings: number;
|
|
800
|
+
avgP0: number;
|
|
801
|
+
avgP1: number;
|
|
802
|
+
avgP2: number;
|
|
803
|
+
scansAnalyzed: number;
|
|
804
|
+
confidence: 'high' | 'medium' | 'low';
|
|
805
|
+
}
|
|
806
|
+
interface InvariantStats {
|
|
807
|
+
invariantId: string;
|
|
808
|
+
avgPerScan: number;
|
|
809
|
+
hitRate: number;
|
|
810
|
+
p0Rate: number;
|
|
811
|
+
p1Rate: number;
|
|
812
|
+
p2Rate: number;
|
|
813
|
+
}
|
|
814
|
+
interface PatternStats {
|
|
815
|
+
patternId: string;
|
|
816
|
+
framework: string | null;
|
|
817
|
+
accuracy: number | null;
|
|
818
|
+
matchesPerScan: number;
|
|
819
|
+
confidence: 'high' | 'medium' | 'low';
|
|
820
|
+
}
|
|
821
|
+
interface CorrelationStats {
|
|
822
|
+
ruleId: string;
|
|
823
|
+
accuracy: number | null;
|
|
824
|
+
escalationRate: number | null;
|
|
825
|
+
isVerified: boolean;
|
|
826
|
+
}
|
|
827
|
+
interface AggregateCalibrationData {
|
|
828
|
+
version: string;
|
|
829
|
+
generatedAt: string;
|
|
830
|
+
frameworks: FrameworkBaseline[];
|
|
831
|
+
invariants: InvariantStats[];
|
|
832
|
+
patterns: PatternStats[];
|
|
833
|
+
correlations: CorrelationStats[];
|
|
834
|
+
meta: {
|
|
835
|
+
totalScansAnalyzed: number;
|
|
836
|
+
lastUpdated: string | null;
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
interface AggregateCalibrationResult {
|
|
840
|
+
data: AggregateCalibrationData | null;
|
|
841
|
+
fromCache: boolean;
|
|
842
|
+
error?: string;
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Fetch aggregate calibration data for the specified frameworks
|
|
846
|
+
*/
|
|
847
|
+
declare function fetchAggregateCalibration(frameworks: string[], config: AggregateCalibrationConfig): Promise<AggregateCalibrationResult>;
|
|
848
|
+
/**
|
|
849
|
+
* Clear the aggregate calibration cache
|
|
850
|
+
*/
|
|
851
|
+
declare function clearAggregateCache(): void;
|
|
852
|
+
/**
|
|
853
|
+
* Get the framework baseline for comparison
|
|
854
|
+
*/
|
|
855
|
+
declare function getFrameworkBaseline(calibration: AggregateCalibrationData, framework: string): FrameworkBaseline | undefined;
|
|
856
|
+
/**
|
|
857
|
+
* Check if a pattern should be skipped due to low accuracy
|
|
858
|
+
*/
|
|
859
|
+
declare function shouldSkipPattern(calibration: AggregateCalibrationData, patternId: string, framework?: string, accuracyThreshold?: number): boolean;
|
|
860
|
+
/**
|
|
861
|
+
* Get patterns that should be skipped for a framework
|
|
862
|
+
*/
|
|
863
|
+
declare function getSkippedPatterns(calibration: AggregateCalibrationData, framework?: string, accuracyThreshold?: number): string[];
|
|
864
|
+
/**
|
|
865
|
+
* Get correlation rules with high confidence
|
|
866
|
+
*/
|
|
867
|
+
declare function getVerifiedCorrelations(calibration: AggregateCalibrationData): CorrelationStats[];
|
|
868
|
+
/**
|
|
869
|
+
* Calculate relative finding severity based on framework baseline
|
|
870
|
+
*/
|
|
871
|
+
declare function calculateRelativeSeverity(findingCount: number, baseline: FrameworkBaseline, type?: 'total' | 'P0' | 'P1' | 'P2'): 'below_average' | 'average' | 'above_average' | 'critical';
|
|
872
|
+
/**
|
|
873
|
+
* Generate calibration summary for output
|
|
874
|
+
*/
|
|
875
|
+
declare function formatAggregateCalibrationSummary(calibration: AggregateCalibrationData, frameworks: string[], findings: {
|
|
876
|
+
P0: number;
|
|
877
|
+
P1: number;
|
|
878
|
+
P2: number;
|
|
879
|
+
total: number;
|
|
880
|
+
}): string;
|
|
881
|
+
/**
|
|
882
|
+
* Check if aggregate calibration is disabled via environment
|
|
883
|
+
*/
|
|
884
|
+
declare function isAggregateCalibrationDisabled(): boolean;
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
* Staff Engineer Templates
|
|
888
|
+
*
|
|
889
|
+
* Shared, stable UX helpers used by:
|
|
890
|
+
* - CLI output (human-readable prompts)
|
|
891
|
+
* - MCP adapters (Claude Code, etc.)
|
|
892
|
+
*
|
|
893
|
+
* Keep these centralized to avoid drift across integration surfaces.
|
|
894
|
+
*/
|
|
895
|
+
type TestFramework = 'jest' | 'vitest' | 'playwright' | (string & {});
|
|
896
|
+
type InvariantLike = {
|
|
897
|
+
id: string;
|
|
898
|
+
name: string;
|
|
899
|
+
requiredProof?: string;
|
|
900
|
+
};
|
|
901
|
+
/**
|
|
902
|
+
* Returns the "A staff engineer would ask..." question for each invariant.
|
|
903
|
+
* These are the probing questions that senior engineers ask in code review.
|
|
904
|
+
*/
|
|
905
|
+
declare function getStaffQuestion(invariantId: string): string | null;
|
|
906
|
+
declare function generateTestSkeleton(invariant: InvariantLike | null | undefined, framework: TestFramework, context?: string): string;
|
|
907
|
+
|
|
908
|
+
export { type AggregateCalibrationConfig, type AggregateCalibrationData, type AggregateCalibrationResult, type AttackPath, type AttackStep, type AuditOptions, BASELINE_SCHEMA_VERSION, type BaselineEntry, type BaselineFile, CLIError, type CategorizationResult, type CategorizedFinding, type CloudEvaluateOptions, type CloudEvaluateResult, type CompoundingEffect, type CorrelatedFinding, type CorrelationResult, type CorrelationStats, type CorrelationTelemetryConfig, type ErrorCode, ErrorCodes, ErrorMessages, ErrorRemediation, type EvaluationProgressCallback, type FrameworkBaseline, type InvariantLike, type InvariantStats, type PatternStats, SUPPORTED_SCHEMA_RANGE, type ScanTelemetry, type SchemaValidationResult, type SharedContext, type TelemetryConfig, type TestFramework, WAIVER_SCHEMA_VERSION, type WaiverEntry, type WaiverFile, addToBaseline, addWaiver, attachFindingId, attachFindingIds, audit, buildTelemetry, calculateRelativeSeverity, categorizeFindings, checkCloudHealth, clearAggregateCache, correlateFindings, evaluateCloud, extractIdentityPayload, fetchAggregateCalibration, formatAggregateCalibrationSummary, formatCorrelatedFinding, formatCorrelationStats, generateFindingId, generateTestSkeleton, getCIExitCode, getCISummary, getCloudInvariants, getCurrentSchemaVersion, getExpiringWaivers, getFrameworkBaseline, getSkippedPatterns, getStaffQuestion, getValidWaiver, getVerifiedCorrelations, hasCollisions, isAggregateCalibrationDisabled, isCLIError, isCloudEvalAvailable, isInBaseline, isTelemetryDisabled, loadBaseline, loadWaivers, pruneBaseline, pruneExpiredWaivers, reportCorrelationFeedback, reportCorrelations, reportTelemetry, resolveCollisions, saveBaseline, saveWaivers, shouldSkipPattern, validateSchemaVersion, wrapError };
|