-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodel.capa
More file actions
126 lines (109 loc) · 3.39 KB
/
Copy pathmodel.capa
File metadata and controls
126 lines (109 loc) · 3.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// model.capa
//
// Shared domain types for policy-eval.
//
// The headline shape is ``Condition``, a sum type whose AllOf /
// AnyOf / NotMatch variants carry payloads of type Condition.
// Self-referential variants let policies nest arbitrarily deep
// in JSON; the evaluator is then a textbook tree-walk.
// =========================================================
// Severity (ordered)
// =========================================================
pub type Severity =
Info
Low
Medium
High
Critical
pub fun severity_name(s: Severity) -> String
return match s
Info -> "Info"
Low -> "Low"
Medium -> "Medium"
High -> "High"
Critical -> "Critical"
pub fun severity_rank(s: Severity) -> Int
return match s
Info -> 0
Low -> 1
Medium -> 2
High -> 3
Critical -> 4
pub fun parse_severity(s: String) -> Severity
if s == "Critical" or s == "critical"
return Critical
if s == "High" or s == "high"
return High
if s == "Medium" or s == "medium"
return Medium
if s == "Low" or s == "low"
return Low
return Info
// =========================================================
// Condition AST (the recursive type)
// =========================================================
//
// Leaf nodes test a value at a dotted path; combinator nodes
// recurse. The evaluator returns Bool: does this Condition
// match the resource?
pub type Condition =
PathEquals(String, JsonValue) // path == value
PathNotEquals(String, JsonValue) // path != value
PathIn(String, List<JsonValue>) // path in [v1, v2, ...]
PathContains(String, JsonValue) // path is a list containing value
PathExists(String, Bool) // path exists (true) or absent (false)
AllOf(List<Condition>) // recursive: AND
AnyOf(List<Condition>) // recursive: OR
NotMatch(Condition) // recursive: NOT
// =========================================================
// Rule + Finding
// =========================================================
pub type Rule {
name: String,
severity: Severity,
condition: Condition,
message: String
}
pub type Policy {
name: String,
rules: List<Rule>
}
pub type Finding {
rule_name: String,
resource_type: String,
resource_name: String,
severity: Severity,
message: String
}
// =========================================================
// Resources (subject)
// =========================================================
//
// Each resource keeps its original JSON envelope so the
// evaluator can drill into arbitrary paths without us
// committing to a fixed shape.
pub type Resource {
res_type: String,
res_name: String,
raw: JsonValue // the whole {"type","name","config":...} object
}
pub type Subject {
environment: String,
snapshot_at: String,
resources: List<Resource>
}
// =========================================================
// Errors + Options
// =========================================================
pub type EvalError =
JsonError(String)
IoFailed(String)
BadArgs(String)
BadPolicy(String)
pub type Options {
policy_path: String,
subject_path: String,
output_dir: String,
fail_threshold: Severity,
verbose: Bool
}