1# Policy Engine Simulator
2
3This tool provides a means to test out security policies. Usage:
4
5```
6 -commands string
7 path to commands JSON file
8 -data string
9 path to initial data state JSON file (optional)
10 -log string
11 path to output log file
12 -logLevel string
13 None|Info|Results|Metadata (default "Info")
14 -policy string
15 path to policy Rego file
16```
17
18## Getting started
19
20From the tool directory run:
21
22 go run . -policy [samples/simple_framework/policy.rego](samples/simple_framework/policy.rego) -commands [samples/simple_framework/commands.json](samples/simple_framework/commands.json)
23
24This will load the authored policy and then simulate the enforcement behavior
25for the provided commands.
26
27This policy uses the framework, however, the simulator also handles completely
28custom policies:
29
30 go run . -policy [samples/simple_custom/policy.rego](samples/simple_framework/policy.rego) -commands [samples/simple_custom/commands.json](samples/simple_custom/commands.json)
31
32## Commands
33
34Consists of a sequential list of commands that will be issued for enforcement to
35the policy. Some sample commands can be seen here:
36
37- [Framework Example Commands](samples/simple_custom/commands.json)
38- [Custom Example Commands](samples/simple_framework/commands.json)
39
40These commands take the form of JSON objects, *e.g.*:
41
42``` json
43[
44 {
45 "name": "load_fragment",
46 "input": {
47 "issuer": "did:web:contoso.github.io",
48 "feed": "contoso.azurecr.io/custom",
49 "namespace": "custom",
50 "local_path": "custom.rego"
51 }
52 },
53 {
54 "name": "mount_device",
55 "input": {
56 "target": "/mnt/layer0",
57 "deviceHash": "16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"
58 }
59 },
60 {
61 "name": "mount_overlay",
62 "input": {
63 "target": "/mnt/overlay0",
64 "containerID": "container0",
65 "layerPaths": [
66 "/mnt/layer0"
67 ]
68 }
69 },
70 {
71 "name": "create_container",
72 "input": {
73 "containerID": "container0",
74 "argList": [
75 "/pause"
76 ],
77 "envList": [
78 "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
79 "TERM=xterm"
80 ],
81 "mounts": [],
82 "workingDir": "/",
83 "sandboxDir": "/sandbox",
84 "hugePagesDir": "/hugepages"
85 }
86 }
87]
88```
89
90Each command has a name (corresponding to the API enforcement point) and then
91an input which will be passed directly to the policy. The API being tested
92is defined in [`api.rego`](../../../pkg/securitypolicy/api.rego).
93
94## Data
95
96If the authored policy requires certain values in the Rego data structure to
97function, or if the author wants to test enforcement behavior given a known
98starting state, they can provide an optional initial data file as an argument
99to the tool. This should take the form of a single JSON object, *e.g.*:
100
101``` json
102{
103 "defaultMounts": [/*some mount constraint objects*/],
104 "privilegedMounts": [/*some mount constraint objects*/],
105 "sandboxPrefix": "sandbox://",
106 "hugePagesPrefix": "hugepages://"
107}
108```
109
110## Log
111
112To aid in debugging, the user can specify a log file. This will enable logging
113at the `Info` level, which consists of the output of any Rego `print()` calls
114from the policy.
115
116## Log Level
117
118There are several log levels that the user can use to gain greater insight into
119policy enforcement:
120
121| Name | Description |
122| ---------- | --------------------------------------------------------- |
123| `None` | Used when no log file is provided via the `-log` argument |
124| `Info` | Outputs the results of Rego `print()` statements. |
125| `Results` | Outputs the results returned by each policy query |
126| `Metadata` | Outputs the entire metadata state after each query |
127
128## Policy
129
130This can be any Rego with a package name of `policy`, though policies which do
131not define the required enforcement point rules will result in enforcement
132failures. We include some straightforward samples below, but see
133[simple_custom](simple_custom) and [simple_framework](simple_framework)
134for more detail.
135
136### Framework-based policy
137
138``` rego
139package policy
140
141api_version := "0.7.0"
142
143import future.keywords.every
144import future.keywords.in
145
146containers := [
147 {
148 "command": ["/pause"],
149 "env_rules": [
150 {
151 "pattern": "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
152 "strategy": "string",
153 "required": false
154 },
155 {
156 "pattern": "TERM=xterm",
157 "strategy": "string",
158 "required": false
159 }
160 ],
161 "layers": ["16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"],
162 "mounts": [],
163 "exec_processes": [],
164 "signals": [],
165 "allow_elevated": false,
166 "working_dir": "/"
167 }
168]
169
170mount_device := data.framework.mount_device
171unmount_device := data.framework.unmount_device
172mount_overlay := data.framework.mount_overlay
173unmount_overlay := data.framework.unmount_overlay
174create_container := data.framework.create_container
175exec_in_container := data.framework.exec_in_container
176exec_external := data.framework.exec_external
177shutdown_container := data.framework.shutdown_container
178signal_container_process := data.framework.signal_container_process
179plan9_mount := data.framework.plan9_mount
180plan9_unmount := data.framework.plan9_unmount
181load_fragment := data.framework.load_fragment
182reason := {"errors": data.framework.errors}
183```
184
185### Custom Policy
186
187``` rego
188package policy
189
190api_version := "0.7.0"
191
192overlays := {
193 "pause": {
194 "deviceHashes": ["16b514057a06ad665f92c02863aca074fd5976c755d26bff16365299169e8415"],
195 "mounts": []
196 }
197}
198
199custom_containers := [
200 {
201 "id": "pause",
202 "command": ["/pause"],
203 "overlayID": "pause",
204 "depends": []
205 }
206]
207
208mount_device := data.custom.mount_device
209mount_overlay := data.custom.mount_overlay
210create_container := data.custom.create_container
211unmount_device := {"allowed": true}
212unmount_overlay := {"allowed": true}
213exec_in_container := {"allowed": true}
214exec_external := {"allowed": true}
215shutdown_container := {"allowed": true}
216signal_container_process := {"allowed": true}
217plan9_mount := {"allowed": true}
218plan9_unmount := {"allowed": true}
219
220default load_fragment := {"allowed": false}
221load_fragment := {"allowed": true, "add_module": true} {
222 input.issuer == "did:web:contoso.github.io"
223 input.feed == "contoso.azurecr.io/custom"
224}
225```
View as plain text