Skip to content

Commit c371632

Browse files
update opa learn things
Signed-off-by: ivan katliarchuk <[email protected]>
1 parent 0a42ccf commit c371632

File tree

4 files changed

+181
-0
lines changed

4 files changed

+181
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [Opa: 101](https://www.permit.io/blog/load-external-data-into-opa)
1111
- [Rego Cool blog](https://www.styra.com/blog/how-to-express-or-in-rego/)
1212
- [Rego Style guide](https://docs.styra.com/opa/rego-style-guide)
13+
- [Opa Cheat Sheet](https://docs.styra.com/opa/rego-cheat-sheet)
1314

1415
## Example Repositories
1516

playground/ex30/policy.rego

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# https://github.com/open-policy-agent/opa/issues/2755
2+
3+
default jwt_exists = false
4+
jwt_exists {
5+
count(jwt_exists_a) > 0
6+
}
7+
jwt_exists_a[r] {
8+
regex.match(`^[A-Za-z0-9-_=]+\.[A-Za-z0-9-_=]+\.?[A-Za-z0-9-_.+/=]*$`, sso_jwt)
9+
r := "input.sso_jwt contains a syntactically valid jwt"
10+
}
11+
jwt_exists_d[r] {
12+
not jwt_exists
13+
r := "input.sso_jwt did not contain a syntactically valid jwt"
14+
}
15+
16+
# Decode the jwt contained in input.sso_jwt
17+
default jwt = null
18+
jwt = t {
19+
jwt_exists
20+
[_, payload, _] = io.jwt.decode(sso_jwt)
21+
t := {
22+
"payload": payload
23+
}
24+
}
25+
26+
# check if the jwt is signed
27+
default jwt_is_signed = false
28+
jwt_is_signed {
29+
count(jwt_is_signed_a) > 0
30+
}
31+
jwt_is_signed_a[r] {
32+
jwt_exists
33+
custom_builtin_verify_jwt(api_host, sso_jwt)
34+
r := {"input.sso_jwt is signed"} | jwt_exists_a
35+
}
36+
jwt_is_signed_d[r] {
37+
not jwt_is_signed
38+
r := {"input.sso_jwt is not signed"} | jwt_exists_d
39+
}
40+
41+
# get employee information in the jwt payload
42+
default employee = null
43+
employee = e {
44+
count(employee_a) > 0
45+
e := {
46+
"username": jwt.payload.username
47+
}
48+
}
49+
employee_a[r] {
50+
jwt_is_signed
51+
jwt_has_expected_prop_2
52+
jwt_has_expected_prop_3
53+
r := {"jwt represents an employee"} | jwt_is_signed_a | jwt_has_expected_prop_2_a | jwt_has_expected_prop_3_a
54+
}
55+
employee_d[r] {
56+
is_null(employee)
57+
r := {"jwt does not represent an employee"} | jwt_is_signed_d | jwt_has_expected_prop_2_d | jwt_has_expected_prop_3_d
58+
}
59+
60+
# check if the jwt has not exceeded its ttl
61+
default jwt_is_fresh = false
62+
jwt_is_fresh {
63+
count(jwt_is_fresh_a) > 0
64+
}
65+
jwt_is_fresh_a[r] {
66+
(round(time.now_ns() / 1e9) - jwt.payload.iat) < max_ttl
67+
r := "jwt is fresh"
68+
}
69+
jwt_is_fresh_d[r] {
70+
not jwt_is_fresh
71+
r := "jwt is not fresh"
72+
}
73+
74+
# can we do a thing
75+
default can_do_thing = false
76+
can_do_thing {
77+
count(can_do_thing_a) > 0
78+
}
79+
can_do_thing_a[r] {
80+
not is_null(employee)
81+
jwt_is_fresh
82+
r := employee_a | jwt_is_fresh_a
83+
}
84+
can_do_thing_d[r] {
85+
not can_do_thing
86+
r := employee_d | jwt_is_fresh_d
87+
}

playground/ex31/policy.rego

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# METADATA
2+
# title: My Example Package
3+
# description: A set of rules illustrating how metadata annotations can be merged.
4+
# authors:
5+
# - John Doe <[email protected]>
6+
# organizations:
7+
# - Acme Corp.
8+
package example
9+
10+
# https://www.openpolicyagent.org/docs/latest/policy-reference/
11+
# opa eval --data playground/ex31 --format pretty 'data.example.allow'
12+
13+
# METADATA
14+
# scope: document
15+
# description: A rule that merges metadata annotations in various ways.
16+
17+
# METADATA
18+
# title: My Allow Rule
19+
# authors:
20+
# - Jane Doe <[email protected]>
21+
allow if {
22+
meta := merge(rego.metadata.chain())
23+
meta.title == "My Allow Rule" # 'title' pulled from 'rule' scope
24+
meta.description == "A rule that merges metadata annotations in various ways." # 'description' pulled from 'document' scope
25+
meta.authors == {
26+
{"email": "[email protected]", "name": "Jane Doe"}, # 'authors' joined from 'package' and 'rule' scopes
27+
{"email": "[email protected]", "name": "John Doe"},
28+
}
29+
meta.organizations == {"Acme Corp."} # 'organizations' pulled from 'package' scope
30+
}
31+
32+
allow if {
33+
meta := merge(rego.metadata.chain())
34+
meta.title == null # No 'title' present in 'rule' or 'document' scopes
35+
meta.description == "A rule that merges metadata annotations in various ways." # 'description' pulled from 'document' scope
36+
meta.authors == { # 'authors' pulled from 'package' scope
37+
{"email": "[email protected]", "name": "John Doe"}
38+
}
39+
meta.organizations == {"Acme Corp."} # 'organizations' pulled from 'package' scope
40+
}
41+
42+
merge(chain) := meta if {
43+
print(chain)
44+
output := opa.runtime()
45+
print("output:", output)
46+
ruleAndDoc := ["rule", "document"]
47+
meta := {
48+
"title": override_annot(chain, "title", ruleAndDoc), # looks for 'title' in 'rule' scope, then 'document' scope
49+
"description": override_annot(chain, "description", ruleAndDoc), # looks for 'description' in 'rule' scope, then 'document' scope
50+
"related_resources": override_annot(chain, "related_resources", ruleAndDoc), # looks for 'related_resources' in 'rule' scope, then 'document' scope
51+
"authors": merge_annot(chain, "authors"), # merges all 'authors' across all scopes
52+
"organizations": merge_annot(chain, "organizations"), # merges all 'organizations' across all scopes
53+
}
54+
}
55+
56+
override_annot(chain, name, scopes) := val if {
57+
val := [v |
58+
link := chain[_]
59+
link.annotations.scope in scopes
60+
v := link.annotations[name]
61+
][0]
62+
} else := null
63+
64+
merge_annot(chain, name) := val if {
65+
val := {v |
66+
v := chain[_].annotations[name][_]
67+
}
68+
} else := null

playground/ex32/policy.rego

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package example
2+
3+
# https://www.openpolicyagent.org/docs/latest/policy-reference/
4+
# opa eval --data playground/ex32 --format pretty 'data.example.deny'
5+
6+
# METADATA
7+
# title: Deny invalid numbers
8+
# description: Numbers may not be higher than 5
9+
# custom:
10+
# severity: MEDIUM
11+
deny contains format(rego.metadata.rule()) if {
12+
print(rego.metadata.rule())
13+
input.number > 5
14+
}
15+
16+
# METADATA
17+
# title: Deny non-admin subjects
18+
# description: Subject must have the 'admin' role
19+
# custom:
20+
# severity: HIGH
21+
deny contains format(rego.metadata.rule()) if {
22+
input.subject.role != "admin"
23+
}
24+
25+
format(meta) := {"severity": meta.custom.severity, "reason": meta.description}

0 commit comments

Comments
 (0)