authorize_opa

command
v0.0.0-...-14b8d0e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 20, 2020 License: Apache-2.0 Imports: 12 Imported by: 0

README

OAuth2 Scope evaluation with OPA Policy

The current status of this plugin is proof-of-concept.

This plugin allows the Tyk Gateway to evaluate OAuth2 Scopes to determine whether the user (resource owner) has provided consent to perform an action.

It uses Open Policy Agent (OPA) as the underlying policy enforcement mechanism. OPA was chosen as the policy agent, because it is Open Source, and facilitates the concepts of Policies as Code.

The plugin assumes that the request has already been authenticated.

Configuration

Caveat: I am not a REGO or OPA expert - so there are probably much better ways, of achieving the same thing. Please familiarise yourself with the OPA docs to ensure that the policy works for your use-case.

The runtime configuration of OPA is configured in the Tyk API Definition object, db, policy & module_name to load. Just insert these as fields in the config_data json object of the API Definition with the key opa.

"config_data": {
    "opa": {
        "db": {
            "scopes": [
                {
                    "operations": [
                        "GET"
                    ],
                    "resources": [
                        "/todos/todos"
                    ],
                    "scope": "todos:read"
                }
            ]
        },
        "module_name": "todos",
        "policy": "cGFja2FnZSB0b2RvcwoKaW1wb3J0IGRhdGEuc2NvcGVzCgpkZWZhdWx0IGFsbG93ID0gZmFsc2UKCiMgYWRtaW4gc2NvcGUgYmUgYWxsb3dlZCBmdWxsIGFjY2VzcwphbGxvdyB7CglzY29wZSA6PSBpbnB1dC5zY29wZXNbX10KCXNjb3BlID09ICJhZG1pbiIKfQoKYWxsb3cgewoJcmVxdWVzdGVkU2NvcGUgOj0gaW5wdXQuc2NvcGVzW19dCglzY29wZSA6PSBzY29wZXNbX10KCQkKCXJlcXVlc3RlZFNjb3BlID0gc2NvcGUuc2NvcGUKCWlucHV0LnBhdGggPSBzY29wZS5yZXNvdXJjZXNbX10KCWlucHV0Lm1ldGhvZCA9IHNjb3BlLm9wZXJhdGlvbnNbX10KfQ=="
    }
}

You will see in the above example, the policy has been base64 encoded. This is because the policy is actually written in the rego language. Decoding the policy, you will see it looks like this:

echo -n 'cGFja2FnZSB0b2RvcwoKaW1wb3J0IGRhdGEuc2NvcGVzCgpkZWZhdWx0IGFsbG93ID0gZmFsc2UKCiMgYWRtaW4gc2NvcGUgYmUgYWxsb3dlZCBmdWxsIGFjY2VzcwphbGxvdyB7CglzY29wZSA6PSBpbnB1dC5zY29wZXNbX10KCXNjb3BlID09ICJhZG1pbiIKfQoKYWxsb3cgewoJcmVxdWVzdGVkU2NvcGUgOj0gaW5wdXQuc2NvcGVzW19dCglzY29wZSA6PSBzY29wZXNbX10KCQkKCXJlcXVlc3RlZFNjb3BlID0gc2NvcGUuc2NvcGUKCWlucHV0LnBhdGggPSBzY29wZS5yZXNvdXJjZXNbX10KCWlucHV0Lm1ldGhvZCA9IHNjb3BlLm9wZXJhdGlvbnNbX10KfQ==' | base64 --decode
package todos

import data.scopes

default allow = false

# admin scope be allowed full access
allow {
	scope := input.scopes[_]
	scope == "admin"
}

allow {
	requestedScope := input.scopes[_]
	scope := scopes[_]

	requestedScope = scope.scope
	input.path = scope.resources[_]
	input.method = scope.operations[_]
}

Usage

OAuth2: Because an access_token may be opaque, we should check for the scopes from an introspection response. JWT: Can contain scopes claims of the token. Tyk Bearer Token: Scopes may be present in the session metadata.

Because the scopes could be anywhere - it is assumed that a plugin, or middleware has performed some pre-processing and injected the scope into an internal header X-Tyk-Plugin-OAuth2Introspect-Scope.

Maybe TODO / Current Known Limitations

  • Make the scope location generic / configurable so that it can extract from specified location.
  • Standardise the required content field names of the opa object in the apidefinition config data.
  • Currently a new instance of OPA is instantiated for every request. This needs to be optimised.

Documentation

The Go Gopher

There is no documentation for this package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL