Skip to content

OPA Token Enrichment

Matthias Osswald edited this page May 26, 2022 · 2 revisions

OPA Token Enrichment

Using an injectable the token sent to OPA can be enriched with additional data. This can be helpful if custom data on a request should be used for the policy decision.

General Usage

A custom injectable must inherit implement fastapi_opa.opa.opa_config.Injectable. The extract method is called within the middleware incl. the request. The output is then appended to the dictionary (data needs to be jsonifyable) using the key provided on instantiating the object.

class CustomInjectable(Injectable):
    async def extract(self, request: Request) -> List:
        return ["whatever", "custom", "data", {"you": "like"}]

The injectables can be added to the OPAConfig object.

custom_injectable = CustomInjectable("cust_inj_key")

opa_config = OPAConfig(
    authentication=auth, opa_host=opa_host, injectables=[custom_injectable])

Skip Endpoints

With skip_endpoints, you can define some endpoints where the injectable will not be applied. The endpoints can be defined either directly or through some regex.

custom_injectable = CustomInjectable("cust_inj_key", skip_endpoints=["/health", "/api/[^/]*/test])

GraphQL Enrichment

There is a GraphQL injectable prepared for you already. If you like the implementation it can be used like this:

gql_injectable = GraphQLInjectable("gql_info")

opa_config = OPAConfig(
    authentication=auth, opa_host=opa_host, injectables=[gql_injectable])

For a graphql payload querying a students like this:

"operationName": "getStudents",
"variables": {"subject": "Physics", "enrolled": True},
"query": """query getStudents(
    $subject: String,
    $enrolled: Boolean){
    students(
        subject: $subject,
        enrolled: $enrolled){
            Student {
                name
                subject
                enrolled
            }
        }
    }
"""

...you could expect an additional mapping with the below information.

"gql_info": [
    {
        "name": "getStudents",
        "operation": "query",
        "selection_set": [
            ["students", ["Student", ["name", "subject", "enrolled"]]]
        ],
        "variables": {"enrolled": "Boolean", "subject": "String"},
    }
],
Clone this wiki locally