mirror of
https://github.com/pomerium/pomerium.git
synced 2025-08-04 17:29:16 +02:00
authorize: update opa rego to support additional policy properties
This commit is contained in:
parent
5ecfa34361
commit
428dee99c4
2 changed files with 143 additions and 11 deletions
|
@ -8,7 +8,7 @@ default allow = false
|
|||
# allow by email
|
||||
allow {
|
||||
some route
|
||||
input.host = route_policies[route].source
|
||||
allowed_route(input.url, route_policies[route])
|
||||
token.payload.email = route_policies[route].allowed_users[_]
|
||||
token.valid
|
||||
count(deny)==0
|
||||
|
@ -17,7 +17,7 @@ allow {
|
|||
# allow group
|
||||
allow {
|
||||
some route
|
||||
input.host = route_policies[route].source
|
||||
allowed_route(input.url, route_policies[route])
|
||||
token.payload.groups[_] = route_policies[route].allowed_groups[_]
|
||||
token.valid
|
||||
count(deny)==0
|
||||
|
@ -26,7 +26,7 @@ allow {
|
|||
# allow by impersonate email
|
||||
allow {
|
||||
some route
|
||||
input.host = route_policies[route].source
|
||||
allowed_route(input.url, route_policies[route])
|
||||
token.payload.impersonate_email = route_policies[route].allowed_users[_]
|
||||
token.valid
|
||||
count(deny)==0
|
||||
|
@ -35,7 +35,7 @@ allow {
|
|||
# allow by impersonate group
|
||||
allow {
|
||||
some route
|
||||
input.host = route_policies[route].source
|
||||
allowed_route(input.url, route_policies[route])
|
||||
token.payload.impersonate_groups[_] = route_policies[route].allowed_groups[_]
|
||||
token.valid
|
||||
count(deny)==0
|
||||
|
@ -44,9 +44,8 @@ allow {
|
|||
# allow by domain
|
||||
allow {
|
||||
some route
|
||||
input.host = route_policies[route].source
|
||||
some domain
|
||||
email_in_domain(token.payload.email, route_policies[route].allowed_domains[domain])
|
||||
allowed_route(input.url, route_policies[route])
|
||||
allowed_user_domain(token.payload.email)
|
||||
token.valid
|
||||
count(deny)==0
|
||||
}
|
||||
|
@ -54,14 +53,69 @@ allow {
|
|||
# allow by impersonate domain
|
||||
allow {
|
||||
some route
|
||||
input.host = route_policies[route].source
|
||||
some domain
|
||||
email_in_domain(token.payload.impersonate_email, route_policies[route].allowed_domains[domain])
|
||||
allowed_route(input.url, route_policies[route])
|
||||
allowed_user_domain(token.payload.impersonate_email)
|
||||
token.valid
|
||||
count(deny)==0
|
||||
}
|
||||
|
||||
email_in_domain(email, domain) {
|
||||
allowed_route(input_url, policy){
|
||||
input_url_obj := parse_url(input_url)
|
||||
allowed_route_source(input_url_obj, policy)
|
||||
allowed_route_prefix(input_url_obj, policy)
|
||||
allowed_route_path(input_url_obj, policy)
|
||||
allowed_route_regex(input_url_obj, policy)
|
||||
}
|
||||
|
||||
allowed_route_source(input_url_obj, policy) {
|
||||
object.get(policy, "source", "") == ""
|
||||
}
|
||||
allowed_route_source(input_url_obj, policy) {
|
||||
object.get(policy, "source", "") != ""
|
||||
source_url_obj := parse_url(policy.source)
|
||||
input_url_obj.host == source_url_obj.host
|
||||
startswith(input_url_obj.path, source_url_obj.path)
|
||||
}
|
||||
|
||||
allowed_route_prefix(input_url_obj, policy) {
|
||||
object.get(policy, "prefix", "") == ""
|
||||
}
|
||||
allowed_route_prefix(input_url_obj, policy) {
|
||||
object.get(policy, "prefix", "") != ""
|
||||
startswith(input_url_obj.path, policy.prefix)
|
||||
}
|
||||
|
||||
allowed_route_path(input_url_obj, policy) {
|
||||
object.get(policy, "path", "") == ""
|
||||
}
|
||||
allowed_route_path(input_url_obj, policy) {
|
||||
object.get(policy, "path", "") != ""
|
||||
policy.path == input_url_obj.path
|
||||
}
|
||||
|
||||
allowed_route_regex(input_url_obj, policy) {
|
||||
object.get(policy, "regex", "") == ""
|
||||
}
|
||||
allowed_route_regex(input_url_obj, policy) {
|
||||
object.get(policy, "regex", "") != ""
|
||||
re_match(policy.regex, input_url_obj.path)
|
||||
}
|
||||
|
||||
parse_url(str) = { "scheme": scheme, "host": host, "path": path } {
|
||||
[_, scheme, host, rawpath] = regex.find_all_string_submatch_n(
|
||||
`(?:(http[s]?)://)?([^/]+)([^?#]*)`,
|
||||
str, 1)[0]
|
||||
path = normalize_url_path(rawpath)
|
||||
}
|
||||
|
||||
normalize_url_path(str) = "/" {
|
||||
str == ""
|
||||
}
|
||||
normalize_url_path(str) = str {
|
||||
str != ""
|
||||
}
|
||||
|
||||
allowed_user_domain(email){
|
||||
x := split(email, "@")
|
||||
count(x) == 2
|
||||
x[1] == domain
|
||||
|
|
78
authorize/evaluator/opa/policy/authz_test.rego
Normal file
78
authorize/evaluator/opa/policy/authz_test.rego
Normal file
|
@ -0,0 +1,78 @@
|
|||
package pomerium.authz
|
||||
|
||||
jwt_header := {
|
||||
"typ": "JWT",
|
||||
"alg": "HS256"
|
||||
}
|
||||
signing_key := {
|
||||
"kty": "oct",
|
||||
"k": "OkFmqMK9U0dmPhMCW0VYy6D_raJKwEJsMdxqdnukThzko3D_XrsihwYE0pxrUSpm0JTrW2QpIz4rT1vdEvZw67WP4xrqjiwyd7PgpPTD5xvQBM7TIKiSW0X2R0pfq_OItszPQRtb7VirrSbGJiLNS-NJMMrYVKWWtUbVSTXEjL7VcFqML5PiSe7XDmyCZjpgEpfE5Q82zIeXM2sLrz6HW2A9IwGk7mWS0c57R_2JGyFO2tCA4zEIYhWvLE62Os2tZ6YrrwdB8n35jlPpgUE6poEvIU20lPLaocozXYMqAku-KJnloJlAzKg2Xa_0iSiSgSAumx44B3n7DQjg3jPhRg"
|
||||
}
|
||||
shared_key := base64url.decode(signing_key.k)
|
||||
|
||||
test_email_allowed {
|
||||
user := io.jwt.encode_sign(jwt_header, {
|
||||
"aud": ["example.com"],
|
||||
"email": "joe@example.com"
|
||||
}, signing_key)
|
||||
|
||||
allow with data.route_policies as [{
|
||||
"source": "example.com",
|
||||
"allowed_users": ["joe@example.com"]
|
||||
}] with data.signing_key as signing_key with data.shared_key as shared_key with input as {
|
||||
"url": "http://example.com",
|
||||
"host": "example.com",
|
||||
"user": user
|
||||
}
|
||||
}
|
||||
|
||||
test_email_denied {
|
||||
user := io.jwt.encode_sign(jwt_header, {
|
||||
"aud": ["example.com"],
|
||||
"email": "joe@example.com"
|
||||
}, signing_key)
|
||||
|
||||
not allow with data.route_policies as [{
|
||||
"source": "example.com",
|
||||
"allowed_users": ["bob@example.com"]
|
||||
}] with data.signing_key as signing_key with data.shared_key as shared_key with input as {
|
||||
"url": "http://example.com",
|
||||
"host": "example.com",
|
||||
"user": user
|
||||
}
|
||||
}
|
||||
|
||||
test_parse_url {
|
||||
url := parse_url("http://example.com/some/path?qs")
|
||||
url.scheme == "http"
|
||||
url.host == "example.com"
|
||||
url.path == "/some/path"
|
||||
}
|
||||
|
||||
test_allowed_route_source {
|
||||
allowed_route("http://example.com", {"source": "example.com"})
|
||||
allowed_route("http://example.com", {"source": "http://example.com"})
|
||||
allowed_route("http://example.com", {"source": "https://example.com"})
|
||||
not allowed_route("http://example.org", {"source": "example.com"})
|
||||
allowed_route("http://example.com/some/path", {"source": "https://example.com/some/path"})
|
||||
allowed_route("http://example.com/some/path", {"source": "https://example.com/some/path?qs"})
|
||||
not allowed_route("http://example.com/some/other/path", {"source": "https://example.com/some/path"})
|
||||
}
|
||||
|
||||
test_allowed_route_prefix {
|
||||
allowed_route("http://example.com", {"prefix": "/"})
|
||||
allowed_route("http://example.com/admin/somepath", {"prefix": "/admin"})
|
||||
not allowed_route("http://example.com", {"prefix": "/admin"})
|
||||
}
|
||||
|
||||
test_allowed_route_path {
|
||||
allowed_route("http://example.com", {"path": "/"})
|
||||
not allowed_route("http://example.com/admin/somepath", {"path": "/admin"})
|
||||
not allowed_route("http://example.com", {"path": "/admin"})
|
||||
}
|
||||
|
||||
test_allowed_route_regex {
|
||||
allowed_route("http://example.com", {"regex": ".*"})
|
||||
allowed_route("http://example.com/admin/somepath", {"regex": "/admin/.*"})
|
||||
not allowed_route("http://example.com", {"regex": "[xyz]"})
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue