-
Notifications
You must be signed in to change notification settings - Fork 0
/
rego.vtt
462 lines (345 loc) · 15.3 KB
/
rego.vtt
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
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
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
WEBVTT
Kind: captions
Language: en
00:00:00.160 --> 00:00:02.240
This training session will cover Rego.
00:00:03.280 --> 00:00:06.320
Rego is a declarative language
for defining policies.
00:00:06.960 --> 00:00:11.280
Rego policies are expressed as
predicates over structured data.
00:00:11.280 --> 00:00:15.040
This structured data is represented
using javascript object notation.
00:00:15.600 --> 00:00:20.640
This training covers the basic Rego features that
will be needed to implement provenance policies.
00:00:21.360 --> 00:00:26.720
Policies in Rego begin with a head, which is
the name of the policy. The head is followed
00:00:26.720 --> 00:00:31.040
by the body, which defines a list of
expressions inside a pair of braces.
00:00:31.600 --> 00:00:35.680
Each expression in the body is evaluated
to determine if the policy is true
00:00:35.680 --> 00:00:44.080
or false. For example, policy1 on the right is
true if all of the expressions 1 to n are true.
00:00:44.080 --> 00:00:48.560
Rego provides many operators seen in
other languages such as arithmetic,
00:00:48.560 --> 00:00:54.320
assignment, or equality. Note that variables are
immutable meaning they cannot be changed after
00:00:54.320 --> 00:01:00.000
their initial assignment. The example policy
named final_policy demonstrates comments,
00:01:00.000 --> 00:01:06.320
assignment, arithmetic, and equality. Final_policy
will always evaluate to true in this case.
00:01:07.920 --> 00:01:13.040
In Rego, arguments may be optionally
passed to policies. The syntax is similar
00:01:13.040 --> 00:01:18.720
to functions in many other languages.
For example, the following policy isZero
00:01:18.720 --> 00:01:22.480
returns true if the argument x is equal to zero.
00:01:23.600 --> 00:01:29.360
Input is created using javascript object
notation or JSON. Provenance graphs can be
00:01:29.360 --> 00:01:35.440
defined as a set of vertices and edges. Each
vertex contains a name and a type and each
00:01:35.440 --> 00:01:42.080
edge contains a relation type, a source, and a
destination. For example, the provenance graph
00:01:42.080 --> 00:01:47.760
below can be defined using the following JSON. The
graph has two vertices and an edge between them.
00:01:48.480 --> 00:01:55.440
JSON data consists of a name and value pair. For
example, name colon Average is one such pair.
00:01:55.440 --> 00:01:59.120
There are two key-value types needed
for defining provenance graphs:
00:01:59.120 --> 00:02:05.120
objects and arrays. Braces define an object and
values can be accessed using the dot operator.
00:02:05.680 --> 00:02:10.400
Brackets define an array; the usual
bracket notation can be used to access
00:02:10.400 --> 00:02:17.120
values in the array. For example,
input dot vertices bracket 0 dot name
00:02:17.120 --> 00:02:21.840
is Average in the input on the right.
This notation can be used in Rego.
00:02:22.880 --> 00:02:27.680
Now let's cover some common scenarios. The
negation policy asserts that a policy or
00:02:27.680 --> 00:02:33.520
expression is not true. In rego, this can be
done using the not keyword. The not keyword
00:02:33.520 --> 00:02:39.600
can be followed by a policy name or expression. In
the left example, the not keyword is used with an
00:02:39.600 --> 00:02:46.000
expression, while in the right example, it is used
with a policy name. These examples are equivalent.
00:02:46.560 --> 00:02:52.000
The conjunction policy, also called "and",
asserts that multiple expressions are true.
00:02:52.000 --> 00:02:59.280
Conjunction is implicit in rego. For final_policy
to be true, both e1 and e2 must be true.
00:02:59.280 --> 00:03:04.960
The disjunction policy, also called "or",
asserts that either expression e1 is true,
00:03:04.960 --> 00:03:11.360
e2 is true, or both e1 and e2 are true.
For disjunction in rego. define two
00:03:11.360 --> 00:03:17.280
policies with the same name. For example, the
following two policies are named final_policy.
00:03:17.280 --> 00:03:21.760
If either instance is true, then
final_policy will evaluate to true.
00:03:22.720 --> 00:03:28.240
The existential policy asserts that an
expression is true for some variable x.
00:03:28.240 --> 00:03:32.960
Variable x can be used in that
expression. To define such a policy,
00:03:32.960 --> 00:03:38.560
the some keyword can be used. The following
policy requires there exists some vertex
00:03:38.560 --> 00:03:45.840
x named Average. The vertex can be used as a
placeholder to access arrays, as in this example.
00:03:46.400 --> 00:03:52.720
The universal policy asserts that an expression
is true for every possible variable x. Variable
00:03:52.720 --> 00:03:58.560
x can be used in that expression. Rego does
not explicitly support this, however, it can be
00:03:58.560 --> 00:04:05.520
accomplished by defining an existential policy and
negating that policy. Final_policy requires that
00:04:05.520 --> 00:04:12.640
for all vertices x, x is not named Average. This
is done by defining averageExists, a helper policy
00:04:12.640 --> 00:04:19.680
which requires there exists some x named Average.
Final_policy then negates this helper policy.
00:04:20.720 --> 00:04:26.400
The edge policy asserts there is an edge between
two vertices with a certain label or relation.
00:04:26.960 --> 00:04:33.520
Possible labels are: was attributed to,
was derived from, was generated by, used,
00:04:34.080 --> 00:04:41.440
acted on behalf of, was associated with, or
was informed by. While rego does not explicitly
00:04:41.440 --> 00:04:46.960
support this either, it can be accomplished using
the some keyword and the equality operator. The
00:04:46.960 --> 00:04:53.600
example policy requires an edge with label used
to exist between the Average and SalaryB vertices.
00:04:54.160 --> 00:04:59.920
To write a policy that combines the existential
and universal policies in Rego, the policy
00:04:59.920 --> 00:05:06.080
argument feature is required. The following
slide has an example. The following policy
00:05:06.080 --> 00:05:12.720
combines universal and existential policies: for
all node agents, there exists some outgoing edge.
00:05:13.360 --> 00:05:17.200
The following Rego implements
this policy. At the bottom,
00:05:17.200 --> 00:05:23.600
the hasEdges policy checks if vertex x has
an outgoing edge. The nodeNoEdge policy
00:05:23.600 --> 00:05:29.120
returns true if there exists some node agent and
that node agent has no edges. This is done by
00:05:29.120 --> 00:05:36.320
passing the node agent to the hasEdges policy and
negating the result. Finally, similar to before,
00:05:36.320 --> 00:05:41.920
final_policy negates the nodeNoEdge policy.
If there is no node agent without an edge,
00:05:41.920 --> 00:05:47.760
then all node agents must have at least one
outgoing edge, and final_policy is thus true.
00:05:49.680 --> 00:05:52.240
Now let's go over some provenance examples.
00:05:52.240 --> 00:05:56.960
The following interface will be provided to
implement your rego policies. The left section
00:05:56.960 --> 00:06:02.960
provides a code editor with syntax highlighting
to define your policies. Note your final answer
00:06:02.960 --> 00:06:08.160
should be named final_policy. This will be
the policy used for determining correctness.
00:06:08.800 --> 00:06:14.000
On the right, the question and a few example
inputs are provided. The inputs are provided
00:06:14.000 --> 00:06:19.120
in the JSON format seen earlier. You may switch
between the different examples using the tabs
00:06:19.120 --> 00:06:24.800
above. Each input contains a note saying if
it should or should not satisfy the policy.
00:06:25.440 --> 00:06:30.240
Finally, once you are ready to test your
policy, you may use the evaluate button below.
00:06:30.240 --> 00:06:33.840
If your policy is correct, you will
be presented with a correct message.
00:06:35.360 --> 00:06:41.520
Write a policy to ensure that activity
Average used data entity SalaryB. First,
00:06:41.520 --> 00:06:47.840
let's take a look at the sample input. Input 1
has an edge between Average and SalaryB, which
00:06:47.840 --> 00:06:56.720
is labeled used, seen here. As the hint suggests,
this input should satisfy the policy. Inputs 2
00:06:56.720 --> 00:07:01.840
and 4 should also satisfy the
policy, while 3 and 5 do not.
00:07:03.600 --> 00:07:08.640
Since we need to check for the existence of an
edge, we begin with the some keyword to create
00:07:08.640 --> 00:07:15.920
variable i like so. I represents
some edge in the input. Using i,
00:07:15.920 --> 00:07:21.600
we place requirements on the edge by using the
input keyword and accessing the edges array,
00:07:27.120 --> 00:07:36.560
like so. In this case, we require that the
relation be used, we require that the source
00:07:36.560 --> 00:07:43.840
be Average, and for the destination to
be SalaryB. We implement this like so.
00:07:56.720 --> 00:07:58.480
And finally the destination.
00:08:02.080 --> 00:08:07.600
And perfect. When we click evaluate, each
possible value for i will be used until
00:08:07.600 --> 00:08:12.880
one is found that makes all three
equalities true. If none is found,
00:08:12.880 --> 00:08:17.440
the policy evaluates to false. In this
case, our policy works correctly for
00:08:17.440 --> 00:08:21.840
all five inputs and you can see that we
have received the correct message here.
00:08:22.880 --> 00:08:28.400
Write a policy to ensure that data entity
AverageSalary was not derived from SalaryC.
00:08:29.680 --> 00:08:33.040
For this policy, we need to check
that, for all data entities,
00:08:33.040 --> 00:08:39.120
AverageSalary was not derived from SalaryC.
Since this is a universal policy, we need to
00:08:39.120 --> 00:08:46.640
first define the opposite existential policy;
that is, AverageSalary is derived from SalaryC.
00:08:47.840 --> 00:08:56.000
The existential policy named derivedSalC is very
similar to the previous example. Some x is used to
00:08:56.000 --> 00:09:02.640
find if there exists an edge with the correct
relation source and destination. To finish,
00:09:02.640 --> 00:09:10.240
final_policy negates derivedSalC, returning true
if AverageSalary was not derived from SalaryC.
00:09:11.440 --> 00:09:18.720
Write a policy to ensure that activity Average
used key entity KeyB and KeyB was attributed to
00:09:18.720 --> 00:09:24.800
account agent Bob. For this policy, there are
two different edges that must be checked for:
00:09:24.800 --> 00:09:27.520
one labeled used between Average and KeyB
00:09:28.160 --> 00:09:35.280
and one labeled was attributed to between KeyB and
Bob. Since two different edges must be checked,
00:09:35.280 --> 00:09:40.560
the some keyword is used to declare an
x and a y. The x is used to find if the
00:09:40.560 --> 00:09:47.440
edge between Average and KeyB exists, and
y is used to find the edge between KeyB and
00:09:47.440 --> 00:09:53.600
Bob. If an x and y can be found that makes these
equalities true, then final_policy returns true.
00:09:54.480 --> 00:09:59.520
Write a policy to ensure that there is some
data entity that AverageSalary was derived from.
00:10:00.320 --> 00:10:05.440
This example requires that an edge, starting
at AverageSalary, ends in a data entity.
00:10:06.080 --> 00:10:11.200
This requires us to check the vertex type,
which can only be found in the vertex array.
00:10:11.840 --> 00:10:15.280
To do this, the some keyword creates an x variable
00:10:15.280 --> 00:10:22.080
to represent the edge and a y to represent the
vertex. The policy begins by finding an x such
00:10:22.080 --> 00:10:29.680
that the edge is labeled was derived from and
begins at salary. Next, both x and y are used
00:10:29.680 --> 00:10:35.760
to find the destination vertex by comparing
the name. Finally, the vertex type is checked.
00:10:36.960 --> 00:10:43.040
Write a policy to ensure for every data entity,
if activity Average used the data entity,y
00:10:43.040 --> 00:10:49.760
then the data entity was attributed to either
Bob, Alice, or Mallory. This policy requires
00:10:49.760 --> 00:10:54.480
all of the techniques seen earlier.
First, this is a universal policy
00:10:54.480 --> 00:11:01.760
as we must check every data entity. Thus, we first
need the opposite existential policy; that is,
00:11:01.760 --> 00:11:08.480
one of the data entities was attributed to someone
other than Bob, Alice, or Mallory. A helper policy
00:11:08.480 --> 00:11:15.600
notBAM will check for this. We will need to
check two edges and a vertex for this policy.
00:11:16.240 --> 00:11:22.560
First, we use x to find the used edge from average
and then use y to find the destination vertex.
00:11:23.360 --> 00:11:30.480
Y is then used to check the vertex type and is
then used with z to find an outgoing edge. Z
00:11:30.480 --> 00:11:36.000
is used to check the edge label and that the
destination is not Bob, Alice, or Mallory.
00:11:36.800 --> 00:11:41.840
To finish, the final_policy
negates the notBAM policy.
00:11:43.760 --> 00:11:48.720
In the case of an incorrect policy, an
error message will be presented. Syntax
00:11:48.720 --> 00:11:52.960
or other errors in the code will be presented
with a line number to help find the error.
00:11:53.760 --> 00:12:00.640
If the policy is valid but incorrect the
warning will list the inputs that did not pass.