opa
Authorizes requests with Open Policy Agent.
opaPriority 2001What it does
opa asks a policy service of your own whether each request on the route may go on to its backend. The gateway puts the question to the service at Host and reads the decision at Policy. The rules live in the policy, not on the gateway.
A request the policy allows reaches the backend. One it refuses is answered 403, with the reason the policy gave. The policy decides by the consumer only when Send the consumer is on and a plugin before it, key-auth for example, has named the consumer.
When to use it
- Authorization rules your security team writes once as policy and keeps in one service, which every API behind the gateway asks.
- A decision that depends on who calls: key-auth names the mobile app or the partner portal, and the policy decides what each of them may reach.
- Rules that read the route or its service, sent along with Send the route and Send the service.
- A backend that needs a value the policy decided, set on the request under Headers set from the decision.
Not for a decision your own authorization service makes from the request's headers — see forward-auth (Delegates authentication to an external service) or a fixed list of consumers a route lets in — see consumer-restriction (Allows or denies requests by consumer, group, route or service).
Set it up
Ask a policy server whether each request may pass, with the consumer in the question
With the consumer in the question, the signed-in consumer travels to the policy server whole, the credential the gateway stores for them included. Reach the server over HTTPS inside your own network and guard its decision log as you guard the credentials themselves.
Under Basics set Host to https://opa.internal:8181 and set Policy to gateway/authz. Under Behavior turn on Send the consumer and set Timeout to 1500 milliseconds.
{
"host": "https://opa.internal:8181",
"policy": "gateway/authz",
"with_consumer": true,
"timeout": 1500
}
Things to know
- Send the consumer — In the example the policy allows only a consumer it knows. A request with that consumer's key is answered
200, and one on a route that names no consumer is answered403with the policy's reason. - Host — There is no degradation switch: a service that cannot be reached refuses every request with 403, and one that answers no decision with 503.
- Host — An address without its scheme,
http://orhttps://, is refused when you save. - Policy — An empty Policy is refused when you save.
- Send the route — On, the route travels to the decision service without its upstream, the configuration of its other plugins with it, their credentials included.
- Send the service — On, the service the route is bound to travels to the decision service without its upstream, the configuration of its plugins with it, their credentials included.
- Send the consumer — On, the signed-in consumer travels whole to the decision service, with the credential the engine stored for them in clear.
- AdviceTurn on Send the consumer, Send the route or Send the service only when the policy decides by it. Reach the policy service over HTTPS inside your own network, and guard its decision log as you guard credentials.
- On a consumer or a consumer group it runs only after the consumer has been identified by a credential; it does not identify the consumer itself.
Settings
The fields as the console shows them, section by section.
Basics
hoststringRequiredThe address of the decision service, scheme included. The decision below is asked for under /v1/data on it.
pattern
^https?://https://opa.internal:8181policystringRequiredThe path of the decision inside the service, written with slashes: the package g8.gateway is asked for as g8/gateway.
Behavior
with_routebooleandefault falsewith_servicebooleandefault falseSends the route's service to the decision service. A route bound to none sends nothing.
with_consumerbooleandefault falsesend_headers_upstreamarray of stringsAfter an allow each name here is read from the decision's answer and set on the request to the upstream, and removed when the answer carries none.
timeoutintegerdefault 3000ssl_verifybooleandefault trueAdvanced
keepalivebooleandefault truekeepalive_poolintegerdefault 5keepalive_timeoutintegerdefault 60000