@cyvest/cyvest-js 6.1.2 → 7.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/README.md +4 -4
- package/dist/index.cjs +2011 -2166
- package/dist/index.d.cts +731 -1439
- package/dist/index.d.ts +731 -1439
- package/dist/index.js +1895 -2026
- package/package.json +31 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,403 +1,546 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
type
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Levels are ordered from lowest (NONE) to highest (MALICIOUS) severity.
|
|
9
|
-
*/
|
|
10
|
-
type Level = "NONE" | "TRUSTED" | "INFO" | "SAFE" | "NOTABLE" | "SUSPICIOUS" | "MALICIOUS";
|
|
11
|
-
type Justification = string | null;
|
|
12
|
-
/**
|
|
13
|
-
* List of whitelist entries applied to this investigation.
|
|
14
|
-
*/
|
|
15
|
-
type Whitelists = InvestigationWhitelist[];
|
|
16
|
-
/**
|
|
17
|
-
* Append-only investigation audit log. Null when serialization disabled audit.
|
|
18
|
-
*/
|
|
19
|
-
type AuditLog = AuditEvent[] | null;
|
|
20
|
-
type Actor = string | null;
|
|
21
|
-
type Reason = string | null;
|
|
22
|
-
type Tool = string | null;
|
|
23
|
-
type ObjectType = string | null;
|
|
24
|
-
type ObjectKey = string | null;
|
|
25
|
-
type Subtype = string | null;
|
|
26
|
-
type Namespace = string | null;
|
|
27
|
-
type Subtype1 = string | null;
|
|
28
|
-
type Namespace1 = string | null;
|
|
29
|
-
type Aliases = ObservableAlias[];
|
|
30
|
-
type ThreatIntels = string[];
|
|
31
|
-
/**
|
|
32
|
-
* Direction of a relationship between observables.
|
|
33
|
-
*/
|
|
34
|
-
type RelationshipDirection = "outbound" | "inbound" | "bidirectional";
|
|
35
|
-
type Relationships = Relationship[];
|
|
36
|
-
/**
|
|
37
|
-
* Findings that currently link to this observable (navigation-only).
|
|
38
|
-
*/
|
|
39
|
-
type FindingLinks = string[];
|
|
40
|
-
/**
|
|
41
|
-
* Controls how a Finding↔Observable link propagates across merged investigations.
|
|
42
|
-
*/
|
|
43
|
-
type PropagationMode = "LOCAL_ONLY" | "GLOBAL";
|
|
44
|
-
type ObservableLinks = ObservableLink[];
|
|
45
|
-
type EvidenceLinks = EvidenceLink[];
|
|
46
|
-
type ExternalId = string | null;
|
|
47
|
-
type Uri = string | null;
|
|
48
|
-
/**
|
|
49
|
-
* Findings that currently link to this evidence (navigation-only).
|
|
50
|
-
*/
|
|
51
|
-
type FindingLinks1 = string[];
|
|
52
|
-
type Taxonomies = Taxonomy[];
|
|
53
|
-
type Findings1 = string[];
|
|
54
|
-
/**
|
|
55
|
-
* Root observable type used during data extraction.
|
|
56
|
-
*/
|
|
57
|
-
type RootType = ("file" | "artifact") | null;
|
|
58
|
-
/**
|
|
59
|
-
* Score calculation mode for observables.
|
|
60
|
-
*/
|
|
61
|
-
type ScoreMode = "max" | "sum";
|
|
62
|
-
/**
|
|
63
|
-
* Schema for a complete serialized investigation.
|
|
64
|
-
*
|
|
65
|
-
* This model describes the output of `serialize_investigation()` from
|
|
66
|
-
* `cyvest.io_serialization`. It is the top-level schema for exported investigations.
|
|
67
|
-
*
|
|
68
|
-
* Entity types reference the runtime models directly. When generating schemas with
|
|
69
|
-
* `mode='serialization'`, Pydantic respects field_serializer decorators and produces
|
|
70
|
-
* schemas matching the actual model_dump() output.
|
|
71
|
-
*/
|
|
72
|
-
interface CyvestInvestigation {
|
|
73
|
-
schema_version?: "6.0.0";
|
|
74
|
-
/**
|
|
75
|
-
* Stable investigation identity (ULID).
|
|
76
|
-
*/
|
|
77
|
-
investigation_id: string;
|
|
78
|
-
investigation_name?: InvestigationName;
|
|
79
|
-
/**
|
|
80
|
-
* Global investigation score.
|
|
81
|
-
*/
|
|
82
|
-
score: number;
|
|
83
|
-
level: Level;
|
|
84
|
-
/**
|
|
85
|
-
* Whether the investigation is whitelisted.
|
|
86
|
-
*/
|
|
87
|
-
whitelisted: boolean;
|
|
88
|
-
whitelists: Whitelists;
|
|
89
|
-
audit_log?: AuditLog;
|
|
90
|
-
observables: Observables;
|
|
91
|
-
findings: Findings;
|
|
92
|
-
evidences: Evidences;
|
|
93
|
-
threat_intels: ThreatIntels1;
|
|
94
|
-
enrichments: Enrichments;
|
|
95
|
-
tags: Tags;
|
|
96
|
-
stats: StatisticsSchema;
|
|
97
|
-
data_extraction: DataExtractionSchema;
|
|
98
|
-
/**
|
|
99
|
-
* Global investigation score formatted as fixed-point x.xx.
|
|
100
|
-
*/
|
|
101
|
-
score_display: string;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Represents a whitelist entry on an investigation.
|
|
105
|
-
*/
|
|
106
|
-
interface InvestigationWhitelist {
|
|
107
|
-
identifier: string;
|
|
108
|
-
name: string;
|
|
109
|
-
justification?: Justification;
|
|
110
|
-
[k: string]: unknown;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Centralized audit event for investigation-level changes.
|
|
114
|
-
*/
|
|
115
|
-
interface AuditEvent {
|
|
116
|
-
event_id: string;
|
|
117
|
-
timestamp: string;
|
|
118
|
-
event_type: string;
|
|
119
|
-
actor?: Actor;
|
|
120
|
-
reason?: Reason;
|
|
121
|
-
tool?: Tool;
|
|
122
|
-
object_type?: ObjectType;
|
|
123
|
-
object_key?: ObjectKey;
|
|
124
|
-
details?: Details;
|
|
125
|
-
[k: string]: unknown;
|
|
126
|
-
}
|
|
127
|
-
interface Details {
|
|
128
|
-
[k: string]: unknown;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Observables keyed by their unique key.
|
|
132
|
-
*/
|
|
133
|
-
interface Observables {
|
|
134
|
-
[k: string]: Observable;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Represents a cyber observable (IP, URL, domain, hash, etc.).
|
|
138
|
-
*
|
|
139
|
-
* Observables can be linked to threat intelligence, findings, and other observables
|
|
140
|
-
* through relationships.
|
|
141
|
-
*/
|
|
142
|
-
interface Observable {
|
|
143
|
-
type: string;
|
|
144
|
-
subtype?: Subtype;
|
|
145
|
-
namespace?: Namespace;
|
|
146
|
-
value: string;
|
|
147
|
-
internal: boolean;
|
|
148
|
-
whitelisted: boolean;
|
|
149
|
-
comment: string;
|
|
150
|
-
extra: Extra;
|
|
151
|
-
score: number;
|
|
152
|
-
level: Level;
|
|
153
|
-
aliases?: Aliases;
|
|
154
|
-
occurrence_count?: number;
|
|
155
|
-
threat_intels: ThreatIntels;
|
|
156
|
-
relationships: Relationships;
|
|
157
|
-
key: string;
|
|
158
|
-
finding_links: FindingLinks;
|
|
159
|
-
score_display: string;
|
|
160
|
-
[k: string]: unknown;
|
|
161
|
-
}
|
|
162
|
-
interface Extra {
|
|
163
|
-
[k: string]: unknown;
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Source observable identity attached to a canonical observable.
|
|
167
|
-
*/
|
|
168
|
-
interface ObservableAlias {
|
|
169
|
-
type: string;
|
|
170
|
-
subtype?: Subtype1;
|
|
171
|
-
namespace?: Namespace1;
|
|
172
|
-
value: string;
|
|
173
|
-
count?: number;
|
|
174
|
-
[k: string]: unknown;
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Represents a relationship between observables.
|
|
178
|
-
*/
|
|
179
|
-
interface Relationship {
|
|
180
|
-
target_key: string;
|
|
181
|
-
relationship_type: string;
|
|
182
|
-
direction: RelationshipDirection;
|
|
183
|
-
[k: string]: unknown;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Findings keyed by their unique key.
|
|
187
|
-
*/
|
|
188
|
-
interface Findings {
|
|
189
|
-
[k: string]: Finding;
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Represents a verification step in the investigation.
|
|
193
|
-
*
|
|
194
|
-
* A finding validates a specific aspect of the data under investigation
|
|
195
|
-
* and contributes to the overall investigation score.
|
|
196
|
-
*/
|
|
197
|
-
interface Finding {
|
|
198
|
-
finding_name: string;
|
|
199
|
-
description: string;
|
|
200
|
-
comment: string;
|
|
201
|
-
extra: Extra1;
|
|
202
|
-
score: number;
|
|
203
|
-
level: Level;
|
|
204
|
-
origin_investigation_id: string;
|
|
205
|
-
observable_links: ObservableLinks;
|
|
206
|
-
evidence_links: EvidenceLinks;
|
|
207
|
-
key: string;
|
|
208
|
-
score_display: string;
|
|
209
|
-
[k: string]: unknown;
|
|
210
|
-
}
|
|
211
|
-
interface Extra1 {
|
|
212
|
-
[k: string]: unknown;
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Edge metadata for a Finding↔Observable association.
|
|
216
|
-
*/
|
|
217
|
-
interface ObservableLink {
|
|
218
|
-
observable_key: string;
|
|
219
|
-
propagation_mode?: PropagationMode;
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Edge metadata for a Finding↔Evidence association.
|
|
223
|
-
*/
|
|
224
|
-
interface EvidenceLink {
|
|
225
|
-
evidence_key: string;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Evidence objects keyed by their unique key.
|
|
229
|
-
*/
|
|
230
|
-
interface Evidences {
|
|
231
|
-
[k: string]: Evidence;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Structured material supporting one or more findings.
|
|
235
|
-
*/
|
|
236
|
-
interface Evidence {
|
|
237
|
-
type: string;
|
|
238
|
-
title: string;
|
|
239
|
-
description: string;
|
|
240
|
-
source: string;
|
|
241
|
-
external_id: ExternalId;
|
|
242
|
-
content: unknown;
|
|
243
|
-
uri: Uri;
|
|
244
|
-
captured_at: string;
|
|
245
|
-
extra: Extra2;
|
|
246
|
-
key: string;
|
|
247
|
-
finding_links: FindingLinks1;
|
|
248
|
-
[k: string]: unknown;
|
|
249
|
-
}
|
|
250
|
-
interface Extra2 {
|
|
251
|
-
[k: string]: unknown;
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* Threat intelligence entries keyed by their unique key.
|
|
255
|
-
*/
|
|
256
|
-
interface ThreatIntels1 {
|
|
257
|
-
[k: string]: ThreatIntel;
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Represents threat intelligence from an external source.
|
|
261
|
-
*
|
|
262
|
-
* Threat intelligence provides verdicts about observables from sources
|
|
263
|
-
* like VirusTotal, URLScan.io, etc.
|
|
264
|
-
*/
|
|
265
|
-
interface ThreatIntel {
|
|
266
|
-
source: string;
|
|
267
|
-
observable_key: string;
|
|
268
|
-
comment: string;
|
|
269
|
-
extra: Extra3;
|
|
270
|
-
score: number;
|
|
271
|
-
level: Level;
|
|
272
|
-
taxonomies: Taxonomies;
|
|
273
|
-
key: string;
|
|
274
|
-
score_display: string;
|
|
275
|
-
[k: string]: unknown;
|
|
276
|
-
}
|
|
277
|
-
interface Extra3 {
|
|
278
|
-
[k: string]: unknown;
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Represents a structured taxonomy entry for threat intelligence.
|
|
282
|
-
*/
|
|
283
|
-
interface Taxonomy {
|
|
284
|
-
level: Level;
|
|
285
|
-
name: string;
|
|
286
|
-
value: string;
|
|
287
|
-
}
|
|
288
|
-
/**
|
|
289
|
-
* Enrichment entries keyed by their unique key.
|
|
1
|
+
//#region src/types.generated.d.ts
|
|
2
|
+
export type RootKey = string | null;
|
|
3
|
+
export type FragmentIds = string[];
|
|
4
|
+
export type OccurredAt = string | null;
|
|
5
|
+
/**
|
|
6
|
+
* Family a source belongs to, used by the policy to weigh its reliability.
|
|
290
7
|
*/
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
8
|
+
export type SourceClass = "vendor_feed" | "sandbox" | "osint" | "internal_tool" | "org_analyst" | "org_policy" | "unknown";
|
|
9
|
+
export type ExternalId = string | null;
|
|
10
|
+
export type EvidenceKeys = string[];
|
|
11
|
+
export type Subtype = string | null;
|
|
12
|
+
export type Namespace = string | null;
|
|
13
|
+
export type Subtype1 = string | null;
|
|
14
|
+
export type Namespace1 = string | null;
|
|
15
|
+
export type Aliases = ObservableAlias[];
|
|
16
|
+
export type OccurredAt1 = string | null;
|
|
17
|
+
export type ExternalId1 = string | null;
|
|
18
|
+
export type EvidenceKeys1 = string[];
|
|
294
19
|
/**
|
|
295
|
-
*
|
|
20
|
+
* The analyst pivot that produced the target from the source.
|
|
296
21
|
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
[k: string]: unknown;
|
|
306
|
-
}
|
|
307
|
-
interface Data {
|
|
308
|
-
[k: string]: unknown;
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Tags keyed by their unique key.
|
|
312
|
-
*/
|
|
313
|
-
interface Tags {
|
|
314
|
-
[k: string]: Tag;
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Groups findings for categorical organization.
|
|
22
|
+
* Direction is implied: ``source_key`` is the parent, ``target_key`` the child. ``RELATED_TO``
|
|
23
|
+
* is symmetric and excluded from propagation, which makes v6's ``EXTRACTION`` +
|
|
24
|
+
* ``BIDIRECTIONAL`` combination inexpressible.
|
|
25
|
+
*/
|
|
26
|
+
export type RelationKind = "extraction" | "pivot" | "related-to";
|
|
27
|
+
export type ObservedAt = string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Direction of a judgment, and the displayed level — they are the same thing.
|
|
318
30
|
*
|
|
319
|
-
*
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
31
|
+
* v7 merges the former ``Level`` into ``Verdict``. The five values line up one-for-one with
|
|
32
|
+
* the score bands ``basic-v1`` inherits from v6 (``< 0``, ``= 0``, ``]0,3[``, ``[3,5[``,
|
|
33
|
+
* ``>= 5``), which makes a verdict/level divergence structurally impossible.
|
|
34
|
+
*
|
|
35
|
+
* Those bands are ``basic-v1``'s convention, **not** part of the enum's contract: a
|
|
36
|
+
* probabilistic engine maps its own posterior thresholds onto the same labels.
|
|
37
|
+
*
|
|
38
|
+
* Two v6 levels deliberately left this axis: ``NONE`` became :class:`Status` and ``TRUSTED``
|
|
39
|
+
* became a :class:`DecisionKind` (or plain ``SAFE`` when it was merely a negative score).
|
|
40
|
+
*/
|
|
41
|
+
export type Verdict = "SAFE" | "INFO" | "NOTABLE" | "SUSPICIOUS" | "MALICIOUS";
|
|
42
|
+
export type Weight = number | null;
|
|
43
|
+
export type OccurredAt2 = string | null;
|
|
44
|
+
export type ExternalId2 = string | null;
|
|
45
|
+
export type EvidenceKeys2 = string[];
|
|
46
|
+
export type ObservedAt1 = string | null;
|
|
47
|
+
export type Labels = Label[];
|
|
48
|
+
export type Taxonomies = string[];
|
|
49
|
+
export type OccurredAt3 = string | null;
|
|
50
|
+
export type ExternalId3 = string | null;
|
|
51
|
+
export type EvidenceKeys3 = string[];
|
|
52
|
+
export type Uri = string | null;
|
|
53
|
+
export type CapturedAt = string | null;
|
|
54
|
+
export type Weight1 = number | null;
|
|
55
|
+
export type OccurredAt4 = string | null;
|
|
56
|
+
export type ExternalId4 = string | null;
|
|
57
|
+
export type EvidenceKeys4 = string[];
|
|
58
|
+
/**
|
|
59
|
+
* Whether a finding takes part in the evaluation at all.
|
|
60
|
+
*
|
|
61
|
+
* Anything other than ``EVALUATED`` is excluded from the score *and* from aggregation
|
|
62
|
+
* denominators, while staying visible in the report.
|
|
63
|
+
*/
|
|
64
|
+
export type Status = "NOT_APPLICABLE" | "PENDING" | "EVALUATED";
|
|
65
|
+
/**
|
|
66
|
+
* How a finding enters the investigation total. :class:`Status` says *whether*, this says *how*.
|
|
67
|
+
*
|
|
68
|
+
* ``ADDITIVE`` is every finding v6 ever had: a term of the sum.
|
|
69
|
+
*
|
|
70
|
+
* ``FLOOR`` and ``CEILING`` are the two halves of a **conclusion** — typically an analysis that
|
|
71
|
+
* read the other findings. Neither is a term: a floor raises the total just enough to reach the
|
|
72
|
+
* verdict it asserts, a ceiling lowers it just enough. Both add nothing once the investigation
|
|
73
|
+
* is already there, so conclusions never compound and several analysers may conclude on the
|
|
74
|
+
* same case without inflating — or deflating — each other.
|
|
75
|
+
*
|
|
76
|
+
* A ceiling is what states a **declared benign context**: an awareness campaign, a sanctioned
|
|
77
|
+
* pentest window, an authorised scanner. Without it the model could force a case up but never
|
|
78
|
+
* down, and the only way to say "whatever the evidence, this is benign" would be to guess a
|
|
79
|
+
* large negative weight — the v6 mistake.
|
|
80
|
+
*
|
|
81
|
+
* The band a verdict maps to is ``basic-v1``'s convention, like every other number here — see
|
|
82
|
+
* :mod:`cyvest.evaluation.projection`.
|
|
83
|
+
*/
|
|
84
|
+
export type Effect = "ADDITIVE" | "FLOOR" | "CEILING";
|
|
85
|
+
/**
|
|
86
|
+
* What a Finding→Observable link scores on.
|
|
87
|
+
*
|
|
88
|
+
* One question, three answers, none of which depends on how the run was threaded:
|
|
89
|
+
*
|
|
90
|
+
* - ``OBSERVABLE`` — the observable as it stands, whoever contributed to it;
|
|
91
|
+
* - ``SIGNALS`` — the signals the link names, and nothing else, which is how a finding that
|
|
92
|
+
* fetched its own threat intel holds that value while the observable keeps accumulating;
|
|
93
|
+
* - ``NONE`` — nothing: the edge is kept for the graph and the narrative, but it is inert.
|
|
94
|
+
*
|
|
95
|
+
* v7.0 briefly carried a fourth, ``FRAGMENT``, gating the observable on the fragment that wrote
|
|
96
|
+
* each fact. It was dropped before release: it damped a merged total but never a local one, so
|
|
97
|
+
* the same rules scored differently depending on whether enrichment ran in its own worker.
|
|
98
|
+
* ``SIGNALS`` states that intent directly, and ``NONE`` covers the inert link it was standing in
|
|
99
|
+
* for when migrating v6 documents.
|
|
100
|
+
*/
|
|
101
|
+
export type LinkBasis = "OBSERVABLE" | "SIGNALS" | "NONE";
|
|
102
|
+
export type SignalKeys = string[];
|
|
103
|
+
export type ObservableLinks = ObservableLink[];
|
|
104
|
+
export type Labels1 = Label[];
|
|
105
|
+
/**
|
|
106
|
+
* A MITRE ATT&CK Enterprise tactic — the phase of the kill chain a finding demonstrates.
|
|
107
|
+
*
|
|
108
|
+
* Kebab-case values, in kill-chain order. A tactic is a classification the timeline displays,
|
|
109
|
+
* never a term the engine scores: whether the activity is malicious is the verdict's job.
|
|
110
|
+
*/
|
|
111
|
+
export type Tactic = "reconnaissance" | "resource-development" | "initial-access" | "execution" | "persistence" | "privilege-escalation" | "defense-evasion" | "credential-access" | "discovery" | "lateral-movement" | "collection" | "command-and-control" | "exfiltration" | "impact";
|
|
112
|
+
export type OccurredAt5 = string | null;
|
|
113
|
+
export type ExternalId5 = string | null;
|
|
114
|
+
export type EvidenceKeys5 = string[];
|
|
115
|
+
/**
|
|
116
|
+
* A named override of the computation.
|
|
117
|
+
*
|
|
118
|
+
* Forcing a score has to be a declared act — never the side effect of an inflated weight.
|
|
342
119
|
*
|
|
343
|
-
*
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
interface
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
[k: string]: number;
|
|
383
|
-
}
|
|
384
|
-
interface ThreatIntelBySource {
|
|
385
|
-
[k: string]: number;
|
|
386
|
-
}
|
|
387
|
-
interface ThreatIntelByLevel {
|
|
388
|
-
[k: string]: number;
|
|
389
|
-
}
|
|
390
|
-
/**
|
|
391
|
-
* Schema for data extraction metadata.
|
|
120
|
+
* The kind states the **intent**; the mechanism follows from the family of the target, which
|
|
121
|
+
* the key already carries. An earlier design enumerated one value per ``(intent, family)``
|
|
122
|
+
* pair — ``ALLOWLISTED``/``BLOCKLISTED``/``CONFIRMED``/``DISMISSED`` — and then needed a
|
|
123
|
+
* validator to forbid the half of that product which made no sense. An enum requiring a
|
|
124
|
+
* validator to reject half its combinations encodes one axis too many: the family is the
|
|
125
|
+
* target's business, not the decision's.
|
|
126
|
+
*
|
|
127
|
+
* The domain vocabulary survives untouched on the façade (``allowlist``, ``blocklist``,
|
|
128
|
+
* ``confirm``, ``dismiss``), where it belongs.
|
|
129
|
+
*/
|
|
130
|
+
export type DecisionKind = "UPHOLD" | "REFUTE" | "VACATED";
|
|
131
|
+
export type OccurredAt6 = string | null;
|
|
132
|
+
export type ExternalId6 = string | null;
|
|
133
|
+
export type EvidenceKeys6 = string[];
|
|
134
|
+
export type FindingKeys = string[];
|
|
135
|
+
export type Score = number | null;
|
|
136
|
+
export type Contributions = Contribution[];
|
|
137
|
+
export type Score1 = number | null;
|
|
138
|
+
export type Contributions1 = Contribution[];
|
|
139
|
+
export type Score2 = number | null;
|
|
140
|
+
export type Contributions2 = Contribution[];
|
|
141
|
+
/**
|
|
142
|
+
* A complete serialized investigation.
|
|
143
|
+
*/
|
|
144
|
+
export interface InvestigationSchema {
|
|
145
|
+
schema_version?: string;
|
|
146
|
+
header: InvestigationHeader;
|
|
147
|
+
policy_version?: string;
|
|
148
|
+
engine_id?: string;
|
|
149
|
+
facts?: FactsSchema;
|
|
150
|
+
decisions?: Decisions;
|
|
151
|
+
tags?: Tags;
|
|
152
|
+
report: Report;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* What used to be a ``Case`` fact: metadata about the store rather than a fact inside it.
|
|
156
|
+
*
|
|
157
|
+
* ``engine_id`` is denormalized here so an investigation stays replayable identically years
|
|
158
|
+
* later, even after a newer stable engine ships.
|
|
392
159
|
*/
|
|
393
|
-
interface
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
160
|
+
export interface InvestigationHeader {
|
|
161
|
+
investigation_id: string;
|
|
162
|
+
name?: string;
|
|
163
|
+
root_key?: RootKey;
|
|
164
|
+
opened_at?: string;
|
|
165
|
+
policy_version?: string;
|
|
166
|
+
engine_id?: string;
|
|
167
|
+
fragment_ids?: FragmentIds;
|
|
168
|
+
[k: string]: unknown;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* The fact collections, each keyed by its semantic key.
|
|
172
|
+
*/
|
|
173
|
+
export interface FactsSchema {
|
|
174
|
+
observables?: Observables;
|
|
175
|
+
relations?: Relations;
|
|
176
|
+
signals?: Signals;
|
|
177
|
+
evidences?: Evidences;
|
|
178
|
+
findings?: Findings;
|
|
179
|
+
}
|
|
180
|
+
export interface Observables {
|
|
181
|
+
[k: string]: Observable;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* A cyber observable. Identity is ``(type, subtype, namespace, value)``, nothing else.
|
|
185
|
+
*/
|
|
186
|
+
export interface Observable {
|
|
187
|
+
key: string;
|
|
188
|
+
seq: string;
|
|
189
|
+
asserted_at: string;
|
|
190
|
+
occurred_at?: OccurredAt;
|
|
191
|
+
source: SourceRef;
|
|
192
|
+
fragment_id: string;
|
|
193
|
+
external_id?: ExternalId;
|
|
194
|
+
evidence_keys?: EvidenceKeys;
|
|
195
|
+
type: string;
|
|
196
|
+
subtype?: Subtype;
|
|
197
|
+
namespace?: Namespace;
|
|
198
|
+
value: string;
|
|
199
|
+
internal?: boolean;
|
|
200
|
+
comment?: string;
|
|
201
|
+
extra?: Extra;
|
|
202
|
+
aliases?: Aliases;
|
|
203
|
+
occurrences?: Occurrences;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Who or what asserted a fact.
|
|
207
|
+
*/
|
|
208
|
+
export interface SourceRef {
|
|
209
|
+
name: string;
|
|
210
|
+
source_class?: SourceClass;
|
|
211
|
+
[k: string]: unknown;
|
|
212
|
+
}
|
|
213
|
+
export interface Extra {
|
|
214
|
+
[k: string]: unknown;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* A source identity that resolved to a canonical observable.
|
|
218
|
+
*/
|
|
219
|
+
export interface ObservableAlias {
|
|
220
|
+
type: string;
|
|
221
|
+
subtype?: Subtype1;
|
|
222
|
+
namespace?: Namespace1;
|
|
223
|
+
value: string;
|
|
224
|
+
counts?: Counts;
|
|
225
|
+
[k: string]: unknown;
|
|
226
|
+
}
|
|
227
|
+
export interface Counts {
|
|
228
|
+
[k: string]: number;
|
|
229
|
+
}
|
|
230
|
+
export interface Occurrences {
|
|
231
|
+
[k: string]: number;
|
|
232
|
+
}
|
|
233
|
+
export interface Relations {
|
|
234
|
+
[k: string]: Relation;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* A directed edge between two observables, labelled by the analyst pivot that produced it.
|
|
238
|
+
*/
|
|
239
|
+
export interface Relation {
|
|
240
|
+
key: string;
|
|
241
|
+
seq: string;
|
|
242
|
+
asserted_at: string;
|
|
243
|
+
occurred_at?: OccurredAt1;
|
|
244
|
+
source: SourceRef;
|
|
245
|
+
fragment_id: string;
|
|
246
|
+
external_id?: ExternalId1;
|
|
247
|
+
evidence_keys?: EvidenceKeys1;
|
|
248
|
+
source_key: string;
|
|
249
|
+
target_key: string;
|
|
250
|
+
kind?: RelationKind;
|
|
251
|
+
observed_at?: ObservedAt;
|
|
252
|
+
confidence?: number;
|
|
253
|
+
comment?: string;
|
|
254
|
+
}
|
|
255
|
+
export interface Signals {
|
|
256
|
+
[k: string]: ThreatIntel;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* A verdict from a threat-intelligence source.
|
|
260
|
+
*
|
|
261
|
+
* Identity is ``(source, subject_key)``, so a source re-asserting the same observable updates
|
|
262
|
+
* in place instead of piling up duplicates. Pass ``external_id`` to keep history on purpose.
|
|
263
|
+
*/
|
|
264
|
+
export interface ThreatIntel {
|
|
265
|
+
verdict?: Verdict;
|
|
266
|
+
confidence?: number;
|
|
267
|
+
weight?: Weight;
|
|
268
|
+
key: string;
|
|
269
|
+
seq: string;
|
|
270
|
+
asserted_at: string;
|
|
271
|
+
occurred_at?: OccurredAt2;
|
|
272
|
+
source: SourceRef;
|
|
273
|
+
fragment_id: string;
|
|
274
|
+
external_id?: ExternalId2;
|
|
275
|
+
evidence_keys?: EvidenceKeys2;
|
|
276
|
+
subject_key: string;
|
|
277
|
+
kind?: "threat_intel";
|
|
278
|
+
observed_at?: ObservedAt1;
|
|
279
|
+
labels?: Labels;
|
|
280
|
+
payload?: Payload;
|
|
281
|
+
source_class?: SourceClass;
|
|
282
|
+
taxonomies?: Taxonomies;
|
|
283
|
+
comment?: string;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* A typed tag on a fact: ``axis`` says what kind of statement ``value`` makes.
|
|
287
|
+
*/
|
|
288
|
+
export interface Label {
|
|
289
|
+
axis: string;
|
|
290
|
+
value: string;
|
|
291
|
+
[k: string]: unknown;
|
|
292
|
+
}
|
|
293
|
+
export interface Payload {
|
|
294
|
+
[k: string]: unknown;
|
|
295
|
+
}
|
|
296
|
+
export interface Evidences {
|
|
297
|
+
[k: string]: Evidence;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* A captured artefact: an API response, a header dump, an enrichment payload.
|
|
301
|
+
*/
|
|
302
|
+
export interface Evidence {
|
|
303
|
+
key: string;
|
|
304
|
+
seq: string;
|
|
305
|
+
asserted_at: string;
|
|
306
|
+
occurred_at?: OccurredAt3;
|
|
307
|
+
source: SourceRef;
|
|
308
|
+
fragment_id: string;
|
|
309
|
+
external_id?: ExternalId3;
|
|
310
|
+
evidence_keys?: EvidenceKeys3;
|
|
311
|
+
evidence_type: string;
|
|
312
|
+
title?: string;
|
|
313
|
+
content?: Content;
|
|
314
|
+
uri?: Uri;
|
|
315
|
+
captured_at?: CapturedAt;
|
|
316
|
+
}
|
|
317
|
+
export interface Content {
|
|
318
|
+
[k: string]: unknown;
|
|
319
|
+
}
|
|
320
|
+
export interface Findings {
|
|
321
|
+
[k: string]: Finding;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* A rule outcome. Identity is ``rule_id`` alone, plus ``external_id`` when one is given.
|
|
325
|
+
*
|
|
326
|
+
* A finding names no subject: what it is about is its ``observable_links``, which are also what
|
|
327
|
+
* it scores on. Use ``external_id`` when the same rule must yield several findings — typically
|
|
328
|
+
* once per observable, ``external_id=url.key``.
|
|
329
|
+
*
|
|
330
|
+
* A finding that describes an activity is **dated** through the envelope's ``occurred_at`` —
|
|
331
|
+
* when the activity happened, as opposed to when the rule fired — and may name the ATT&CK
|
|
332
|
+
* ``tactic`` it demonstrates. Both are what the timeline reads; neither enters the score.
|
|
333
|
+
*/
|
|
334
|
+
export interface Finding {
|
|
335
|
+
verdict?: Verdict;
|
|
336
|
+
confidence?: number;
|
|
337
|
+
weight?: Weight1;
|
|
338
|
+
key: string;
|
|
339
|
+
seq: string;
|
|
340
|
+
asserted_at: string;
|
|
341
|
+
occurred_at?: OccurredAt4;
|
|
342
|
+
source: SourceRef;
|
|
343
|
+
fragment_id: string;
|
|
344
|
+
external_id?: ExternalId4;
|
|
345
|
+
evidence_keys?: EvidenceKeys4;
|
|
346
|
+
rule_id: string;
|
|
347
|
+
rule_version?: string;
|
|
348
|
+
name?: string;
|
|
349
|
+
comment?: string;
|
|
350
|
+
status?: Status;
|
|
351
|
+
effect?: Effect;
|
|
352
|
+
observable_links?: ObservableLinks;
|
|
353
|
+
labels?: Labels1;
|
|
354
|
+
tactic?: Tactic | null;
|
|
355
|
+
extra?: Extra1;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* A link from a finding to one of its observables, with the basis it is evaluated on.
|
|
359
|
+
*
|
|
360
|
+
* Basis is **per link**, exactly like v6's ``propagation_mode``: a finding may mix bases, and
|
|
361
|
+
* may even link the same observable twice under two of them. Deduplication is on the triple
|
|
362
|
+
* ``(observable_key, basis, signal_keys)``.
|
|
363
|
+
*
|
|
364
|
+
* ``signal_keys`` is sorted and deduplicated so that two links naming the same signals in a
|
|
365
|
+
* different order are the same link, and merging stays idempotent.
|
|
366
|
+
*/
|
|
367
|
+
export interface ObservableLink {
|
|
368
|
+
observable_key: string;
|
|
369
|
+
basis?: LinkBasis;
|
|
370
|
+
signal_keys?: SignalKeys;
|
|
371
|
+
[k: string]: unknown;
|
|
372
|
+
}
|
|
373
|
+
export interface Extra1 {
|
|
374
|
+
[k: string]: unknown;
|
|
375
|
+
}
|
|
376
|
+
export interface Decisions {
|
|
377
|
+
[k: string]: Decision;
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* A human (or automated) call that overrides the computed result for one target.
|
|
381
|
+
*
|
|
382
|
+
* ``UPHOLD`` forces the target to the policy floor, ``REFUTE`` neutralises it, ``VACATED``
|
|
383
|
+
* withdraws a previous stance and restores the computed value. How each is applied depends on
|
|
384
|
+
* the family of the target — an observable is bounded, a claim is taken out of the count — but
|
|
385
|
+
* that is the engine's dispatch, not a second axis of this model.
|
|
386
|
+
*
|
|
387
|
+
* ``justification`` is required: an override whose reason is optional is an override that
|
|
388
|
+
* cannot be audited, which defeats the point of recording it as a fact at all.
|
|
389
|
+
*/
|
|
390
|
+
export interface Decision {
|
|
391
|
+
key: string;
|
|
392
|
+
seq: string;
|
|
393
|
+
asserted_at: string;
|
|
394
|
+
occurred_at?: OccurredAt5;
|
|
395
|
+
source: SourceRef;
|
|
396
|
+
fragment_id: string;
|
|
397
|
+
external_id?: ExternalId5;
|
|
398
|
+
evidence_keys?: EvidenceKeys5;
|
|
399
|
+
target_key: string;
|
|
400
|
+
kind: DecisionKind;
|
|
401
|
+
justification: string;
|
|
402
|
+
}
|
|
403
|
+
export interface Tags {
|
|
404
|
+
[k: string]: Tag;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* A label grouping findings. Merging two tags unions their finding keys.
|
|
408
|
+
*/
|
|
409
|
+
export interface Tag {
|
|
410
|
+
key: string;
|
|
411
|
+
seq: string;
|
|
412
|
+
asserted_at: string;
|
|
413
|
+
occurred_at?: OccurredAt6;
|
|
414
|
+
source: SourceRef;
|
|
415
|
+
fragment_id: string;
|
|
416
|
+
external_id?: ExternalId6;
|
|
417
|
+
evidence_keys?: EvidenceKeys6;
|
|
418
|
+
name: string;
|
|
419
|
+
description?: string;
|
|
420
|
+
finding_keys?: FindingKeys;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* A full evaluation. Derived, never stored on the facts, recomputed from them.
|
|
424
|
+
*/
|
|
425
|
+
export interface Report {
|
|
426
|
+
engine_id: string;
|
|
427
|
+
policy_version: string;
|
|
428
|
+
investigation: InvestigationResult;
|
|
429
|
+
findings?: Findings1;
|
|
430
|
+
observables?: Observables1;
|
|
431
|
+
[k: string]: unknown;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* The investigation-level verdict.
|
|
435
|
+
*/
|
|
436
|
+
export interface InvestigationResult {
|
|
437
|
+
key: string;
|
|
438
|
+
verdict?: Verdict;
|
|
439
|
+
confidence?: number;
|
|
440
|
+
score?: Score;
|
|
441
|
+
contributions?: Contributions;
|
|
442
|
+
suppressed_by_decision?: boolean;
|
|
443
|
+
raw?: Raw;
|
|
444
|
+
[k: string]: unknown;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* One named term that fed a result, kept so the report can explain itself.
|
|
448
|
+
*/
|
|
449
|
+
export interface Contribution {
|
|
450
|
+
source_key: string;
|
|
451
|
+
label: string;
|
|
452
|
+
value: number;
|
|
453
|
+
retained?: boolean;
|
|
454
|
+
detail?: string;
|
|
455
|
+
[k: string]: unknown;
|
|
456
|
+
}
|
|
457
|
+
export interface Raw {
|
|
458
|
+
[k: string]: unknown;
|
|
459
|
+
}
|
|
460
|
+
export interface Findings1 {
|
|
461
|
+
[k: string]: FindingResult;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* A finding's verdict.
|
|
465
|
+
*
|
|
466
|
+
* ``own_term_suppressed`` flags that the rule's own claim was overridden by a stronger link —
|
|
467
|
+
* a contradiction worth surfacing rather than silently dropping.
|
|
468
|
+
*
|
|
469
|
+
* Three combinations of ``(counted, score)`` are meaningful, and a consumer must not conflate
|
|
470
|
+
* the last two:
|
|
471
|
+
*
|
|
472
|
+
* - ``(True, float)`` — an additive finding, a term of the total;
|
|
473
|
+
* - ``(False, None)`` — dismissed or not evaluated: visible, but out of the evaluation;
|
|
474
|
+
* - ``(True, None)`` — a conclusion (``effect`` is ``FLOOR`` or ``CEILING``): it takes part, but
|
|
475
|
+
* it has no magnitude of its own. Its effect is a bound on the investigation total, reported
|
|
476
|
+
* as a contribution of :class:`InvestigationResult`.
|
|
477
|
+
*/
|
|
478
|
+
export interface FindingResult {
|
|
479
|
+
key: string;
|
|
480
|
+
verdict?: Verdict;
|
|
481
|
+
confidence?: number;
|
|
482
|
+
score?: Score1;
|
|
483
|
+
contributions?: Contributions1;
|
|
484
|
+
suppressed_by_decision?: boolean;
|
|
485
|
+
raw?: Raw1;
|
|
486
|
+
status?: Status;
|
|
487
|
+
effect?: Effect;
|
|
488
|
+
own_term_suppressed?: boolean;
|
|
489
|
+
counted?: boolean;
|
|
490
|
+
[k: string]: unknown;
|
|
491
|
+
}
|
|
492
|
+
export interface Raw1 {
|
|
493
|
+
[k: string]: unknown;
|
|
494
|
+
}
|
|
495
|
+
export interface Observables1 {
|
|
496
|
+
[k: string]: ObservableResult;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* An observable's verdict. One per observable: the graph holds every fact anyone contributed.
|
|
500
|
+
*/
|
|
501
|
+
export interface ObservableResult {
|
|
502
|
+
key: string;
|
|
503
|
+
verdict?: Verdict;
|
|
504
|
+
confidence?: number;
|
|
505
|
+
score?: Score2;
|
|
506
|
+
contributions?: Contributions2;
|
|
507
|
+
suppressed_by_decision?: boolean;
|
|
508
|
+
raw?: Raw2;
|
|
509
|
+
[k: string]: unknown;
|
|
510
|
+
}
|
|
511
|
+
export interface Raw2 {
|
|
512
|
+
[k: string]: unknown;
|
|
513
|
+
}
|
|
514
|
+
//#endregion
|
|
515
|
+
//#region src/types.d.ts
|
|
516
|
+
type Investigation = InvestigationSchema;
|
|
517
|
+
type Observable$1 = Observable;
|
|
518
|
+
type Relation$1 = Relation;
|
|
519
|
+
type ThreatIntel$1 = ThreatIntel;
|
|
520
|
+
type Evidence$1 = Evidence;
|
|
521
|
+
type Finding$1 = Finding;
|
|
522
|
+
type Decision$1 = Decision;
|
|
523
|
+
type Tag$1 = Tag;
|
|
524
|
+
type ObservableResult$1 = ObservableResult;
|
|
525
|
+
type FindingResult$1 = FindingResult;
|
|
526
|
+
type InvestigationResult$1 = InvestigationResult;
|
|
527
|
+
//#endregion
|
|
528
|
+
//#region src/helpers.d.ts
|
|
529
|
+
export declare const SCHEMA_VERSION = "7.0.0";
|
|
530
|
+
/**
|
|
531
|
+
* Read the declared schema version, falling back to `"5"` for anything unversioned.
|
|
532
|
+
*
|
|
533
|
+
* A document with no `schema_version` is a pre-v7 document, not a current one: `schema_version`
|
|
534
|
+
* is not in the schema's `required` list, so defaulting it to `SCHEMA_VERSION` would wave every
|
|
535
|
+
* legacy payload straight through. Python's `detect_schema_version` makes the same choice.
|
|
536
|
+
*/
|
|
537
|
+
export declare function detectSchemaVersion(json: unknown): string;
|
|
538
|
+
/** Upward compatibility only: read older documents, never newer ones. */
|
|
539
|
+
export declare function assertReadableVersion(version: string): void;
|
|
540
|
+
export declare function parseCyvest(json: unknown): Investigation;
|
|
541
|
+
export declare function isCyvest(json: unknown): json is Investigation;
|
|
542
|
+
//#endregion
|
|
543
|
+
//#region src/keys.d.ts
|
|
401
544
|
/**
|
|
402
545
|
* Key generation utilities for Cyvest objects.
|
|
403
546
|
*
|
|
@@ -407,7 +550,9 @@ declare function isCyvest(json: unknown): json is CyvestInvestigation;
|
|
|
407
550
|
/**
|
|
408
551
|
* Key type prefixes used in Cyvest.
|
|
409
552
|
*/
|
|
410
|
-
type KeyType = "obs" | "fnd" | "evd" | "
|
|
553
|
+
export type KeyType = "obs" | "fnd" | "evd" | "sig" | "rel" | "dec" | "tag";
|
|
554
|
+
/** Every prefix a v7 document can carry. `enr:` is gone — enrichments are evidence now. */
|
|
555
|
+
export declare const KEY_PREFIXES: readonly KeyType[];
|
|
411
556
|
/**
|
|
412
557
|
* Generate a unique key for an observable.
|
|
413
558
|
*
|
|
@@ -423,57 +568,53 @@ type KeyType = "obs" | "fnd" | "evd" | "ti" | "enr" | "tag";
|
|
|
423
568
|
* // => "obs:ipv4:192.168.1.1"
|
|
424
569
|
* ```
|
|
425
570
|
*/
|
|
426
|
-
declare function generateObservableKey(obsType: string, value: string, subtype?: string, namespace?: string): string;
|
|
571
|
+
export declare function generateObservableKey(obsType: string, value: string, subtype?: string, namespace?: string): string;
|
|
427
572
|
/**
|
|
428
|
-
* Generate a
|
|
573
|
+
* Generate a finding key.
|
|
429
574
|
*
|
|
430
|
-
* Format: fnd:{
|
|
575
|
+
* Format: `fnd:{rule_id}`, or `fnd:{rule_id}:{external_id}`.
|
|
431
576
|
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
577
|
+
* A finding is identified by the rule that produced it. Running the same rule on several
|
|
578
|
+
* observables means several findings, so pass an `externalId` to keep them apart — usually the
|
|
579
|
+
* observable key.
|
|
434
580
|
*
|
|
435
581
|
* @example
|
|
436
582
|
* ```ts
|
|
437
|
-
* generateFindingKey("
|
|
438
|
-
* // => "fnd:
|
|
583
|
+
* generateFindingKey("url_in_body")
|
|
584
|
+
* // => "fnd:url_in_body"
|
|
439
585
|
* ```
|
|
440
586
|
*/
|
|
441
|
-
declare function generateFindingKey(
|
|
587
|
+
export declare function generateFindingKey(ruleId: string, externalId?: string): string;
|
|
442
588
|
/**
|
|
443
|
-
* Generate
|
|
444
|
-
*
|
|
445
|
-
* Format: ti:{normalized_source}:{observable_key}
|
|
589
|
+
* Generate an observable-signal key.
|
|
446
590
|
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
* @returns Unique threat intel key
|
|
591
|
+
* Format: `sig:{source}:{subject_key}`. The prefix names the *family*, not its first member:
|
|
592
|
+
* v6's `ti:` would have locked every future signal kind behind a threat-intel name.
|
|
450
593
|
*
|
|
451
594
|
* @example
|
|
452
595
|
* ```ts
|
|
453
|
-
*
|
|
454
|
-
* // => "
|
|
596
|
+
* generateSignalKey("virustotal", "obs:ipv4:192.168.1.1")
|
|
597
|
+
* // => "sig:virustotal:obs:ipv4:192.168.1.1"
|
|
455
598
|
* ```
|
|
456
599
|
*/
|
|
457
|
-
declare function
|
|
600
|
+
export declare function generateSignalKey(source: string, subjectKey: string, externalId?: string): string;
|
|
601
|
+
/** Kept under its v6 name; new code calls {@link generateSignalKey}. */
|
|
602
|
+
export declare const generateThreatIntelKey: typeof generateSignalKey;
|
|
458
603
|
/**
|
|
459
|
-
* Generate a
|
|
604
|
+
* Generate a relation key.
|
|
460
605
|
*
|
|
461
|
-
* Format:
|
|
462
|
-
*
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
*
|
|
467
|
-
* @example
|
|
468
|
-
* ```ts
|
|
469
|
-
* generateEnrichmentKey("whois_data")
|
|
470
|
-
* // => "enr:whois_data"
|
|
606
|
+
* Format: `rel:{kind}:{source_key}>{target_key}` — direction lives in the key itself, so no
|
|
607
|
+
* `direction` field is needed to disambiguate.
|
|
608
|
+
*/
|
|
609
|
+
export declare function generateRelationKey(sourceKey: string, targetKey: string, kind: string, externalId?: string): string;
|
|
610
|
+
/**
|
|
611
|
+
* Generate a decision key.
|
|
471
612
|
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
474
|
-
*
|
|
613
|
+
* Format: `dec:{target_key}` — one decision per target, whatever it says. The kind is content,
|
|
614
|
+
* not identity: a target holds a single current stance, and changing one's mind is a
|
|
615
|
+
* re-assertion the merge law settles by freshness.
|
|
475
616
|
*/
|
|
476
|
-
declare function
|
|
617
|
+
export declare function generateDecisionKey(targetKey: string): string;
|
|
477
618
|
/**
|
|
478
619
|
* Generate a unique key for a tag.
|
|
479
620
|
*
|
|
@@ -488,7 +629,7 @@ declare function generateEnrichmentKey(name: string, context?: string): string;
|
|
|
488
629
|
* // => "tag:header:auth:dkim"
|
|
489
630
|
* ```
|
|
490
631
|
*/
|
|
491
|
-
declare function generateTagKey(name: string): string;
|
|
632
|
+
export declare function generateTagKey(name: string): string;
|
|
492
633
|
/**
|
|
493
634
|
* Get all ancestor tag names from a hierarchical tag name.
|
|
494
635
|
*
|
|
@@ -501,7 +642,7 @@ declare function generateTagKey(name: string): string;
|
|
|
501
642
|
* // => ["header", "header:auth"]
|
|
502
643
|
* ```
|
|
503
644
|
*/
|
|
504
|
-
declare function getTagAncestors(name: string): string[];
|
|
645
|
+
export declare function getTagAncestors(name: string): string[];
|
|
505
646
|
/**
|
|
506
647
|
* Check if a tag is a direct child of another tag.
|
|
507
648
|
*
|
|
@@ -515,7 +656,7 @@ declare function getTagAncestors(name: string): string[];
|
|
|
515
656
|
* isTagChildOf("header:auth:dkim", "header") // => false (grandchild)
|
|
516
657
|
* ```
|
|
517
658
|
*/
|
|
518
|
-
declare function isTagChildOf(childName: string, parentName: string): boolean;
|
|
659
|
+
export declare function isTagChildOf(childName: string, parentName: string): boolean;
|
|
519
660
|
/**
|
|
520
661
|
* Check if a tag is a descendant of another tag (any depth).
|
|
521
662
|
*
|
|
@@ -529,12 +670,12 @@ declare function isTagChildOf(childName: string, parentName: string): boolean;
|
|
|
529
670
|
* isTagDescendantOf("header", "header") // => false (same)
|
|
530
671
|
* ```
|
|
531
672
|
*/
|
|
532
|
-
declare function isTagDescendantOf(descendantName: string, ancestorName: string): boolean;
|
|
673
|
+
export declare function isTagDescendantOf(descendantName: string, ancestorName: string): boolean;
|
|
533
674
|
/**
|
|
534
675
|
* Extract the type prefix from a key.
|
|
535
676
|
*
|
|
536
677
|
* @param key - The key to parse
|
|
537
|
-
* @returns Type prefix (
|
|
678
|
+
* @returns Type prefix (see {@link KEY_PREFIXES}) or null if invalid
|
|
538
679
|
*
|
|
539
680
|
* @example
|
|
540
681
|
* ```ts
|
|
@@ -542,7 +683,7 @@ declare function isTagDescendantOf(descendantName: string, ancestorName: string)
|
|
|
542
683
|
* parseKeyType("invalid") // => null
|
|
543
684
|
* ```
|
|
544
685
|
*/
|
|
545
|
-
declare function parseKeyType(key: string): KeyType | null;
|
|
686
|
+
export declare function parseKeyType(key: string): KeyType | null;
|
|
546
687
|
/**
|
|
547
688
|
* Validate a key format and optionally finding its type.
|
|
548
689
|
*
|
|
@@ -558,10 +699,15 @@ declare function parseKeyType(key: string): KeyType | null;
|
|
|
558
699
|
* validateKey("invalid") // => false
|
|
559
700
|
* ```
|
|
560
701
|
*/
|
|
561
|
-
declare function validateKey(key: string, expectedType?: KeyType): boolean;
|
|
702
|
+
export declare function validateKey(key: string, expectedType?: KeyType): boolean;
|
|
562
703
|
/**
|
|
563
704
|
* Extract components from an observable key.
|
|
564
705
|
*
|
|
706
|
+
* Only reliable for the simple form `obs:{type}:{value}`. A key carrying a subtype or a
|
|
707
|
+
* namespace, and a `command_line` or oversized key folded into `obs:{type}:sha256:{digest}`,
|
|
708
|
+
* both return the remaining segments verbatim as `value` — a key is an identity token, not a
|
|
709
|
+
* record. Read the observable from the document instead of parsing its key.
|
|
710
|
+
*
|
|
565
711
|
* @param key - Observable key to parse
|
|
566
712
|
* @returns Object with type and value, or null if invalid
|
|
567
713
|
*
|
|
@@ -571,1009 +717,155 @@ declare function validateKey(key: string, expectedType?: KeyType): boolean;
|
|
|
571
717
|
* // => { type: "ipv4", value: "192.168.1.1" }
|
|
572
718
|
* ```
|
|
573
719
|
*/
|
|
574
|
-
declare function parseObservableKey(key: string): {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
} | null;
|
|
578
|
-
/**
|
|
579
|
-
* Extract components from a finding key.
|
|
580
|
-
*
|
|
581
|
-
* @param key - Finding key to parse
|
|
582
|
-
* @returns Object with findingName, or null if invalid
|
|
583
|
-
*
|
|
584
|
-
* @example
|
|
585
|
-
* ```ts
|
|
586
|
-
* parseFindingKey("fnd:sender_verification")
|
|
587
|
-
* // => { findingName: "sender_verification" }
|
|
588
|
-
* ```
|
|
589
|
-
*/
|
|
590
|
-
declare function parseFindingKey(key: string): {
|
|
591
|
-
findingName: string;
|
|
592
|
-
} | null;
|
|
593
|
-
/**
|
|
594
|
-
* Extract components from a threat intel key.
|
|
595
|
-
*
|
|
596
|
-
* @param key - Threat intel key to parse
|
|
597
|
-
* @returns Object with source and observableKey, or null if invalid
|
|
598
|
-
*
|
|
599
|
-
* @example
|
|
600
|
-
* ```ts
|
|
601
|
-
* parseThreatIntelKey("ti:virustotal:obs:ipv4:192.168.1.1")
|
|
602
|
-
* // => { source: "virustotal", observableKey: "obs:ipv4:192.168.1.1" }
|
|
603
|
-
* ```
|
|
604
|
-
*/
|
|
605
|
-
declare function parseThreatIntelKey(key: string): {
|
|
606
|
-
source: string;
|
|
607
|
-
observableKey: string;
|
|
720
|
+
export declare function parseObservableKey(key: string): {
|
|
721
|
+
type: string;
|
|
722
|
+
value: string;
|
|
608
723
|
} | null;
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
*
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
declare
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
declare
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
declare function
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
declare function
|
|
652
|
-
/**
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
declare function
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
*
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
*
|
|
688
|
-
*/
|
|
689
|
-
declare function
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
declare function
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
declare function
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
declare function
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
declare function
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
*/
|
|
758
|
-
declare function hasLevel(obj: unknown): obj is {
|
|
759
|
-
level: Level;
|
|
760
|
-
};
|
|
761
|
-
/**
|
|
762
|
-
* Extract level from an entity (Observable, Finding, ThreatIntel, Tag).
|
|
763
|
-
*/
|
|
764
|
-
declare function getEntityLevel(entity: Observable | Finding | ThreatIntel | Tag): Level;
|
|
765
|
-
|
|
766
|
-
/**
|
|
767
|
-
* Get an observable by its key.
|
|
768
|
-
*
|
|
769
|
-
* @param inv - The investigation to search
|
|
770
|
-
* @param key - Observable key (e.g., "obs:ipv4:192.168.1.1")
|
|
771
|
-
* @returns The observable or undefined if not found
|
|
772
|
-
*
|
|
773
|
-
* @example
|
|
774
|
-
* ```ts
|
|
775
|
-
* const obs = getObservable(investigation, "obs:ipv4:192.168.1.1");
|
|
776
|
-
* if (obs) {
|
|
777
|
-
* console.log(obs.value, obs.level);
|
|
778
|
-
* }
|
|
779
|
-
* ```
|
|
780
|
-
*/
|
|
781
|
-
declare function getObservable(inv: CyvestInvestigation, key: string): Observable | undefined;
|
|
782
|
-
/**
|
|
783
|
-
* Get an observable by type and value.
|
|
784
|
-
*
|
|
785
|
-
* @param inv - The investigation to search
|
|
786
|
-
* @param type - Observable type (e.g., "ipv4", "url")
|
|
787
|
-
* @param value - Observable value
|
|
788
|
-
* @returns The observable or undefined if not found
|
|
789
|
-
*
|
|
790
|
-
* @example
|
|
791
|
-
* ```ts
|
|
792
|
-
* const obs = getObservableByTypeValue(investigation, "ipv4", "192.168.1.1");
|
|
793
|
-
* ```
|
|
794
|
-
*/
|
|
795
|
-
declare function getObservableByTypeValue(inv: CyvestInvestigation, type: string, value: string, subtype?: string, namespace?: string): Observable | undefined;
|
|
796
|
-
/**
|
|
797
|
-
* Get the root observable of the investigation.
|
|
798
|
-
*
|
|
799
|
-
* The root observable is identified using the `root_type` from data extraction
|
|
800
|
-
* metadata combined with value="root".
|
|
801
|
-
*
|
|
802
|
-
* @param inv - The investigation
|
|
803
|
-
* @returns The root observable, or undefined if not found
|
|
804
|
-
*
|
|
805
|
-
* @example
|
|
806
|
-
* ```ts
|
|
807
|
-
* const root = getRootObservable(investigation);
|
|
808
|
-
* if (root) {
|
|
809
|
-
* console.log(`Root: ${root.type} = ${root.value}`);
|
|
810
|
-
* }
|
|
811
|
-
* ```
|
|
812
|
-
*/
|
|
813
|
-
declare function getRootObservable(inv: CyvestInvestigation): Observable | undefined;
|
|
814
|
-
/**
|
|
815
|
-
* Get a finding by its key.
|
|
816
|
-
*
|
|
817
|
-
* @param inv - The investigation to search
|
|
818
|
-
* @param key - Finding key (e.g., "fnd:sender_verification:email_headers")
|
|
819
|
-
* @returns The finding or undefined if not found
|
|
820
|
-
*
|
|
821
|
-
* @example
|
|
822
|
-
* ```ts
|
|
823
|
-
* const finding = getFinding(investigation, "fnd:sender_verification:email_headers");
|
|
824
|
-
* ```
|
|
825
|
-
*/
|
|
826
|
-
declare function getFinding(inv: CyvestInvestigation, key: string): Finding | undefined;
|
|
827
|
-
/**
|
|
828
|
-
* Get a finding by its name.
|
|
829
|
-
*
|
|
830
|
-
* @param inv - The investigation to search
|
|
831
|
-
* @param findingName - Finding name
|
|
832
|
-
* @returns The finding or undefined if not found
|
|
833
|
-
*
|
|
834
|
-
* @example
|
|
835
|
-
* ```ts
|
|
836
|
-
* const finding = getFindingByName(investigation, "sender_verification");
|
|
837
|
-
* ```
|
|
838
|
-
*/
|
|
839
|
-
declare function getFindingByName(inv: CyvestInvestigation, findingName: string): Finding | undefined;
|
|
840
|
-
/**
|
|
841
|
-
* Get all findings as an array.
|
|
842
|
-
*
|
|
843
|
-
* @param inv - The investigation
|
|
844
|
-
* @returns Array of all findings
|
|
845
|
-
*
|
|
846
|
-
* @example
|
|
847
|
-
* ```ts
|
|
848
|
-
* const allFindings = getAllFindings(investigation);
|
|
849
|
-
* console.log(`Total findings: ${allFindings.length}`);
|
|
850
|
-
* ```
|
|
851
|
-
*/
|
|
852
|
-
declare function getAllFindings(inv: CyvestInvestigation): Finding[];
|
|
853
|
-
declare function getEvidence(inv: CyvestInvestigation, key: string): Evidence | undefined;
|
|
854
|
-
declare function getAllEvidences(inv: CyvestInvestigation): Evidence[];
|
|
855
|
-
/**
|
|
856
|
-
* Get a threat intel entry by its key.
|
|
857
|
-
*
|
|
858
|
-
* @param inv - The investigation to search
|
|
859
|
-
* @param key - Threat intel key (e.g., "ti:virustotal:obs:ipv4:192.168.1.1")
|
|
860
|
-
* @returns The threat intel or undefined if not found
|
|
861
|
-
*/
|
|
862
|
-
declare function getThreatIntel(inv: CyvestInvestigation, key: string): ThreatIntel | undefined;
|
|
863
|
-
/**
|
|
864
|
-
* Get a threat intel entry by source and observable key.
|
|
865
|
-
*
|
|
866
|
-
* @param inv - The investigation to search
|
|
867
|
-
* @param source - Threat intel source name
|
|
868
|
-
* @param observableKey - Key of the related observable
|
|
869
|
-
* @returns The threat intel or undefined if not found
|
|
870
|
-
*/
|
|
871
|
-
declare function getThreatIntelBySourceObservable(inv: CyvestInvestigation, source: string, observableKey: string): ThreatIntel | undefined;
|
|
872
|
-
/**
|
|
873
|
-
* Get all threat intel entries as an array.
|
|
874
|
-
*
|
|
875
|
-
* @param inv - The investigation
|
|
876
|
-
* @returns Array of all threat intel entries
|
|
877
|
-
*/
|
|
878
|
-
declare function getAllThreatIntels(inv: CyvestInvestigation): ThreatIntel[];
|
|
879
|
-
/**
|
|
880
|
-
* Get an enrichment by its key.
|
|
881
|
-
*
|
|
882
|
-
* @param inv - The investigation to search
|
|
883
|
-
* @param key - Enrichment key (e.g., "enr:whois_data")
|
|
884
|
-
* @returns The enrichment or undefined if not found
|
|
885
|
-
*/
|
|
886
|
-
declare function getEnrichment(inv: CyvestInvestigation, key: string): Enrichment | undefined;
|
|
887
|
-
/**
|
|
888
|
-
* Get an enrichment by name.
|
|
889
|
-
*
|
|
890
|
-
* @param inv - The investigation to search
|
|
891
|
-
* @param name - Enrichment name
|
|
892
|
-
* @returns The first matching enrichment or undefined if not found
|
|
893
|
-
*/
|
|
894
|
-
declare function getEnrichmentByName(inv: CyvestInvestigation, name: string): Enrichment | undefined;
|
|
895
|
-
/**
|
|
896
|
-
* Get all enrichments as an array.
|
|
897
|
-
*
|
|
898
|
-
* @param inv - The investigation
|
|
899
|
-
* @returns Array of all enrichments
|
|
900
|
-
*/
|
|
901
|
-
declare function getAllEnrichments(inv: CyvestInvestigation): Enrichment[];
|
|
902
|
-
/**
|
|
903
|
-
* Get a tag by its key.
|
|
904
|
-
*
|
|
905
|
-
* @param inv - The investigation to search
|
|
906
|
-
* @param key - Tag key (e.g., "tag:header:auth")
|
|
907
|
-
* @returns The tag or undefined if not found
|
|
908
|
-
*
|
|
909
|
-
* @example
|
|
910
|
-
* ```ts
|
|
911
|
-
* const tag = getTag(investigation, "tag:header:auth");
|
|
912
|
-
* if (tag) {
|
|
913
|
-
* console.log(tag.name, tag.direct_level);
|
|
914
|
-
* }
|
|
915
|
-
* ```
|
|
916
|
-
*/
|
|
917
|
-
declare function getTag(inv: CyvestInvestigation, key: string): Tag | undefined;
|
|
918
|
-
/**
|
|
919
|
-
* Get a tag by its name.
|
|
920
|
-
*
|
|
921
|
-
* @param inv - The investigation to search
|
|
922
|
-
* @param name - Tag name (e.g., "header:auth:dkim")
|
|
923
|
-
* @returns The tag or undefined if not found
|
|
924
|
-
*
|
|
925
|
-
* @example
|
|
926
|
-
* ```ts
|
|
927
|
-
* const tag = getTagByName(investigation, "header:auth:dkim");
|
|
928
|
-
* ```
|
|
929
|
-
*/
|
|
930
|
-
declare function getTagByName(inv: CyvestInvestigation, name: string): Tag | undefined;
|
|
931
|
-
/**
|
|
932
|
-
* Get all tags as an array.
|
|
933
|
-
*
|
|
934
|
-
* @param inv - The investigation
|
|
935
|
-
* @returns Array of all tags
|
|
936
|
-
*
|
|
937
|
-
* @example
|
|
938
|
-
* ```ts
|
|
939
|
-
* const allTags = getAllTags(investigation);
|
|
940
|
-
* console.log(`Total tags: ${allTags.length}`);
|
|
941
|
-
* ```
|
|
942
|
-
*/
|
|
943
|
-
declare function getAllTags(inv: CyvestInvestigation): Tag[];
|
|
944
|
-
/**
|
|
945
|
-
* Get all observables as an array.
|
|
946
|
-
*
|
|
947
|
-
* @param inv - The investigation
|
|
948
|
-
* @returns Array of all observables
|
|
949
|
-
*/
|
|
950
|
-
declare function getAllObservables(inv: CyvestInvestigation): Observable[];
|
|
951
|
-
/**
|
|
952
|
-
* Get all whitelists from the investigation.
|
|
953
|
-
*
|
|
954
|
-
* @param inv - The investigation
|
|
955
|
-
* @returns Array of all whitelists
|
|
956
|
-
*/
|
|
957
|
-
declare function getWhitelists(inv: CyvestInvestigation): Whitelists;
|
|
958
|
-
/**
|
|
959
|
-
* Get the investigation statistics.
|
|
960
|
-
*
|
|
961
|
-
* @param inv - The investigation
|
|
962
|
-
* @returns Statistics object
|
|
963
|
-
*/
|
|
964
|
-
declare function getStats(inv: CyvestInvestigation): StatisticsSchema;
|
|
965
|
-
/**
|
|
966
|
-
* Get the data extraction configuration.
|
|
967
|
-
*
|
|
968
|
-
* @param inv - The investigation
|
|
969
|
-
* @returns Data extraction config
|
|
970
|
-
*/
|
|
971
|
-
declare function getDataExtraction(inv: CyvestInvestigation): DataExtractionSchema;
|
|
972
|
-
/**
|
|
973
|
-
* Count entities in the investigation.
|
|
974
|
-
*/
|
|
975
|
-
interface InvestigationCounts {
|
|
976
|
-
observables: number;
|
|
977
|
-
findings: number;
|
|
978
|
-
evidences: number;
|
|
979
|
-
threatIntels: number;
|
|
980
|
-
enrichments: number;
|
|
981
|
-
tags: number;
|
|
982
|
-
whitelists: number;
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Get counts of all entities in the investigation.
|
|
986
|
-
*
|
|
987
|
-
* @param inv - The investigation
|
|
988
|
-
* @returns Object with counts for each entity type
|
|
989
|
-
*/
|
|
990
|
-
declare function getCounts(inv: CyvestInvestigation): InvestigationCounts;
|
|
991
|
-
/**
|
|
992
|
-
* Get the investigation start time from the event log.
|
|
993
|
-
*
|
|
994
|
-
* Looks for the INVESTIGATION_STARTED event and returns its timestamp.
|
|
995
|
-
*
|
|
996
|
-
* @param inv - The investigation
|
|
997
|
-
* @returns The start timestamp string or undefined if not found
|
|
998
|
-
*
|
|
999
|
-
* @example
|
|
1000
|
-
* ```ts
|
|
1001
|
-
* const startedAt = getStartedAt(investigation);
|
|
1002
|
-
* if (startedAt) {
|
|
1003
|
-
* console.log(`Started: ${startedAt}`);
|
|
1004
|
-
* }
|
|
1005
|
-
* ```
|
|
1006
|
-
*/
|
|
1007
|
-
declare function getStartedAt(inv: CyvestInvestigation): string | undefined;
|
|
1008
|
-
/**
|
|
1009
|
-
* Get direct child tags of a given tag.
|
|
1010
|
-
*
|
|
1011
|
-
* @param inv - The investigation
|
|
1012
|
-
* @param tagName - Parent tag name
|
|
1013
|
-
* @returns Array of direct child tags
|
|
1014
|
-
*
|
|
1015
|
-
* @example
|
|
1016
|
-
* ```ts
|
|
1017
|
-
* const children = getTagChildren(investigation, "bodies");
|
|
1018
|
-
* // Returns tags like "bodies:urls", "bodies:domains" (but not "bodies:urls:something")
|
|
1019
|
-
* ```
|
|
1020
|
-
*/
|
|
1021
|
-
declare function getTagChildren(inv: CyvestInvestigation, tagName: string): Tag[];
|
|
1022
|
-
/**
|
|
1023
|
-
* Get all descendant tags of a given tag (any depth).
|
|
1024
|
-
*
|
|
1025
|
-
* @param inv - The investigation
|
|
1026
|
-
* @param tagName - Ancestor tag name
|
|
1027
|
-
* @returns Array of all descendant tags
|
|
1028
|
-
*
|
|
1029
|
-
* @example
|
|
1030
|
-
* ```ts
|
|
1031
|
-
* const descendants = getTagDescendants(investigation, "bodies");
|
|
1032
|
-
* // Returns all tags starting with "bodies:"
|
|
1033
|
-
* ```
|
|
1034
|
-
*/
|
|
1035
|
-
declare function getTagDescendants(inv: CyvestInvestigation, tagName: string): Tag[];
|
|
1036
|
-
/**
|
|
1037
|
-
* Get the aggregated score for a tag including all descendant tags.
|
|
1038
|
-
*
|
|
1039
|
-
* The aggregated score includes:
|
|
1040
|
-
* - The tag's direct_score (from its direct findings)
|
|
1041
|
-
* - Recursively, the aggregated scores of all child tags
|
|
1042
|
-
*
|
|
1043
|
-
* @param inv - The investigation
|
|
1044
|
-
* @param tagName - Name of the tag
|
|
1045
|
-
* @returns Total aggregated score, or 0 if tag not found
|
|
1046
|
-
*
|
|
1047
|
-
* @example
|
|
1048
|
-
* ```ts
|
|
1049
|
-
* const score = getTagAggregatedScore(investigation, "bodies");
|
|
1050
|
-
* // Includes scores from bodies, bodies:urls, bodies:domains, etc.
|
|
1051
|
-
* ```
|
|
1052
|
-
*/
|
|
1053
|
-
declare function getTagAggregatedScore(inv: CyvestInvestigation, tagName: string): number;
|
|
1054
|
-
/**
|
|
1055
|
-
* Get the aggregated level for a tag including all descendant tags.
|
|
1056
|
-
*
|
|
1057
|
-
* The level is calculated from the aggregated score using the standard
|
|
1058
|
-
* score-to-level mapping.
|
|
1059
|
-
*
|
|
1060
|
-
* @param inv - The investigation
|
|
1061
|
-
* @param tagName - Name of the tag
|
|
1062
|
-
* @returns Level based on aggregated score
|
|
1063
|
-
*
|
|
1064
|
-
* @example
|
|
1065
|
-
* ```ts
|
|
1066
|
-
* const level = getTagAggregatedLevel(investigation, "bodies");
|
|
1067
|
-
* // Returns "MALICIOUS" if aggregated score >= 5, etc.
|
|
1068
|
-
* ```
|
|
1069
|
-
*/
|
|
1070
|
-
declare function getTagAggregatedLevel(inv: CyvestInvestigation, tagName: string): Level;
|
|
1071
|
-
|
|
1072
|
-
/**
|
|
1073
|
-
* Finder utilities for querying and filtering Cyvest Investigation data.
|
|
1074
|
-
*
|
|
1075
|
-
* These functions provide filtering, searching, and cross-referencing
|
|
1076
|
-
* capabilities for observables, findings, and threat intel.
|
|
1077
|
-
*/
|
|
1078
|
-
|
|
1079
|
-
/**
|
|
1080
|
-
* Find all observables of a specific type.
|
|
1081
|
-
*
|
|
1082
|
-
* @param inv - The investigation to search
|
|
1083
|
-
* @param type - Observable type (e.g., "ipv4", "url", "domain")
|
|
1084
|
-
* @returns Array of matching observables
|
|
1085
|
-
*
|
|
1086
|
-
* @example
|
|
1087
|
-
* ```ts
|
|
1088
|
-
* const ips = findObservablesByType(investigation, "ipv4");
|
|
1089
|
-
* const urls = findObservablesByType(investigation, "url");
|
|
1090
|
-
* ```
|
|
1091
|
-
*/
|
|
1092
|
-
declare function findObservablesByType(inv: CyvestInvestigation, type: string): Observable[];
|
|
1093
|
-
/**
|
|
1094
|
-
* Find all observables at a specific level.
|
|
1095
|
-
*
|
|
1096
|
-
* @param inv - The investigation to search
|
|
1097
|
-
* @param level - Security level to filter by
|
|
1098
|
-
* @returns Array of matching observables
|
|
1099
|
-
*
|
|
1100
|
-
* @example
|
|
1101
|
-
* ```ts
|
|
1102
|
-
* const malicious = findObservablesByLevel(investigation, "MALICIOUS");
|
|
1103
|
-
* ```
|
|
1104
|
-
*/
|
|
1105
|
-
declare function findObservablesByLevel(inv: CyvestInvestigation, level: Level): Observable[];
|
|
1106
|
-
/**
|
|
1107
|
-
* Find all observables at or above a minimum level.
|
|
1108
|
-
*
|
|
1109
|
-
* @param inv - The investigation to search
|
|
1110
|
-
* @param minLevel - Minimum security level
|
|
1111
|
-
* @returns Array of matching observables
|
|
1112
|
-
*
|
|
1113
|
-
* @example
|
|
1114
|
-
* ```ts
|
|
1115
|
-
* const suspicious = findObservablesAtLeast(investigation, "SUSPICIOUS");
|
|
1116
|
-
* // Returns SUSPICIOUS and MALICIOUS observables
|
|
1117
|
-
* ```
|
|
1118
|
-
*/
|
|
1119
|
-
declare function findObservablesAtLeast(inv: CyvestInvestigation, minLevel: Level): Observable[];
|
|
1120
|
-
/**
|
|
1121
|
-
* Find observables by exact value match.
|
|
1122
|
-
*
|
|
1123
|
-
* @param inv - The investigation to search
|
|
1124
|
-
* @param value - Value to search for
|
|
1125
|
-
* @param caseSensitive - Whether to perform case-sensitive match (default: false)
|
|
1126
|
-
* @returns Array of matching observables
|
|
1127
|
-
*/
|
|
1128
|
-
declare function findObservablesByValue(inv: CyvestInvestigation, value: string, caseSensitive?: boolean): Observable[];
|
|
1129
|
-
/**
|
|
1130
|
-
* Find observables containing a substring in their value.
|
|
1131
|
-
*
|
|
1132
|
-
* @param inv - The investigation to search
|
|
1133
|
-
* @param substring - Substring to search for
|
|
1134
|
-
* @param caseSensitive - Whether to perform case-sensitive match (default: false)
|
|
1135
|
-
* @returns Array of matching observables
|
|
1136
|
-
*/
|
|
1137
|
-
declare function findObservablesContaining(inv: CyvestInvestigation, substring: string, caseSensitive?: boolean): Observable[];
|
|
1138
|
-
/**
|
|
1139
|
-
* Find observables matching a regular expression.
|
|
1140
|
-
*
|
|
1141
|
-
* @param inv - The investigation to search
|
|
1142
|
-
* @param pattern - Regular expression pattern
|
|
1143
|
-
* @returns Array of matching observables
|
|
1144
|
-
*/
|
|
1145
|
-
declare function findObservablesMatching(inv: CyvestInvestigation, pattern: RegExp): Observable[];
|
|
1146
|
-
/**
|
|
1147
|
-
* Find internal observables.
|
|
1148
|
-
*
|
|
1149
|
-
* @param inv - The investigation to search
|
|
1150
|
-
* @returns Array of internal observables
|
|
1151
|
-
*/
|
|
1152
|
-
declare function findInternalObservables(inv: CyvestInvestigation): Observable[];
|
|
1153
|
-
/**
|
|
1154
|
-
* Find external (non-internal) observables.
|
|
1155
|
-
*
|
|
1156
|
-
* @param inv - The investigation to search
|
|
1157
|
-
* @returns Array of external observables
|
|
1158
|
-
*/
|
|
1159
|
-
declare function findExternalObservables(inv: CyvestInvestigation): Observable[];
|
|
1160
|
-
/**
|
|
1161
|
-
* Find whitelisted observables.
|
|
1162
|
-
*
|
|
1163
|
-
* @param inv - The investigation to search
|
|
1164
|
-
* @returns Array of whitelisted observables
|
|
1165
|
-
*/
|
|
1166
|
-
declare function findWhitelistedObservables(inv: CyvestInvestigation): Observable[];
|
|
1167
|
-
/**
|
|
1168
|
-
* Find observables with threat intelligence data.
|
|
1169
|
-
*
|
|
1170
|
-
* @param inv - The investigation to search
|
|
1171
|
-
* @returns Array of observables that have associated threat intel
|
|
1172
|
-
*/
|
|
1173
|
-
declare function findObservablesWithThreatIntel(inv: CyvestInvestigation): Observable[];
|
|
1174
|
-
/**
|
|
1175
|
-
* Find all findings at a specific level.
|
|
1176
|
-
*
|
|
1177
|
-
* @param inv - The investigation to search
|
|
1178
|
-
* @param level - Security level to filter by
|
|
1179
|
-
* @returns Array of matching findings
|
|
1180
|
-
*/
|
|
1181
|
-
declare function findFindingsByLevel(inv: CyvestInvestigation, level: Level): Finding[];
|
|
1182
|
-
/**
|
|
1183
|
-
* Find all findings at or above a minimum level.
|
|
1184
|
-
*
|
|
1185
|
-
* @param inv - The investigation to search
|
|
1186
|
-
* @param minLevel - Minimum security level
|
|
1187
|
-
* @returns Array of matching findings
|
|
1188
|
-
*/
|
|
1189
|
-
declare function findFindingsAtLeast(inv: CyvestInvestigation, minLevel: Level): Finding[];
|
|
1190
|
-
/**
|
|
1191
|
-
* Find findings by finding name.
|
|
1192
|
-
*
|
|
1193
|
-
* @param inv - The investigation to search
|
|
1194
|
-
* @param findingName - Finding name to search for
|
|
1195
|
-
* @returns The matching finding or undefined
|
|
1196
|
-
*/
|
|
1197
|
-
declare function findFindingByName(inv: CyvestInvestigation, findingName: string): Finding | undefined;
|
|
1198
|
-
/**
|
|
1199
|
-
* Find all threat intel from a specific source.
|
|
1200
|
-
*
|
|
1201
|
-
* @param inv - The investigation to search
|
|
1202
|
-
* @param source - Source name (e.g., "virustotal", "otx")
|
|
1203
|
-
* @returns Array of threat intel from the source
|
|
1204
|
-
*/
|
|
1205
|
-
declare function findThreatIntelBySource(inv: CyvestInvestigation, source: string): ThreatIntel[];
|
|
1206
|
-
/**
|
|
1207
|
-
* Find all threat intel at a specific level.
|
|
1208
|
-
*
|
|
1209
|
-
* @param inv - The investigation to search
|
|
1210
|
-
* @param level - Security level to filter by
|
|
1211
|
-
* @returns Array of matching threat intel
|
|
1212
|
-
*/
|
|
1213
|
-
declare function findThreatIntelByLevel(inv: CyvestInvestigation, level: Level): ThreatIntel[];
|
|
1214
|
-
/**
|
|
1215
|
-
* Find all threat intel at or above a minimum level.
|
|
1216
|
-
*
|
|
1217
|
-
* @param inv - The investigation to search
|
|
1218
|
-
* @param minLevel - Minimum security level
|
|
1219
|
-
* @returns Array of matching threat intel
|
|
1220
|
-
*/
|
|
1221
|
-
declare function findThreatIntelAtLeast(inv: CyvestInvestigation, minLevel: Level): ThreatIntel[];
|
|
1222
|
-
/**
|
|
1223
|
-
* Find tags at a specific direct level.
|
|
1224
|
-
*
|
|
1225
|
-
* @param inv - The investigation to search
|
|
1226
|
-
* @param level - Direct level to filter by
|
|
1227
|
-
* @returns Array of matching tags
|
|
1228
|
-
*/
|
|
1229
|
-
declare function findTagsByLevel(inv: CyvestInvestigation, level: Level): Tag[];
|
|
1230
|
-
/**
|
|
1231
|
-
* Find tags at or above a minimum direct level.
|
|
1232
|
-
*
|
|
1233
|
-
* @param inv - The investigation to search
|
|
1234
|
-
* @param minLevel - Minimum direct level
|
|
1235
|
-
* @returns Array of matching tags
|
|
1236
|
-
*/
|
|
1237
|
-
declare function findTagsAtLeast(inv: CyvestInvestigation, minLevel: Level): Tag[];
|
|
1238
|
-
/**
|
|
1239
|
-
* Find tags by name pattern.
|
|
1240
|
-
*
|
|
1241
|
-
* @param inv - The investigation to search
|
|
1242
|
-
* @param pattern - Pattern to match against tag names
|
|
1243
|
-
* @returns Array of matching tags
|
|
1244
|
-
*/
|
|
1245
|
-
declare function findTagsByNamePattern(inv: CyvestInvestigation, pattern: RegExp): Tag[];
|
|
1246
|
-
/**
|
|
1247
|
-
* Find all findings that generated or reference a specific observable.
|
|
1248
|
-
*
|
|
1249
|
-
* @param inv - The investigation to search
|
|
1250
|
-
* @param observableKey - Key of the observable
|
|
1251
|
-
* @returns Array of findings that reference this observable
|
|
1252
|
-
*
|
|
1253
|
-
* @example
|
|
1254
|
-
* ```ts
|
|
1255
|
-
* const findings = findFindingsForObservable(investigation, "obs:ipv4:192.168.1.1");
|
|
1256
|
-
* ```
|
|
1257
|
-
*/
|
|
1258
|
-
declare function findFindingsForObservable(inv: CyvestInvestigation, observableKey: string): Finding[];
|
|
1259
|
-
/**
|
|
1260
|
-
* Find all threat intel entries for a specific observable.
|
|
1261
|
-
*
|
|
1262
|
-
* @param inv - The investigation to search
|
|
1263
|
-
* @param observableKey - Key of the observable
|
|
1264
|
-
* @returns Array of threat intel for this observable
|
|
1265
|
-
*/
|
|
1266
|
-
declare function findThreatIntelsForObservable(inv: CyvestInvestigation, observableKey: string): ThreatIntel[];
|
|
1267
|
-
/**
|
|
1268
|
-
* Find all observables referenced by a specific finding.
|
|
1269
|
-
*
|
|
1270
|
-
* @param inv - The investigation to search
|
|
1271
|
-
* @param findingKey - Key of the finding
|
|
1272
|
-
* @returns Array of observables referenced by this finding
|
|
1273
|
-
*/
|
|
1274
|
-
declare function findObservablesForFinding(inv: CyvestInvestigation, findingKey: string): Observable[];
|
|
1275
|
-
/**
|
|
1276
|
-
* Find all findings for a specific tag.
|
|
1277
|
-
*
|
|
1278
|
-
* @param inv - The investigation to search
|
|
1279
|
-
* @param tagKey - Key of the tag
|
|
1280
|
-
* @param recursive - Include findings from descendant tags (default: false)
|
|
1281
|
-
* @returns Array of findings in the tag
|
|
1282
|
-
*/
|
|
1283
|
-
declare function findFindingsForTag(inv: CyvestInvestigation, tagKey: string, recursive?: boolean): Finding[];
|
|
1284
|
-
/**
|
|
1285
|
-
* Sort observables by score (descending - highest first).
|
|
1286
|
-
*
|
|
1287
|
-
* @param observables - Array of observables to sort
|
|
1288
|
-
* @returns Sorted array (new array, doesn't mutate input)
|
|
1289
|
-
*/
|
|
1290
|
-
declare function sortObservablesByScore(observables: Observable[]): Observable[];
|
|
1291
|
-
/**
|
|
1292
|
-
* Sort findings by score (descending - highest first).
|
|
1293
|
-
*
|
|
1294
|
-
* @param findings - Array of findings to sort
|
|
1295
|
-
* @returns Sorted array (new array, doesn't mutate input)
|
|
1296
|
-
*/
|
|
1297
|
-
declare function sortFindingsByScore(findings: Finding[]): Finding[];
|
|
1298
|
-
/**
|
|
1299
|
-
* Sort observables by level (descending - most severe first).
|
|
1300
|
-
*
|
|
1301
|
-
* @param observables - Array of observables to sort
|
|
1302
|
-
* @returns Sorted array (new array, doesn't mutate input)
|
|
1303
|
-
*/
|
|
1304
|
-
declare function sortObservablesByLevel(observables: Observable[]): Observable[];
|
|
1305
|
-
/**
|
|
1306
|
-
* Sort findings by level (descending - most severe first).
|
|
1307
|
-
*
|
|
1308
|
-
* @param findings - Array of findings to sort
|
|
1309
|
-
* @returns Sorted array (new array, doesn't mutate input)
|
|
1310
|
-
*/
|
|
1311
|
-
declare function sortFindingsByLevel(findings: Finding[]): Finding[];
|
|
1312
|
-
/**
|
|
1313
|
-
* Find the highest scoring observables.
|
|
1314
|
-
*
|
|
1315
|
-
* @param inv - The investigation to search
|
|
1316
|
-
* @param n - Number of results to return (default: 10)
|
|
1317
|
-
* @returns Array of highest scoring observables
|
|
1318
|
-
*/
|
|
1319
|
-
declare function findHighestScoringObservables(inv: CyvestInvestigation, n?: number): Observable[];
|
|
1320
|
-
/**
|
|
1321
|
-
* Find the highest scoring findings.
|
|
1322
|
-
*
|
|
1323
|
-
* @param inv - The investigation to search
|
|
1324
|
-
* @param n - Number of results to return (default: 10)
|
|
1325
|
-
* @returns Array of highest scoring findings
|
|
1326
|
-
*/
|
|
1327
|
-
declare function findHighestScoringFindings(inv: CyvestInvestigation, n?: number): Finding[];
|
|
1328
|
-
/**
|
|
1329
|
-
* Find all malicious observables (convenience function).
|
|
1330
|
-
*
|
|
1331
|
-
* @param inv - The investigation to search
|
|
1332
|
-
* @returns Array of malicious observables
|
|
1333
|
-
*/
|
|
1334
|
-
declare function findMaliciousObservables(inv: CyvestInvestigation): Observable[];
|
|
1335
|
-
/**
|
|
1336
|
-
* Find all suspicious observables (convenience function).
|
|
1337
|
-
*
|
|
1338
|
-
* @param inv - The investigation to search
|
|
1339
|
-
* @returns Array of suspicious observables
|
|
1340
|
-
*/
|
|
1341
|
-
declare function findSuspiciousObservables(inv: CyvestInvestigation): Observable[];
|
|
1342
|
-
/**
|
|
1343
|
-
* Find all malicious findings (convenience function).
|
|
1344
|
-
*
|
|
1345
|
-
* @param inv - The investigation to search
|
|
1346
|
-
* @returns Array of malicious findings
|
|
1347
|
-
*/
|
|
1348
|
-
declare function findMaliciousFindings(inv: CyvestInvestigation): Finding[];
|
|
1349
|
-
/**
|
|
1350
|
-
* Find all suspicious findings (convenience function).
|
|
1351
|
-
*
|
|
1352
|
-
* @param inv - The investigation to search
|
|
1353
|
-
* @returns Array of suspicious findings
|
|
1354
|
-
*/
|
|
1355
|
-
declare function findSuspiciousFindings(inv: CyvestInvestigation): Finding[];
|
|
1356
|
-
/**
|
|
1357
|
-
* Get all finding keys in the investigation.
|
|
1358
|
-
*
|
|
1359
|
-
* @param inv - The investigation
|
|
1360
|
-
* @returns Array of finding keys
|
|
1361
|
-
*/
|
|
1362
|
-
declare function getAllFindingKeys(inv: CyvestInvestigation): string[];
|
|
1363
|
-
/**
|
|
1364
|
-
* Get all observable types present in the investigation.
|
|
1365
|
-
*
|
|
1366
|
-
* @param inv - The investigation
|
|
1367
|
-
* @returns Array of unique observable types
|
|
1368
|
-
*/
|
|
1369
|
-
declare function getAllObservableTypes(inv: CyvestInvestigation): string[];
|
|
1370
|
-
/**
|
|
1371
|
-
* Get all threat intel sources present in the investigation.
|
|
1372
|
-
*
|
|
1373
|
-
* @param inv - The investigation
|
|
1374
|
-
* @returns Array of unique source names
|
|
1375
|
-
*/
|
|
1376
|
-
declare function getAllThreatIntelSources(inv: CyvestInvestigation): string[];
|
|
1377
|
-
|
|
1378
|
-
/**
|
|
1379
|
-
* Graph and relationship traversal utilities for Cyvest Investigation.
|
|
1380
|
-
*
|
|
1381
|
-
* These functions provide graph-like traversal of observable relationships,
|
|
1382
|
-
* useful for understanding connections and preparing data for visualization.
|
|
1383
|
-
*/
|
|
1384
|
-
|
|
1385
|
-
/**
|
|
1386
|
-
* Edge representation for graph operations.
|
|
1387
|
-
*/
|
|
1388
|
-
interface GraphEdge {
|
|
1389
|
-
/** Source observable key */
|
|
1390
|
-
source: string;
|
|
1391
|
-
/** Target observable key */
|
|
1392
|
-
target: string;
|
|
1393
|
-
/** Relationship type label */
|
|
1394
|
-
type: string;
|
|
1395
|
-
/** Relationship direction */
|
|
1396
|
-
direction: RelationshipDirection;
|
|
1397
|
-
}
|
|
1398
|
-
/**
|
|
1399
|
-
* Graph node representation.
|
|
1400
|
-
*/
|
|
1401
|
-
interface GraphNode {
|
|
1402
|
-
/** Observable key (unique identifier) */
|
|
1403
|
-
id: string;
|
|
1404
|
-
/** Observable type */
|
|
1405
|
-
type: string;
|
|
1406
|
-
/** Observable value */
|
|
1407
|
-
value: string;
|
|
1408
|
-
/** Security level */
|
|
1409
|
-
level: Level;
|
|
1410
|
-
/** Numeric score */
|
|
1411
|
-
score: number;
|
|
1412
|
-
/** Whether internal */
|
|
1413
|
-
internal: boolean;
|
|
1414
|
-
/** Whether whitelisted */
|
|
1415
|
-
whitelisted: boolean;
|
|
1416
|
-
}
|
|
1417
|
-
/**
|
|
1418
|
-
* Full graph representation of an investigation.
|
|
1419
|
-
*/
|
|
1420
|
-
interface InvestigationGraph {
|
|
1421
|
-
/** All nodes (observables) */
|
|
1422
|
-
nodes: GraphNode[];
|
|
1423
|
-
/** All edges (relationships) */
|
|
1424
|
-
edges: GraphEdge[];
|
|
1425
|
-
}
|
|
1426
|
-
/**
|
|
1427
|
-
* Get all related observables for a given observable.
|
|
1428
|
-
*
|
|
1429
|
-
* Returns observables that are directly connected via any relationship,
|
|
1430
|
-
* regardless of direction.
|
|
1431
|
-
*
|
|
1432
|
-
* @param inv - The investigation to search
|
|
1433
|
-
* @param observableKey - Key of the source observable
|
|
1434
|
-
* @returns Array of related observables
|
|
1435
|
-
*
|
|
1436
|
-
* @example
|
|
1437
|
-
* ```ts
|
|
1438
|
-
* const related = getRelatedObservables(investigation, "obs:email:test@example.com");
|
|
1439
|
-
* ```
|
|
1440
|
-
*/
|
|
1441
|
-
declare function getRelatedObservables(inv: CyvestInvestigation, observableKey: string): Observable[];
|
|
1442
|
-
/**
|
|
1443
|
-
* Get observables related by outbound relationships (children).
|
|
1444
|
-
*
|
|
1445
|
-
* @param inv - The investigation to search
|
|
1446
|
-
* @param observableKey - Key of the source observable
|
|
1447
|
-
* @returns Array of child observables
|
|
1448
|
-
*/
|
|
1449
|
-
declare function getObservableChildren(inv: CyvestInvestigation, observableKey: string): Observable[];
|
|
1450
|
-
/**
|
|
1451
|
-
* Get observables related by inbound relationships (parents).
|
|
1452
|
-
*
|
|
1453
|
-
* @param inv - The investigation to search
|
|
1454
|
-
* @param observableKey - Key of the target observable
|
|
1455
|
-
* @returns Array of parent observables
|
|
1456
|
-
*/
|
|
1457
|
-
declare function getObservableParents(inv: CyvestInvestigation, observableKey: string): Observable[];
|
|
1458
|
-
/**
|
|
1459
|
-
* Get related observables filtered by relationship type.
|
|
1460
|
-
*
|
|
1461
|
-
* @param inv - The investigation to search
|
|
1462
|
-
* @param observableKey - Key of the source observable
|
|
1463
|
-
* @param relationshipType - Type of relationship to filter (e.g., "related-to", "uses")
|
|
1464
|
-
* @returns Array of related observables
|
|
1465
|
-
*/
|
|
1466
|
-
declare function getRelatedObservablesByType(inv: CyvestInvestigation, observableKey: string, relationshipType: string): Observable[];
|
|
1467
|
-
/**
|
|
1468
|
-
* Get related observables filtered by direction.
|
|
1469
|
-
*
|
|
1470
|
-
* @param inv - The investigation to search
|
|
1471
|
-
* @param observableKey - Key of the source observable
|
|
1472
|
-
* @param direction - Direction to filter by
|
|
1473
|
-
* @returns Array of related observables
|
|
1474
|
-
*/
|
|
1475
|
-
declare function getRelatedObservablesByDirection(inv: CyvestInvestigation, observableKey: string, direction: RelationshipDirection): Observable[];
|
|
1476
|
-
/**
|
|
1477
|
-
* Build a graph representation of all observables and their relationships.
|
|
1478
|
-
*
|
|
1479
|
-
* Useful for visualization libraries like vis.js, d3, or cytoscape.
|
|
1480
|
-
*
|
|
1481
|
-
* @param inv - The investigation
|
|
1482
|
-
* @returns Graph with nodes and edges
|
|
1483
|
-
*
|
|
1484
|
-
* @example
|
|
1485
|
-
* ```ts
|
|
1486
|
-
* const graph = getObservableGraph(investigation);
|
|
1487
|
-
* console.log(`Nodes: ${graph.nodes.length}, Edges: ${graph.edges.length}`);
|
|
1488
|
-
*
|
|
1489
|
-
* // Use with vis.js:
|
|
1490
|
-
* const network = new vis.Network(container, {
|
|
1491
|
-
* nodes: graph.nodes.map(n => ({ id: n.id, label: n.value })),
|
|
1492
|
-
* edges: graph.edges.map(e => ({ from: e.source, to: e.target, label: e.type }))
|
|
1493
|
-
* });
|
|
1494
|
-
* ```
|
|
1495
|
-
*/
|
|
1496
|
-
declare function getObservableGraph(inv: CyvestInvestigation): InvestigationGraph;
|
|
1497
|
-
/**
|
|
1498
|
-
* Find source observables in the investigation graph.
|
|
1499
|
-
*
|
|
1500
|
-
* Source observables are those that have no incoming relationships
|
|
1501
|
-
* (nothing points to them as a target).
|
|
1502
|
-
*
|
|
1503
|
-
* @param inv - The investigation
|
|
1504
|
-
* @returns Array of source observables
|
|
1505
|
-
*/
|
|
1506
|
-
declare function findSourceObservables(inv: CyvestInvestigation): Observable[];
|
|
1507
|
-
/**
|
|
1508
|
-
* Find orphan observables (not connected to any other observable).
|
|
1509
|
-
*
|
|
1510
|
-
* @param inv - The investigation
|
|
1511
|
-
* @returns Array of orphan observables
|
|
1512
|
-
*/
|
|
1513
|
-
declare function findOrphanObservables(inv: CyvestInvestigation): Observable[];
|
|
1514
|
-
/**
|
|
1515
|
-
* Find leaf observables (have incoming but no outgoing relationships).
|
|
1516
|
-
*
|
|
1517
|
-
* @param inv - The investigation
|
|
1518
|
-
* @returns Array of leaf observables
|
|
1519
|
-
*/
|
|
1520
|
-
declare function findLeafObservables(inv: CyvestInvestigation): Observable[];
|
|
1521
|
-
/**
|
|
1522
|
-
* Check if two observables are connected (directly or transitively).
|
|
1523
|
-
*
|
|
1524
|
-
* @param inv - The investigation
|
|
1525
|
-
* @param sourceKey - Starting observable key
|
|
1526
|
-
* @param targetKey - Target observable key
|
|
1527
|
-
* @returns True if a path exists from source to target
|
|
1528
|
-
*/
|
|
1529
|
-
declare function areConnected(inv: CyvestInvestigation, sourceKey: string, targetKey: string): boolean;
|
|
1530
|
-
/**
|
|
1531
|
-
* Find the shortest path between two observables.
|
|
1532
|
-
*
|
|
1533
|
-
* @param inv - The investigation
|
|
1534
|
-
* @param sourceKey - Starting observable key
|
|
1535
|
-
* @param targetKey - Target observable key
|
|
1536
|
-
* @returns Array of observable keys representing the path, or null if no path exists
|
|
1537
|
-
*/
|
|
1538
|
-
declare function findPath(inv: CyvestInvestigation, sourceKey: string, targetKey: string): string[] | null;
|
|
1539
|
-
/**
|
|
1540
|
-
* Get all observables reachable from a starting point.
|
|
1541
|
-
*
|
|
1542
|
-
* @param inv - The investigation
|
|
1543
|
-
* @param startKey - Starting observable key
|
|
1544
|
-
* @param maxDepth - Maximum traversal depth (default: Infinity)
|
|
1545
|
-
* @returns Array of reachable observables
|
|
1546
|
-
*/
|
|
1547
|
-
declare function getReachableObservables(inv: CyvestInvestigation, startKey: string, maxDepth?: number): Observable[];
|
|
1548
|
-
/**
|
|
1549
|
-
* Get all unique relationship types used in the investigation.
|
|
1550
|
-
*
|
|
1551
|
-
* @param inv - The investigation
|
|
1552
|
-
* @returns Array of unique relationship type strings
|
|
1553
|
-
*/
|
|
1554
|
-
declare function getAllRelationshipTypes(inv: CyvestInvestigation): string[];
|
|
1555
|
-
/**
|
|
1556
|
-
* Count relationships by type.
|
|
1557
|
-
*
|
|
1558
|
-
* @param inv - The investigation
|
|
1559
|
-
* @returns Object mapping relationship type to count
|
|
1560
|
-
*/
|
|
1561
|
-
declare function countRelationshipsByType(inv: CyvestInvestigation): Record<string, number>;
|
|
1562
|
-
/**
|
|
1563
|
-
* Get all relationships for an observable.
|
|
1564
|
-
*
|
|
1565
|
-
* @param inv - The investigation
|
|
1566
|
-
* @param observableKey - Observable key
|
|
1567
|
-
* @returns Object with outbound, inbound, and all relationships
|
|
1568
|
-
*/
|
|
1569
|
-
declare function getRelationshipsForObservable(inv: CyvestInvestigation, observableKey: string): {
|
|
1570
|
-
outbound: Relationship[];
|
|
1571
|
-
inbound: Array<Relationship & {
|
|
1572
|
-
source_key: string;
|
|
1573
|
-
}>;
|
|
1574
|
-
all: Array<Relationship & {
|
|
1575
|
-
source_key?: string;
|
|
1576
|
-
}>;
|
|
1577
|
-
};
|
|
1578
|
-
|
|
1579
|
-
export { type Actor, type Aliases, type AuditEvent, type AuditLog, type CyvestInvestigation, type Data, type DataExtractionSchema, type Details, type Enrichment, type Enrichments, type Evidence, type EvidenceLink, type EvidenceLinks, type Evidences, type EvidencesBySource, type EvidencesByType, type ExternalId, type Extra, type Extra1, type Extra2, type Extra3, type Finding, type FindingLinks, type FindingLinks1, type Findings, type Findings1, type FindingsByLevel, type GraphEdge, type GraphNode, type InvestigationCounts, type InvestigationGraph, type InvestigationName, type InvestigationWhitelist, type Justification, type KeyType, LEVEL_COLORS, LEVEL_ORDER, LEVEL_VALUES, type Level, type Namespace, type Namespace1, type ObjectKey, type ObjectType, type Observable, type ObservableAlias, type ObservableLink, type ObservableLinks, type Observables, type ObservablesByLevel, type ObservablesByType, type ObservablesByTypeAndLevel, type PropagationMode, type Reason, type Relationship, type RelationshipDirection, type Relationships, type RootType, type ScoreMode, type StatisticsSchema, type Subtype, type Subtype1, type Tag, type Tags, type Taxonomies, type Taxonomy, type ThreatIntel, type ThreatIntelByLevel, type ThreatIntelBySource, type ThreatIntels, type ThreatIntels1, type Tool, type Uri, type Whitelists, areConnected, compareLevels, countRelationshipsByType, findExternalObservables, findFindingByName, findFindingsAtLeast, findFindingsByLevel, findFindingsForObservable, findFindingsForTag, findHighestScoringFindings, findHighestScoringObservables, findInternalObservables, findLeafObservables, findMaliciousFindings, findMaliciousObservables, findObservablesAtLeast, findObservablesByLevel, findObservablesByType, findObservablesByValue, findObservablesContaining, findObservablesForFinding, findObservablesMatching, findObservablesWithThreatIntel, findOrphanObservables, findPath, findSourceObservables, findSuspiciousFindings, findSuspiciousObservables, findTagsAtLeast, findTagsByLevel, findTagsByNamePattern, findThreatIntelAtLeast, findThreatIntelByLevel, findThreatIntelBySource, findThreatIntelsForObservable, findWhitelistedObservables, generateEnrichmentKey, generateFindingKey, generateObservableKey, generateTagKey, generateThreatIntelKey, getAllEnrichments, getAllEvidences, getAllFindingKeys, getAllFindings, getAllObservableTypes, getAllObservables, getAllRelationshipTypes, getAllTags, getAllThreatIntelSources, getAllThreatIntels, getColorForLevel, getColorForScore, getCounts, getDataExtraction, getEnrichment, getEnrichmentByName, getEntityLevel, getEvidence, getFinding, getFindingByName, getLevelFromScore, getObservable, getObservableByTypeValue, getObservableChildren, getObservableGraph, getObservableParents, getReachableObservables, getRelatedObservables, getRelatedObservablesByDirection, getRelatedObservablesByType, getRelationshipsForObservable, getRootObservable, getStartedAt, getStats, getTag, getTagAggregatedLevel, getTagAggregatedScore, getTagAncestors, getTagByName, getTagChildren, getTagDescendants, getThreatIntel, getThreatIntelBySourceObservable, getWhitelists, hasLevel, isCyvest, isLevelAtLeast, isLevelHigherThan, isLevelLowerThan, isTagChildOf, isTagDescendantOf, isValidLevel, maxLevel, minLevel, normalizeLevel, parseCyvest, parseFindingKey, parseKeyType, parseObservableKey, parseThreatIntelKey, sortFindingsByLevel, sortFindingsByScore, sortObservablesByLevel, sortObservablesByScore, validateKey };
|
|
724
|
+
//#endregion
|
|
725
|
+
//#region src/verdicts.d.ts
|
|
726
|
+
/** Ordered from most exculpatory to most inculpatory. */
|
|
727
|
+
export declare const VERDICT_ORDER: readonly Verdict[];
|
|
728
|
+
/**
|
|
729
|
+
* Rich style names, mirroring the Python terminal renderer.
|
|
730
|
+
*
|
|
731
|
+
* These are *not* CSS colours: a browser cannot draw `orange3`. Use {@link VERDICT_HEX_COLORS}
|
|
732
|
+
* for anything rendered on screen.
|
|
733
|
+
*/
|
|
734
|
+
export declare const VERDICT_TERMINAL_STYLES: Record<Verdict, string>;
|
|
735
|
+
/** The web palette: muted enough that a wall of NOTABLE nodes stays readable. */
|
|
736
|
+
export declare const VERDICT_HEX_COLORS: Record<Verdict, string>;
|
|
737
|
+
/** Direction the judgment pushes: -1 exculpatory, 0 neutral, +1 inculpatory. */
|
|
738
|
+
export declare function verdictPolarity(verdict: Verdict): -1 | 0 | 1;
|
|
739
|
+
export declare function isValidVerdict(value: unknown): value is Verdict;
|
|
740
|
+
export declare function normalizeVerdict(value: unknown): Verdict;
|
|
741
|
+
export declare function compareVerdicts(a: Verdict, b: Verdict): number;
|
|
742
|
+
export declare function isVerdictAtLeast(verdict: Verdict, floor: Verdict): boolean;
|
|
743
|
+
export declare function maxVerdict(verdicts: readonly Verdict[]): Verdict;
|
|
744
|
+
export declare function minVerdict(verdicts: readonly Verdict[]): Verdict;
|
|
745
|
+
export declare function getColorForVerdict(verdict: Verdict): string;
|
|
746
|
+
/** Coarse bands for display; the engine works in floats. */
|
|
747
|
+
export declare function confidenceBand(confidence: number): "low" | "medium" | "high";
|
|
748
|
+
//#endregion
|
|
749
|
+
//#region src/getters.d.ts
|
|
750
|
+
export declare function getObservable(inv: Investigation, key: string): Observable$1 | undefined;
|
|
751
|
+
export declare function getAllObservables(inv: Investigation): Record<string, Observable$1>;
|
|
752
|
+
export declare function getRootObservable(inv: Investigation): Observable$1 | undefined;
|
|
753
|
+
export declare function getRelation(inv: Investigation, key: string): Relation$1 | undefined;
|
|
754
|
+
export declare function getAllRelations(inv: Investigation): Record<string, Relation$1>;
|
|
755
|
+
export declare function getThreatIntel(inv: Investigation, key: string): ThreatIntel$1 | undefined;
|
|
756
|
+
export declare function getAllThreatIntels(inv: Investigation): Record<string, ThreatIntel$1>;
|
|
757
|
+
/** Signals attached to one observable. */
|
|
758
|
+
export declare function getThreatIntelsFor(inv: Investigation, observableKey: string): ThreatIntel$1[];
|
|
759
|
+
export declare function getFinding(inv: Investigation, key: string): Finding$1 | undefined;
|
|
760
|
+
export declare function getAllFindings(inv: Investigation): Record<string, Finding$1>;
|
|
761
|
+
export declare function getEvidence(inv: Investigation, key: string): Evidence$1 | undefined;
|
|
762
|
+
export declare function getAllEvidences(inv: Investigation): Record<string, Evidence$1>;
|
|
763
|
+
/** The v6 `Enrichment` is just an evidence type; filter instead of a dedicated accessor. */
|
|
764
|
+
export declare function getEvidencesByType(inv: Investigation, evidenceType: string): Evidence$1[];
|
|
765
|
+
export declare function getDecision(inv: Investigation, key: string): Decision$1 | undefined;
|
|
766
|
+
export declare function getAllDecisions(inv: Investigation): Record<string, Decision$1>;
|
|
767
|
+
/** The single stance standing on a target — the key carries the target alone. */
|
|
768
|
+
export declare function getDecisionFor(inv: Investigation, targetKey: string): Decision$1 | undefined;
|
|
769
|
+
export declare function isAllowlisted(inv: Investigation, observableKey: string): boolean;
|
|
770
|
+
export declare function isBlocklisted(inv: Investigation, observableKey: string): boolean;
|
|
771
|
+
export declare function isConfirmed(inv: Investigation, findingKey: string): boolean;
|
|
772
|
+
export declare function isDismissed(inv: Investigation, findingKey: string): boolean;
|
|
773
|
+
/** True when a stance was withdrawn and the computed value applies again. */
|
|
774
|
+
export declare function isVacated(inv: Investigation, targetKey: string): boolean;
|
|
775
|
+
/**
|
|
776
|
+
* The analyst's word for a stance, rebuilt from the intent and the family of its target.
|
|
777
|
+
*
|
|
778
|
+
* The model carries one axis on purpose; the vocabulary that reads naturally carries two, and
|
|
779
|
+
* the display layer is the right place to pay for that.
|
|
780
|
+
*/
|
|
781
|
+
export declare function decisionLabel(decision: Decision$1): string;
|
|
782
|
+
export declare function getTag(inv: Investigation, key: string): Tag$1 | undefined;
|
|
783
|
+
export declare function getTagByName(inv: Investigation, name: string): Tag$1 | undefined;
|
|
784
|
+
export declare function getAllTags(inv: Investigation): Record<string, Tag$1>;
|
|
785
|
+
export declare function getInvestigationResult(inv: Investigation): InvestigationResult$1;
|
|
786
|
+
export declare function getObservableResult(inv: Investigation, observableKey: string): ObservableResult$1 | undefined;
|
|
787
|
+
export declare function getFindingResult(inv: Investigation, findingKey: string): FindingResult$1 | undefined;
|
|
788
|
+
export declare function getObservableScore(inv: Investigation, observableKey: string): number;
|
|
789
|
+
export declare function getObservableVerdict(inv: Investigation, observableKey: string): Verdict;
|
|
790
|
+
export declare function getFindingScore(inv: Investigation, findingKey: string): number;
|
|
791
|
+
export declare function getFindingVerdict(inv: Investigation, findingKey: string): Verdict;
|
|
792
|
+
export declare function getGlobalScore(inv: Investigation): number;
|
|
793
|
+
export declare function getGlobalVerdict(inv: Investigation): Verdict;
|
|
794
|
+
/** True when a decision or a stronger link overrode the computed value. */
|
|
795
|
+
export declare function wasSuppressed(inv: Investigation, key: string): boolean;
|
|
796
|
+
/** Findings a tag points at, plus those of every descendant tag. */
|
|
797
|
+
export declare function getTagFindingKeys(inv: Investigation, tagName: string): string[];
|
|
798
|
+
/**
|
|
799
|
+
* A tag's aggregated score.
|
|
800
|
+
*
|
|
801
|
+
* This sums values the engine produced; it does not re-derive them. Uncounted findings — not
|
|
802
|
+
* applicable, pending or dismissed — are absent from the sum *and* from any ratio built on it.
|
|
803
|
+
*/
|
|
804
|
+
export declare function getTagAggregatedScore(inv: Investigation, tagName: string): number;
|
|
805
|
+
export interface InvestigationCounts {
|
|
806
|
+
observables: number;
|
|
807
|
+
relations: number;
|
|
808
|
+
signals: number;
|
|
809
|
+
evidences: number;
|
|
810
|
+
findings: number;
|
|
811
|
+
evaluatedFindings: number;
|
|
812
|
+
decisions: number;
|
|
813
|
+
tags: number;
|
|
814
|
+
}
|
|
815
|
+
export declare function getCounts(inv: Investigation): InvestigationCounts;
|
|
816
|
+
//#endregion
|
|
817
|
+
//#region src/finders.d.ts
|
|
818
|
+
export declare function findObservablesByType(inv: Investigation, type: string): Observable$1[];
|
|
819
|
+
export declare function findObservablesByValue(inv: Investigation, value: string): Observable$1[];
|
|
820
|
+
export declare function findObservablesContaining(inv: Investigation, fragment: string): Observable$1[];
|
|
821
|
+
export declare function findInternalObservables(inv: Investigation): Observable$1[];
|
|
822
|
+
export declare function findExternalObservables(inv: Investigation): Observable$1[];
|
|
823
|
+
export declare function findObservablesByVerdict(inv: Investigation, verdict: Verdict): Observable$1[];
|
|
824
|
+
export declare function findObservablesAtLeast(inv: Investigation, floor: Verdict): Observable$1[];
|
|
825
|
+
export declare function findObservablesWithThreatIntel(inv: Investigation): Observable$1[];
|
|
826
|
+
export declare function findFindingsByVerdict(inv: Investigation, verdict: Verdict): Finding$1[];
|
|
827
|
+
export declare function findFindingsAtLeast(inv: Investigation, floor: Verdict): Finding$1[];
|
|
828
|
+
export declare function findFindingsByRule(inv: Investigation, ruleId: string): Finding$1[];
|
|
829
|
+
export declare function findFindingsByConfidence(inv: Investigation, band: "low" | "medium" | "high"): Finding$1[];
|
|
830
|
+
/** Findings excluded from the score but still worth showing, with their reason. */
|
|
831
|
+
export declare function findUncountedFindings(inv: Investigation): Finding$1[];
|
|
832
|
+
/** Findings whose own claim was outweighed by one of their observables — worth surfacing. */
|
|
833
|
+
export declare function findContradictedFindings(inv: Investigation): Finding$1[];
|
|
834
|
+
export declare function findThreatIntelBySource(inv: Investigation, source: string): ThreatIntel$1[];
|
|
835
|
+
export declare function findThreatIntelByVerdict(inv: Investigation, verdict: Verdict): ThreatIntel$1[];
|
|
836
|
+
export declare function findThreatIntelForObservable(inv: Investigation, observableKey: string): ThreatIntel$1[];
|
|
837
|
+
//#endregion
|
|
838
|
+
//#region src/graph.d.ts
|
|
839
|
+
export interface GraphEdge {
|
|
840
|
+
key: string;
|
|
841
|
+
source: string;
|
|
842
|
+
target: string;
|
|
843
|
+
kind: string;
|
|
844
|
+
confidence: number;
|
|
845
|
+
/** True when the edge actually carried score, per the report's contributions. */
|
|
846
|
+
carriedScore: boolean;
|
|
847
|
+
}
|
|
848
|
+
export interface GraphNode {
|
|
849
|
+
key: string;
|
|
850
|
+
observable: Observable$1;
|
|
851
|
+
score: number;
|
|
852
|
+
verdict: string;
|
|
853
|
+
}
|
|
854
|
+
export interface InvestigationGraph {
|
|
855
|
+
nodes: GraphNode[];
|
|
856
|
+
edges: GraphEdge[];
|
|
857
|
+
}
|
|
858
|
+
export declare function getObservableChildren(inv: Investigation, observableKey: string): Observable$1[];
|
|
859
|
+
export declare function getObservableParents(inv: Investigation, observableKey: string): Observable$1[];
|
|
860
|
+
export declare function getRelatedObservables(inv: Investigation, observableKey: string): Observable$1[];
|
|
861
|
+
export declare function getRelationsForObservable(inv: Investigation, observableKey: string): Relation$1[];
|
|
862
|
+
export declare function countRelationsByKind(inv: Investigation): Record<string, number>;
|
|
863
|
+
export declare function getObservableGraph(inv: Investigation): InvestigationGraph;
|
|
864
|
+
export declare function areConnected(inv: Investigation, a: string, b: string): boolean;
|
|
865
|
+
/** Undirected reachability — the same walk `finalize_relationships` uses to spot orphans. */
|
|
866
|
+
export declare function getReachableObservables(inv: Investigation, start: string): Set<string>;
|
|
867
|
+
export declare function findOrphanObservables(inv: Investigation): Observable$1[];
|
|
868
|
+
export declare function findLeafObservables(inv: Investigation): Observable$1[];
|
|
869
|
+
export declare function findSourceObservables(inv: Investigation): Observable$1[];
|
|
870
|
+
//#endregion
|
|
871
|
+
export type { Investigation };
|