@cyvest/cyvest-js 3.2.0 → 4.1.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/index.d.mts +55 -33
- package/dist/index.d.ts +55 -33
- package/dist/index.js +191 -71
- package/dist/index.mjs +191 -69
- package/package.json +5 -5
- package/src/finders.ts +29 -20
- package/src/getters.ts +0 -10
- package/src/types.generated.ts +54 -18
- package/tests/getters-finders.test.ts +40 -24
- package/tests/graph.test.ts +21 -16
- package/vitest.config.ts +8 -0
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,97 @@ import addFormats from "ajv-formats";
|
|
|
5
5
|
// ../../../schema/cyvest.schema.json
|
|
6
6
|
var cyvest_schema_default = {
|
|
7
7
|
$defs: {
|
|
8
|
+
AuditEvent: {
|
|
9
|
+
additionalProperties: true,
|
|
10
|
+
description: "Centralized audit event for investigation-level changes.",
|
|
11
|
+
properties: {
|
|
12
|
+
event_id: {
|
|
13
|
+
title: "Event Id",
|
|
14
|
+
type: "string"
|
|
15
|
+
},
|
|
16
|
+
timestamp: {
|
|
17
|
+
format: "date-time",
|
|
18
|
+
title: "Timestamp",
|
|
19
|
+
type: "string"
|
|
20
|
+
},
|
|
21
|
+
event_type: {
|
|
22
|
+
title: "Event Type",
|
|
23
|
+
type: "string"
|
|
24
|
+
},
|
|
25
|
+
actor: {
|
|
26
|
+
anyOf: [
|
|
27
|
+
{
|
|
28
|
+
type: "string"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
type: "null"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
default: null,
|
|
35
|
+
title: "Actor"
|
|
36
|
+
},
|
|
37
|
+
reason: {
|
|
38
|
+
anyOf: [
|
|
39
|
+
{
|
|
40
|
+
type: "string"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "null"
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
default: null,
|
|
47
|
+
title: "Reason"
|
|
48
|
+
},
|
|
49
|
+
tool: {
|
|
50
|
+
anyOf: [
|
|
51
|
+
{
|
|
52
|
+
type: "string"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
type: "null"
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
default: null,
|
|
59
|
+
title: "Tool"
|
|
60
|
+
},
|
|
61
|
+
object_type: {
|
|
62
|
+
anyOf: [
|
|
63
|
+
{
|
|
64
|
+
type: "string"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "null"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
default: null,
|
|
71
|
+
title: "Object Type"
|
|
72
|
+
},
|
|
73
|
+
object_key: {
|
|
74
|
+
anyOf: [
|
|
75
|
+
{
|
|
76
|
+
type: "string"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: "null"
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
default: null,
|
|
83
|
+
title: "Object Key"
|
|
84
|
+
},
|
|
85
|
+
details: {
|
|
86
|
+
additionalProperties: true,
|
|
87
|
+
title: "Details",
|
|
88
|
+
type: "object"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
required: [
|
|
92
|
+
"event_id",
|
|
93
|
+
"timestamp",
|
|
94
|
+
"event_type"
|
|
95
|
+
],
|
|
96
|
+
title: "AuditEvent",
|
|
97
|
+
type: "object"
|
|
98
|
+
},
|
|
8
99
|
Check: {
|
|
9
100
|
description: "Represents a verification step in the investigation.\n\nA check validates a specific aspect of the data under investigation\nand contributes to the overall investigation score.",
|
|
10
101
|
properties: {
|
|
@@ -36,17 +127,17 @@ var cyvest_schema_default = {
|
|
|
36
127
|
level: {
|
|
37
128
|
$ref: "#/$defs/Level"
|
|
38
129
|
},
|
|
39
|
-
|
|
130
|
+
origin_investigation_id: {
|
|
131
|
+
title: "Origin Investigation Id",
|
|
132
|
+
type: "string"
|
|
133
|
+
},
|
|
134
|
+
observable_links: {
|
|
40
135
|
items: {
|
|
41
|
-
|
|
136
|
+
$ref: "#/$defs/ObservableLink"
|
|
42
137
|
},
|
|
43
|
-
title: "
|
|
138
|
+
title: "Observable Links",
|
|
44
139
|
type: "array"
|
|
45
140
|
},
|
|
46
|
-
score_policy: {
|
|
47
|
-
$ref: "#/$defs/CheckScorePolicy",
|
|
48
|
-
default: "auto"
|
|
49
|
-
},
|
|
50
141
|
key: {
|
|
51
142
|
title: "Key",
|
|
52
143
|
type: "string"
|
|
@@ -65,22 +156,14 @@ var cyvest_schema_default = {
|
|
|
65
156
|
"extra",
|
|
66
157
|
"score",
|
|
67
158
|
"level",
|
|
68
|
-
"
|
|
159
|
+
"origin_investigation_id",
|
|
160
|
+
"observable_links",
|
|
69
161
|
"key",
|
|
70
162
|
"score_display"
|
|
71
163
|
],
|
|
72
164
|
title: "Check",
|
|
73
165
|
type: "object"
|
|
74
166
|
},
|
|
75
|
-
CheckScorePolicy: {
|
|
76
|
-
description: "Controls how a check reacts to linked observables.",
|
|
77
|
-
enum: [
|
|
78
|
-
"auto",
|
|
79
|
-
"manual"
|
|
80
|
-
],
|
|
81
|
-
title: "CheckScorePolicy",
|
|
82
|
-
type: "string"
|
|
83
|
-
},
|
|
84
167
|
Container: {
|
|
85
168
|
additionalProperties: false,
|
|
86
169
|
description: "Groups checks and sub-containers for hierarchical organization.\n\nContainers allow structuring the investigation into logical sections\nwith aggregated scores and levels.",
|
|
@@ -141,6 +224,10 @@ var cyvest_schema_default = {
|
|
|
141
224
|
root_type: {
|
|
142
225
|
anyOf: [
|
|
143
226
|
{
|
|
227
|
+
enum: [
|
|
228
|
+
"file",
|
|
229
|
+
"artifact"
|
|
230
|
+
],
|
|
144
231
|
type: "string"
|
|
145
232
|
},
|
|
146
233
|
{
|
|
@@ -151,13 +238,13 @@ var cyvest_schema_default = {
|
|
|
151
238
|
description: "Root observable type used during data extraction.",
|
|
152
239
|
title: "Root Type"
|
|
153
240
|
},
|
|
154
|
-
|
|
241
|
+
score_mode_obs: {
|
|
155
242
|
$ref: "#/$defs/ScoreMode",
|
|
156
|
-
description: "
|
|
243
|
+
description: "Observable score aggregation mode: 'max' takes highest score, 'sum' adds all scores."
|
|
157
244
|
}
|
|
158
245
|
},
|
|
159
246
|
required: [
|
|
160
|
-
"
|
|
247
|
+
"score_mode_obs"
|
|
161
248
|
],
|
|
162
249
|
title: "DataExtractionSchema",
|
|
163
250
|
type: "object"
|
|
@@ -290,13 +377,13 @@ var cyvest_schema_default = {
|
|
|
290
377
|
title: "Key",
|
|
291
378
|
type: "string"
|
|
292
379
|
},
|
|
293
|
-
|
|
294
|
-
description: "Checks that
|
|
380
|
+
check_links: {
|
|
381
|
+
description: "Checks that currently link to this observable (navigation-only).",
|
|
295
382
|
items: {
|
|
296
383
|
type: "string"
|
|
297
384
|
},
|
|
298
385
|
readOnly: true,
|
|
299
|
-
title: "
|
|
386
|
+
title: "Check Links",
|
|
300
387
|
type: "array"
|
|
301
388
|
},
|
|
302
389
|
score_display: {
|
|
@@ -317,12 +404,40 @@ var cyvest_schema_default = {
|
|
|
317
404
|
"threat_intels",
|
|
318
405
|
"relationships",
|
|
319
406
|
"key",
|
|
320
|
-
"
|
|
407
|
+
"check_links",
|
|
321
408
|
"score_display"
|
|
322
409
|
],
|
|
323
410
|
title: "Observable",
|
|
324
411
|
type: "object"
|
|
325
412
|
},
|
|
413
|
+
ObservableLink: {
|
|
414
|
+
additionalProperties: false,
|
|
415
|
+
description: "Edge metadata for a Check\u2194Observable association.",
|
|
416
|
+
properties: {
|
|
417
|
+
observable_key: {
|
|
418
|
+
title: "Observable Key",
|
|
419
|
+
type: "string"
|
|
420
|
+
},
|
|
421
|
+
propagation_mode: {
|
|
422
|
+
$ref: "#/$defs/PropagationMode",
|
|
423
|
+
default: "LOCAL_ONLY"
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
required: [
|
|
427
|
+
"observable_key"
|
|
428
|
+
],
|
|
429
|
+
title: "ObservableLink",
|
|
430
|
+
type: "object"
|
|
431
|
+
},
|
|
432
|
+
PropagationMode: {
|
|
433
|
+
description: "Controls how a Check\u2194Observable link propagates across merged investigations.",
|
|
434
|
+
enum: [
|
|
435
|
+
"LOCAL_ONLY",
|
|
436
|
+
"GLOBAL"
|
|
437
|
+
],
|
|
438
|
+
title: "PropagationMode",
|
|
439
|
+
type: "string"
|
|
440
|
+
},
|
|
326
441
|
Relationship: {
|
|
327
442
|
description: "Represents a relationship between observables.",
|
|
328
443
|
properties: {
|
|
@@ -482,28 +597,6 @@ var cyvest_schema_default = {
|
|
|
482
597
|
title: "StatisticsSchema",
|
|
483
598
|
type: "object"
|
|
484
599
|
},
|
|
485
|
-
StatsChecksSchema: {
|
|
486
|
-
additionalProperties: false,
|
|
487
|
-
description: "Schema for check statistics summary.",
|
|
488
|
-
properties: {
|
|
489
|
-
checks: {
|
|
490
|
-
minimum: 0,
|
|
491
|
-
title: "Checks",
|
|
492
|
-
type: "integer"
|
|
493
|
-
},
|
|
494
|
-
applied: {
|
|
495
|
-
minimum: 0,
|
|
496
|
-
title: "Applied",
|
|
497
|
-
type: "integer"
|
|
498
|
-
}
|
|
499
|
-
},
|
|
500
|
-
required: [
|
|
501
|
-
"checks",
|
|
502
|
-
"applied"
|
|
503
|
-
],
|
|
504
|
-
title: "StatsChecksSchema",
|
|
505
|
-
type: "object"
|
|
506
|
-
},
|
|
507
600
|
ThreatIntel: {
|
|
508
601
|
description: "Represents threat intelligence from an external source.\n\nThreat intelligence provides verdicts about observables from sources\nlike VirusTotal, URLScan.io, etc.",
|
|
509
602
|
properties: {
|
|
@@ -569,6 +662,24 @@ var cyvest_schema_default = {
|
|
|
569
662
|
additionalProperties: false,
|
|
570
663
|
description: "Schema for a complete serialized investigation.\n\nThis model describes the output of `serialize_investigation()` from\n`cyvest.io_serialization`. It is the top-level schema for exported investigations.\n\nEntity types reference the runtime models directly. When generating schemas with\n`mode='serialization'`, Pydantic respects field_serializer decorators and produces\nschemas matching the actual model_dump() output.",
|
|
571
664
|
properties: {
|
|
665
|
+
investigation_id: {
|
|
666
|
+
description: "Stable investigation identity (ULID).",
|
|
667
|
+
title: "Investigation Id",
|
|
668
|
+
type: "string"
|
|
669
|
+
},
|
|
670
|
+
investigation_name: {
|
|
671
|
+
anyOf: [
|
|
672
|
+
{
|
|
673
|
+
type: "string"
|
|
674
|
+
},
|
|
675
|
+
{
|
|
676
|
+
type: "null"
|
|
677
|
+
}
|
|
678
|
+
],
|
|
679
|
+
default: null,
|
|
680
|
+
description: "Optional human-readable investigation name.",
|
|
681
|
+
title: "Investigation Name"
|
|
682
|
+
},
|
|
572
683
|
started_at: {
|
|
573
684
|
description: "Investigation start time (UTC).",
|
|
574
685
|
format: "date-time",
|
|
@@ -597,6 +708,14 @@ var cyvest_schema_default = {
|
|
|
597
708
|
title: "Whitelists",
|
|
598
709
|
type: "array"
|
|
599
710
|
},
|
|
711
|
+
event_log: {
|
|
712
|
+
description: "Append-only investigation audit log.",
|
|
713
|
+
items: {
|
|
714
|
+
$ref: "#/$defs/AuditEvent"
|
|
715
|
+
},
|
|
716
|
+
title: "Event Log",
|
|
717
|
+
type: "array"
|
|
718
|
+
},
|
|
600
719
|
observables: {
|
|
601
720
|
additionalProperties: {
|
|
602
721
|
$ref: "#/$defs/Observable"
|
|
@@ -655,10 +774,6 @@ var cyvest_schema_default = {
|
|
|
655
774
|
$ref: "#/$defs/StatisticsSchema",
|
|
656
775
|
description: "Investigation statistics summary."
|
|
657
776
|
},
|
|
658
|
-
stats_checks: {
|
|
659
|
-
$ref: "#/$defs/StatsChecksSchema",
|
|
660
|
-
description: "Check statistics summary."
|
|
661
|
-
},
|
|
662
777
|
data_extraction: {
|
|
663
778
|
$ref: "#/$defs/DataExtractionSchema",
|
|
664
779
|
description: "Data extraction metadata."
|
|
@@ -671,6 +786,7 @@ var cyvest_schema_default = {
|
|
|
671
786
|
}
|
|
672
787
|
},
|
|
673
788
|
required: [
|
|
789
|
+
"investigation_id",
|
|
674
790
|
"started_at",
|
|
675
791
|
"score",
|
|
676
792
|
"level",
|
|
@@ -683,7 +799,6 @@ var cyvest_schema_default = {
|
|
|
683
799
|
"enrichments",
|
|
684
800
|
"containers",
|
|
685
801
|
"stats",
|
|
686
|
-
"stats_checks",
|
|
687
802
|
"data_extraction",
|
|
688
803
|
"score_display"
|
|
689
804
|
],
|
|
@@ -1056,9 +1171,6 @@ function getWhitelists(inv) {
|
|
|
1056
1171
|
function getStats(inv) {
|
|
1057
1172
|
return inv.stats;
|
|
1058
1173
|
}
|
|
1059
|
-
function getStatsChecks(inv) {
|
|
1060
|
-
return inv.stats_checks;
|
|
1061
|
-
}
|
|
1062
1174
|
function getDataExtraction(inv) {
|
|
1063
1175
|
return inv.data_extraction;
|
|
1064
1176
|
}
|
|
@@ -1165,17 +1277,6 @@ function findChecksByCheckId(inv, checkId) {
|
|
|
1165
1277
|
}
|
|
1166
1278
|
return result;
|
|
1167
1279
|
}
|
|
1168
|
-
function findManuallyScored(inv) {
|
|
1169
|
-
const result = [];
|
|
1170
|
-
for (const checks of Object.values(inv.checks)) {
|
|
1171
|
-
for (const check of checks) {
|
|
1172
|
-
if (check.score_policy === "manual") {
|
|
1173
|
-
result.push(check);
|
|
1174
|
-
}
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1177
|
-
return result;
|
|
1178
|
-
}
|
|
1179
1280
|
function findThreatIntelBySource(inv, source) {
|
|
1180
1281
|
const normalizedSource = source.trim().toLowerCase();
|
|
1181
1282
|
return Object.values(inv.threat_intels).filter(
|
|
@@ -1218,13 +1319,32 @@ function findContainersAtLeast(inv, minLevel2) {
|
|
|
1218
1319
|
}
|
|
1219
1320
|
function getChecksForObservable(inv, observableKey) {
|
|
1220
1321
|
const result = [];
|
|
1322
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1323
|
+
const checkLookup = /* @__PURE__ */ new Map();
|
|
1221
1324
|
for (const checks of Object.values(inv.checks)) {
|
|
1222
1325
|
for (const check of checks) {
|
|
1223
|
-
|
|
1326
|
+
checkLookup.set(check.key, check);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
const observable = inv.observables[observableKey];
|
|
1330
|
+
if (observable) {
|
|
1331
|
+
for (const checkKey of observable.check_links) {
|
|
1332
|
+
const check = checkLookup.get(checkKey);
|
|
1333
|
+
if (check && !seen.has(check.key)) {
|
|
1224
1334
|
result.push(check);
|
|
1335
|
+
seen.add(check.key);
|
|
1225
1336
|
}
|
|
1226
1337
|
}
|
|
1227
1338
|
}
|
|
1339
|
+
for (const check of checkLookup.values()) {
|
|
1340
|
+
if (seen.has(check.key)) {
|
|
1341
|
+
continue;
|
|
1342
|
+
}
|
|
1343
|
+
if (check.observable_links.some((link) => link.observable_key === observableKey)) {
|
|
1344
|
+
result.push(check);
|
|
1345
|
+
seen.add(check.key);
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1228
1348
|
return result;
|
|
1229
1349
|
}
|
|
1230
1350
|
function getThreatIntelsForObservable(inv, observableKey) {
|
|
@@ -1240,7 +1360,11 @@ function getObservablesForCheck(inv, checkKey) {
|
|
|
1240
1360
|
for (const checks of Object.values(inv.checks)) {
|
|
1241
1361
|
for (const check of checks) {
|
|
1242
1362
|
if (check.key === checkKey) {
|
|
1243
|
-
|
|
1363
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1364
|
+
for (const link of check.observable_links) {
|
|
1365
|
+
keys.add(link.observable_key);
|
|
1366
|
+
}
|
|
1367
|
+
return Array.from(keys).map((obsKey) => inv.observables[obsKey]).filter((obs) => obs !== void 0);
|
|
1244
1368
|
}
|
|
1245
1369
|
}
|
|
1246
1370
|
}
|
|
@@ -1612,7 +1736,6 @@ export {
|
|
|
1612
1736
|
findExternalObservables,
|
|
1613
1737
|
findInternalObservables,
|
|
1614
1738
|
findLeafObservables,
|
|
1615
|
-
findManuallyScored,
|
|
1616
1739
|
findObservablesAtLeast,
|
|
1617
1740
|
findObservablesByLevel,
|
|
1618
1741
|
findObservablesByType,
|
|
@@ -1671,7 +1794,6 @@ export {
|
|
|
1671
1794
|
getRelatedObservablesByType,
|
|
1672
1795
|
getRelationshipsForObservable,
|
|
1673
1796
|
getStats,
|
|
1674
|
-
getStatsChecks,
|
|
1675
1797
|
getSuspiciousChecks,
|
|
1676
1798
|
getSuspiciousObservables,
|
|
1677
1799
|
getThreatIntel,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cyvest/cyvest-js",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"main": "dist/index.cjs",
|
|
5
5
|
"module": "dist/index.mjs",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
"ajv-formats": "^3.0.1"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"json-schema-to-typescript": "^
|
|
14
|
-
"tsup": "^8.
|
|
15
|
-
"typescript": "^5.
|
|
16
|
-
"vitest": "^
|
|
13
|
+
"json-schema-to-typescript": "^15.0.4",
|
|
14
|
+
"tsup": "^8.5.1",
|
|
15
|
+
"typescript": "^5.9.3",
|
|
16
|
+
"vitest": "^4.0.16"
|
|
17
17
|
},
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">=20"
|
package/src/finders.ts
CHANGED
|
@@ -288,24 +288,6 @@ export function findChecksByCheckId(
|
|
|
288
288
|
return result;
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
/**
|
|
292
|
-
* Find checks with score policy set to manual.
|
|
293
|
-
*
|
|
294
|
-
* @param inv - The investigation to search
|
|
295
|
-
* @returns Array of manually scored checks
|
|
296
|
-
*/
|
|
297
|
-
export function findManuallyScored(inv: CyvestInvestigation): Check[] {
|
|
298
|
-
const result: Check[] = [];
|
|
299
|
-
for (const checks of Object.values(inv.checks)) {
|
|
300
|
-
for (const check of checks) {
|
|
301
|
-
if (check.score_policy === "manual") {
|
|
302
|
-
result.push(check);
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return result;
|
|
307
|
-
}
|
|
308
|
-
|
|
309
291
|
// ============================================================================
|
|
310
292
|
// Threat Intel Finders
|
|
311
293
|
// ============================================================================
|
|
@@ -434,15 +416,37 @@ export function getChecksForObservable(
|
|
|
434
416
|
observableKey: string
|
|
435
417
|
): Check[] {
|
|
436
418
|
const result: Check[] = [];
|
|
419
|
+
const seen = new Set<string>();
|
|
420
|
+
const checkLookup = new Map<string, Check>();
|
|
437
421
|
|
|
438
422
|
for (const checks of Object.values(inv.checks)) {
|
|
439
423
|
for (const check of checks) {
|
|
440
|
-
|
|
424
|
+
checkLookup.set(check.key, check);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const observable = inv.observables[observableKey];
|
|
429
|
+
if (observable) {
|
|
430
|
+
for (const checkKey of observable.check_links) {
|
|
431
|
+
const check = checkLookup.get(checkKey);
|
|
432
|
+
if (check && !seen.has(check.key)) {
|
|
441
433
|
result.push(check);
|
|
434
|
+
seen.add(check.key);
|
|
442
435
|
}
|
|
443
436
|
}
|
|
444
437
|
}
|
|
445
438
|
|
|
439
|
+
for (const check of checkLookup.values()) {
|
|
440
|
+
if (seen.has(check.key)) {
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
if (check.observable_links.some((link) => link.observable_key === observableKey)) {
|
|
445
|
+
result.push(check);
|
|
446
|
+
seen.add(check.key);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
446
450
|
return result;
|
|
447
451
|
}
|
|
448
452
|
|
|
@@ -486,7 +490,12 @@ export function getObservablesForCheck(
|
|
|
486
490
|
for (const checks of Object.values(inv.checks)) {
|
|
487
491
|
for (const check of checks) {
|
|
488
492
|
if (check.key === checkKey) {
|
|
489
|
-
|
|
493
|
+
const keys = new Set<string>();
|
|
494
|
+
for (const link of check.observable_links) {
|
|
495
|
+
keys.add(link.observable_key);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
return Array.from(keys)
|
|
490
499
|
.map((obsKey) => inv.observables[obsKey])
|
|
491
500
|
.filter((obs): obs is Observable => obs !== undefined);
|
|
492
501
|
}
|
package/src/getters.ts
CHANGED
|
@@ -359,16 +359,6 @@ export function getStats(inv: CyvestInvestigation) {
|
|
|
359
359
|
return inv.stats;
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
-
/**
|
|
363
|
-
* Get the investigation check statistics.
|
|
364
|
-
*
|
|
365
|
-
* @param inv - The investigation
|
|
366
|
-
* @returns Check statistics object
|
|
367
|
-
*/
|
|
368
|
-
export function getStatsChecks(inv: CyvestInvestigation) {
|
|
369
|
-
return inv.stats_checks;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
362
|
/**
|
|
373
363
|
* Get the data extraction configuration.
|
|
374
364
|
*
|
package/src/types.generated.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// AUTO-GENERATED FROM cyvest.schema.json — DO NOT EDIT
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Optional human-readable investigation name.
|
|
5
|
+
*/
|
|
6
|
+
export type InvestigationName = string | null;
|
|
3
7
|
/**
|
|
4
8
|
* Security level classification for checks, observables, and threat intelligence.
|
|
5
9
|
*
|
|
@@ -11,6 +15,15 @@ export type Justification = string | null;
|
|
|
11
15
|
* List of whitelist entries applied to this investigation.
|
|
12
16
|
*/
|
|
13
17
|
export type Whitelists = InvestigationWhitelist[];
|
|
18
|
+
export type Actor = string | null;
|
|
19
|
+
export type Reason = string | null;
|
|
20
|
+
export type Tool = string | null;
|
|
21
|
+
export type ObjectType = string | null;
|
|
22
|
+
export type ObjectKey = string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Append-only investigation audit log.
|
|
25
|
+
*/
|
|
26
|
+
export type EventLog = AuditEvent[];
|
|
14
27
|
export type ThreatIntels = string[];
|
|
15
28
|
/**
|
|
16
29
|
* Direction of a relationship between observables.
|
|
@@ -18,14 +31,14 @@ export type ThreatIntels = string[];
|
|
|
18
31
|
export type RelationshipDirection = "outbound" | "inbound" | "bidirectional";
|
|
19
32
|
export type Relationships = Relationship[];
|
|
20
33
|
/**
|
|
21
|
-
* Checks that
|
|
34
|
+
* Checks that currently link to this observable (navigation-only).
|
|
22
35
|
*/
|
|
23
|
-
export type
|
|
24
|
-
export type Observables1 = string[];
|
|
36
|
+
export type CheckLinks = string[];
|
|
25
37
|
/**
|
|
26
|
-
* Controls how a
|
|
38
|
+
* Controls how a Check↔Observable link propagates across merged investigations.
|
|
27
39
|
*/
|
|
28
|
-
export type
|
|
40
|
+
export type PropagationMode = "LOCAL_ONLY" | "GLOBAL";
|
|
41
|
+
export type ObservableLinks = ObservableLink[];
|
|
29
42
|
export type Taxonomies = {
|
|
30
43
|
[k: string]: unknown;
|
|
31
44
|
}[];
|
|
@@ -33,7 +46,7 @@ export type Checks1 = string[];
|
|
|
33
46
|
/**
|
|
34
47
|
* Root observable type used during data extraction.
|
|
35
48
|
*/
|
|
36
|
-
export type RootType =
|
|
49
|
+
export type RootType = ("file" | "artifact") | null;
|
|
37
50
|
/**
|
|
38
51
|
* Score calculation mode for observables.
|
|
39
52
|
*/
|
|
@@ -50,6 +63,11 @@ export type ScoreMode = "max" | "sum";
|
|
|
50
63
|
* schemas matching the actual model_dump() output.
|
|
51
64
|
*/
|
|
52
65
|
export interface CyvestInvestigation {
|
|
66
|
+
/**
|
|
67
|
+
* Stable investigation identity (ULID).
|
|
68
|
+
*/
|
|
69
|
+
investigation_id: string;
|
|
70
|
+
investigation_name?: InvestigationName;
|
|
53
71
|
/**
|
|
54
72
|
* Investigation start time (UTC).
|
|
55
73
|
*/
|
|
@@ -64,6 +82,7 @@ export interface CyvestInvestigation {
|
|
|
64
82
|
*/
|
|
65
83
|
whitelisted: boolean;
|
|
66
84
|
whitelists: Whitelists;
|
|
85
|
+
event_log?: EventLog;
|
|
67
86
|
observables: Observables;
|
|
68
87
|
checks: Checks;
|
|
69
88
|
checks_by_level: ChecksByLevel;
|
|
@@ -71,7 +90,6 @@ export interface CyvestInvestigation {
|
|
|
71
90
|
enrichments: Enrichments;
|
|
72
91
|
containers: Containers;
|
|
73
92
|
stats: StatisticsSchema;
|
|
74
|
-
stats_checks: StatsChecksSchema;
|
|
75
93
|
data_extraction: DataExtractionSchema;
|
|
76
94
|
/**
|
|
77
95
|
* Global investigation score formatted as fixed-point x.xx.
|
|
@@ -87,6 +105,24 @@ export interface InvestigationWhitelist {
|
|
|
87
105
|
justification?: Justification;
|
|
88
106
|
[k: string]: unknown;
|
|
89
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Centralized audit event for investigation-level changes.
|
|
110
|
+
*/
|
|
111
|
+
export interface AuditEvent {
|
|
112
|
+
event_id: string;
|
|
113
|
+
timestamp: string;
|
|
114
|
+
event_type: string;
|
|
115
|
+
actor?: Actor;
|
|
116
|
+
reason?: Reason;
|
|
117
|
+
tool?: Tool;
|
|
118
|
+
object_type?: ObjectType;
|
|
119
|
+
object_key?: ObjectKey;
|
|
120
|
+
details?: Details;
|
|
121
|
+
[k: string]: unknown;
|
|
122
|
+
}
|
|
123
|
+
export interface Details {
|
|
124
|
+
[k: string]: unknown;
|
|
125
|
+
}
|
|
90
126
|
/**
|
|
91
127
|
* Observables keyed by their unique key.
|
|
92
128
|
*/
|
|
@@ -111,7 +147,7 @@ export interface Observable {
|
|
|
111
147
|
threat_intels: ThreatIntels;
|
|
112
148
|
relationships: Relationships;
|
|
113
149
|
key: string;
|
|
114
|
-
|
|
150
|
+
check_links: CheckLinks;
|
|
115
151
|
score_display: string;
|
|
116
152
|
[k: string]: unknown;
|
|
117
153
|
}
|
|
@@ -147,8 +183,8 @@ export interface Check {
|
|
|
147
183
|
extra: Extra1;
|
|
148
184
|
score: number;
|
|
149
185
|
level: Level;
|
|
150
|
-
|
|
151
|
-
|
|
186
|
+
origin_investigation_id: string;
|
|
187
|
+
observable_links: ObservableLinks;
|
|
152
188
|
key: string;
|
|
153
189
|
score_display: string;
|
|
154
190
|
[k: string]: unknown;
|
|
@@ -156,6 +192,13 @@ export interface Check {
|
|
|
156
192
|
export interface Extra1 {
|
|
157
193
|
[k: string]: unknown;
|
|
158
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Edge metadata for a Check↔Observable association.
|
|
197
|
+
*/
|
|
198
|
+
export interface ObservableLink {
|
|
199
|
+
observable_key: string;
|
|
200
|
+
propagation_mode?: PropagationMode;
|
|
201
|
+
}
|
|
159
202
|
/**
|
|
160
203
|
* Check keys organized by level name.
|
|
161
204
|
*/
|
|
@@ -280,17 +323,10 @@ export interface ThreatIntelBySource {
|
|
|
280
323
|
export interface ThreatIntelByLevel {
|
|
281
324
|
[k: string]: number;
|
|
282
325
|
}
|
|
283
|
-
/**
|
|
284
|
-
* Schema for check statistics summary.
|
|
285
|
-
*/
|
|
286
|
-
export interface StatsChecksSchema {
|
|
287
|
-
checks: number;
|
|
288
|
-
applied: number;
|
|
289
|
-
}
|
|
290
326
|
/**
|
|
291
327
|
* Schema for data extraction metadata.
|
|
292
328
|
*/
|
|
293
329
|
export interface DataExtractionSchema {
|
|
294
330
|
root_type?: RootType;
|
|
295
|
-
|
|
331
|
+
score_mode_obs: ScoreMode;
|
|
296
332
|
}
|