Spring Boot library for enforcing authorization on Spring Data JPA and MongoDB by filtering data using the Open Policy Agent (OPA) partial evaluation feature.
APACHE-2.0 License
The blog posts below explain enough of the What and Why!
opa-datafilter-jpa-spring-boot-starter and opa-datafilter-mongo-spring-boot-starter are Spring Boot libraries which can be used together with Spring Data JPA and Spring Data MongoDB, respectively, to enforce authorization on data by filtering using OPA Partial Evaluation feature. When a user wants to access a protected collection of resources, the libraries create a partial request object which contains about the user and the operation a user wants to perform. The partial request object is sent to the OPA compile API. OPA evaluates the partial request and returns a new and simplified policy that can be evaluated more efficiently than the original policy. These libraries convert the new policy, the OPA compile API response, into SQL or MongoDB queries. A filtered collection of data is returned to the user which a user is allowed to see.
findAll
methodsThe libraries override Spring Data methods:
See each individual folder for installation and usage instructions.
To verify how the SQL or MongoDB query looks like, use the opa-datafilter-datafilter-query-service or the the docker image, opa-query-service. The service provides an API for translating OPA partial request object into a SQL or MongoDB query.
Properties | Type | Default Value | Description | Required |
---|---|---|---|---|
opa.authorization.url | String | http://localhost:8181/v1/compile | The OPA compile API endpoint. | Yes |
opa.authorization.data-filter-enabled | Boolean | true | Enable OPA data filter authorization | No |
opa.partial-request.log-partial-request | Boolean | false | Log the partial request json which was sent to OPA on std out for debugging | No |
opa.partial-request.query | String | The query to partially evaluate and compile | Yes | |
opa.partial-request.unknowns | Set | The terms to treat as unknown during partial evaluation | Yes | |
opa.partial-request.user-attribute-to-http-header-map | Map<String, String> | The mapping of user attribute to Http Header. These mappings will be added as subject attributesin the input of the partial request. The key will be set as the attribute name and the value of the Http header will be set as the value of the key. | No |
See example Spring Boot microservice applications that use these libraries:
When the findAll
method is invoked from OpaDataFilterRepository
interface, a partial request object is sent
to the OPA compile API endpoint. The default partial request is the following:
{
"query": "data.petclinic.authz.allow = true",
"input": {
"path": ["pets"],
"method": "GET",
"subject": {
"user": "alice",
"jwt": "<jwt token>"
}
},
"unknowns": ["data.pets"]
}
where:
query
- is the value of opa.partial-request.query
from the configuration property.input
- by default http servlet path and method are added as path
and method
respectively. The subject
(the current user) by default has user
propertyjwt
property from the Authorization Bearer header if it exists.unknowns
- the value of opa.partial-request.unknowns
from the configuration property.It is possible to add attributes to the subject
property of the default partial request. This can be done by mapping the attribute to the Http header using
a configuration opa.partial-request.user-attribute-to-http-header-map
. For example:
opa:
partial-request:
log-partial-request: true
user-attribute-to-http-header-map:
organization: X-ORG-HEADER
The organization
is key of the attribute and the value of the X-ORG-HEADER
http header is the value of the key. The partial request will
look like the following:
{
"query": "data.petclinic.authz.allow = true",
"input": {
"path": ["pets"],
"method": "GET",
"subject": {
"user": "alice",
"attributes": {
"organization": "SOMA"
}
}
},
"unknowns": ["data.pets"]
}