Skip to main content

Gate: Open Policy Agent Evaluator

info

This plugin supports all intercept modes (request, response, request_response)

This plugin embeds an Open Policy Agent engine into Gate and restricts access to specific HTTP resources based on OPA policy evaluations. To evaluate an OPA policy you need two pieces of input:

  • The Rego policy
  • Input data, passed to the Rego policy as the special input object

When it comes to policy distribution, the plugin currently supports two different methods to distribute policies.

The first is to inline policies, this approach works best when you have a limited number of policies and performance is really important.

UserLoad balancerGate+OPADestination endpointYour systemHTTPrequestHTTPrequest?Embedded OPA policy

The second approach is to use a remote bundle. The remote bundle can be pulled from any remote host, including the SlashID distribution hub.

UserLoad balancerGate+OPADestination endpointBundle serviceYour systemHTTPrequestHTTPrequest?BundlerequestBundleRemote OPA bundle

Policy input object example

As mentioned, the input option is the second ingredient necessary for OPA. The plugin passes the follow input format to OPA.

info

Note that this format is compatible with OPA-Envoy, so you can reuse your existing OPA policies with Gate.

The following is an example of input object Gate makes available to Rego policies during evaluation in its current Version 1 format:

{
"version": {
"gate": "v1.1"
},
"request": {
"http": {
"headers": {
"Accept": [
"application/json, text/plain, */*"
],
"Accept-Encoding": [
"gzip, compress, deflate, br"
],
"Authorization": [
"Bearer eyJhb..."
],
"Cookie": [
"foo=bar"
]
"User-Agent": [
"axios/1.3.4"
]
},
"cookies": {
"foo": "bar"
}
"host": "example.com",
"method": "GET",
"path": "/some/path",
"protocol": "HTTP/1.1",
"query": "option=value",
"scheme": "https",
"url": "https://example.com/some/path?option=value"
},
"parsed_path": [
"some",
"path"
],
"parsed_query": {
"option": [
"value"
]
},
"parsed_token": {
"header": {
"alg": "RS256",
"kid": "pYsNGA"
},
"payload": {
...
},
"signature": "JvVt..."
},
"time": "2023-04-09T18:38:41.117405838Z",
"token": "eyJh..."
}
}

Note that if the plugin is configured to execute on responses as well then the input object contains both the request and response objects. The request is the same as the object shown above. The whole input object looks as follows:

{
"version": {
"gate": "v1.1"
},
"request": {
"http": {
...
}
},
"response": {
"http": {
"contentType": "application/json"
"status": 200
"body": "{}"
"headers": {
"Accept": [
"application/json, text/plain, */*"
],
"Accept-Encoding": [
"gzip, compress, deflate, br"
],
"Authorization": [
"Bearer eyJhb..."
],
"User-Agent": [
"axios/1.3.4"
]
},
},
"time": "2023-04-09T18:38:46.117405838Z",
"parsed_path": [
"some",
"path"
],
"parsed_query": {
"option": [
"value"
]
},

}
}

The output of an evaluation is expected to be a boolean to be found at the location specified in the policy_decision_path plugin parameter.

Configuring Gate

GATE_PLUGINS_<PLUGIN NUMBER>_TYPE=opa
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_HEADER_WITH_TOKEN=<Header with token>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_COOKIE_WITH_TOKEN=<Cookie with token>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_SLASHID_BASE_URL=<SlashID base URL>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_POLICY=<Embedded Rego policy>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_POLICY_BUNDLE_URL=<URL of a remote OPA bundle>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_POLICY_DECISION_PATH=<Location of the policy evaluation decision>
GATE_PLUGINS_<PLUGIN NUMBER>_PARAMETERS_MONITORING_MODE=<boolean - Run the plugin in monitoring mode or enforcement mode. Default is enforcementn>

In the Environment variables configuration, <PLUGIN NUMBER> defined plugin execution order.

where:

  • <Header with token> is the request header containing the token, if any. This option and cookie_with_token are mutually exclusive.
  • <Cookie with token> is the request cookie containing the token, if any. This option and header_with_token are mutually exclusive.
  • <Embedded Rego policy> a Rego policy you can inline directly in Gate's configuration to accept or deny incoming requests. This option is mutually exclusive with policy_bundle_url.
  • <URL of a remote OPA bundle> location of a policy and data OPA bundle built with opa build Gate will fetch periodically to gather updated policies and data. This option is mutually exclusive with the embedded policy option.
  • <Location of the policy evaluation decision> a Rego policy decision path to a boolean value: if true the request is granted, otherwise it's rejected with a 403 status.
  • <Monitoring mode> a boolean indicating whether to run the plugin in monitoring mode or enforcement mode. If true the plugin runs in monitoring mode, by default it is false (enforcement mode).

If neither <Header with token> nor <Cookie with token> are set, the plugin attempts to get a bearer token from the Authorization header, and strips the Bearer prefix from it.

Disabling plugin for specific URLs

You can enable or disable this plugin for specific URLs by using the enabled option in the URLs configuration.

GATE_PLUGINS_<plugin number>_TYPE=<plugin type>
GATE_PLUGINS_<plugin number>_ID=<plugin ID>
GATE_PLUGINS_<plugin number>_ENABLED=false
GATE_PLUGINS_<plugin number>_PARAMETERS_<plugin_parameter>=<plugin parameter value>

GATE_URLS_0_PATTERN=svc-another-example.com/
GATE_URLS_0_TARGET=https://another-example:8080
GATE_URLS_0_PLUGINS__<PLUGIN ID>__ENABLED=true
GATE_URLS_0_PLUGINS__<PLUGIN ID>__PARAMETERS_<plugin_parameter>=<plugin parameter value>

Plugin ID is case-insensitive. Because of that, <PLUGIN ID> can be the uppercase version of the plugin ID.

Please note that in URL configuration, the plugin ID is separated by two underscores (__).