...
Code Block | ||||
---|---|---|---|---|
| ||||
package main import input.attributes.request.http as http_request default allow = false policy_realms := { "rappopaprovider": "opa" } name := trim_prefix(replace(http_request.path, "-", ""), "/") realm := policy_realms[name] router[policy] = data.policies[name][policy].deny deny[msg] { policy := router[_] msg := policy[_] } allow { count(deny) == 0 } |
This main policy will use the request path to determine which policy to apply. (We remove the forward slash and and "-" characters)
...
Code Block | ||||
---|---|---|---|---|
| ||||
package policies.rappopaprovider.policy import input.attributes.request.http as http_request import future.keywords.in realm_name := "opa" realm_url := sprintf("http://keycloak:8080/auth/realms/%v", [realm_name]) certs_url := sprintf("%v/protocol/openid-connect/certs", [realm_url]) jwks := jwks_request(certs_url).body filtered_jwks := [ key | some key in jwks.keys key.use == "sig" ] token_cert := json.marshal({"keys": filtered_jwks}) token = { "isValid": isValid, "header": header, "payload": payload } { print("realm is:", realm_name) print("realm_url:", realm_url) print("certs_url:", certs_url) [_, encoded] := split(http_request.headers.authorization, " ") [isValid, header, payload] := io.jwt.decode_verify(encoded, { "cert": token_cert, "aud": "account", "iss": realm_url}) } deny[msg] { not is_token_valid msg = "denied by rappopaprovider.policy: not a valid token" } is_token_valid { token.isValid now := time.now_ns() / 1000000000 token.payload.iat <= now now < token.payload.exp token.payload.clientRole = "[opa-client-role]" } jwks_request(url) = http.send({ "url": url, "method": "GET", "force_cache": true, "force_json_decode": true, "force_cache_duration_seconds": 3600 # Cache response for an hour }) |
...