Package: fastapi-opa
Open Policy Agent middleware for FastAPITable of contentsContributorsWhat does fastapi-opa doInstallationHow to get startedOpen Policy AgentAuthentication flowAPI key authenticationOIDC authenticationSAML authenticationCustom payload enrichmentGraphQL enrichmentContributorsThanks to all the contributors below. Furthermore thanks for raising issues.What does fastapi-opa doThe FastAPI extensionfastapi-opaallows to add login flows and integrates
Open Policy Agent to your app.The middleware redirects the request to the identity provider. After the
authentication it validates the token. Using the token, Open Policy Agent
decides if the response has success or failure status.Installationpoetryadd[--extras"graphql"][--extras"saml"]fastapi-opaHow to get started:bulb: checkout the wiki for an environment setup with Keycloak and Open Policy Agent:Getting Started with FastAPI app with Authentication and AuthorizationThe package combines authentication and authorization with FastAPI. You can
customize theOPAMiddlewaredepending on your authentication flow.Check out these examples for the most common flows:OIDC:fastapi_opa.example_oidc.pySAML:fastapi_opa.example_saml.pyOpen Policy AgentThe middleware sends the validated and authenticated user token to Open
Policy Agent. It adds the extra attributesrequest_methodandrequest_path.{"input":{"exp":1617466243,"iat":1617465943,"auth_time":1617465663,"jti":"9aacb638-70c6-4f0a-b0c8-dbc67f92e3d1","iss":"http://localhost:8080/auth/realms/example-realm","aud":"example-client","sub":"ccf78dc0-e1d6-4606-99d4-9009e74e3ab4","typ":"ID","azp":"david","session_state":"41640fe7-39d2-44bc-818c-a3360b36fb87","at_hash":"2IGw-B9f5910Sll1tnfQRg","acr":"0","email_verified":false,"hr":"true","preferred_username":"david","user":"david","subordinates":[],"request_method":"GET","request_path":["finance","salary","david"]}}In Open Policy Agent you can create policies using user roles,
routes, request methods etc.An example policy (fromthe official Open Policy Agent
docs)
for this setup could look like this:package httpapi.authz

# bob is alice's manager, and betty is charlie's.
subordinates = {"alice": [], "charlie": [], "bob": ["alice"], "betty": ["charlie"]}

# HTTP API request
import input

default allow = false

# Allow users to get their own salaries.
allow {
  some username
  input.request_method == "GET"
  input.request_path = ["finance", "salary", username]
  input.user == username
}

# Allow managers to get their subordinates' salaries.
allow {
  some username
  input.request_method == "GET"
  input.request_path = ["finance", "salary", username]
  subordinates[input.user][_] == username
}Authentication flowUse the provided interface to set up your desired authentication flow. Then
insert it intoOPAMiddleware(fastapi_opa.auth.auth_interface.AuthInterface).
Consider submitting a pull request with new flows.You can also use these ready-to-go implementations:API key authenticationIn the API key authentication a request header needs to match a given value.# Configure API keysapi_key_config=APIKeyConfig(header_key="test",api_key="1234")api_key_auth=APIKeyAuthentication(api_key_config)In the example the headerheader["test"] = "1234"authenticates the request.
For Open Policy Agent, set user toAPIKeyand the variableclientto the
client address.OIDC authenticationThe example inHow to get startedprovides an example for
the implementation of the OIDC Authentication.SAML authenticationFor the saml implementation create your certs usingopenssl req -new -x509 -days 3652 -nodes -out sp.crt -keyout sp.keyand
add the keys to the sp section of yoursettings.json. Checkout the test
settings to get an idea (tests/test_data/saml/*.json).
Provide the path to your ownsettings.jsonandadvanced_settings.jsonin theSAMLAuthConfiglike in the example below (don't use the test data in
production).fromfastapi_opaimportOPAConfigfromfastapi_opa.auth.auth_samlimportSAMLAuthenticationfromfastapi_opa.auth.auth_samlimportSAMLConfigopa_host="http://localhost:8181"saml_config=SAMLConfig(settings_directory="./tests/test_data/saml")saml_auth=SAMLAuthentication(saml_config)opa_config=OPAConfig(authentication=saml_auth,opa_host=opa_host,accepted_methods=["id_token","access_token"])Upload the certificate to your identity provider. Using Keycloak as an
identity provider you need to configureencrypt assertion,client signature required,force POST bindingson creating the client.
Also configure:Client Scopes->role_list (saml)->Mappers tab->role list->Single Role AttributeCustom payload enrichmentUse the interfacefastapi_opa.opa.opa_config.Injectableto add
more information to the payload sent to Open Policy Agent.Configure the injectables in theOPAConfig:classFancyInjectable(Injectable):asyncdefextract(self,request:Request)->List:return["some","custom","stuff"]fancy_inj=FancyInjectable("fancy_key",skip_endpoints=["/health","/api/[^/]*/test])opa_config=OPAConfig(authentication=oidc_auth,opa_host=opa_host,injectables=[fancy_inj])Useskip_endpointsto choose which endpoints the injectable shouldn't affect.
To define an endpoint, specify an exact string or a regular expression.GraphQL enrichmentFor GraphQL you can use the ready to go injectable:fromfastapi_opa.opa.enrichment.graphql_enrichmentimportGraphQLInjectable`graphql=GraphQLInjectable("gql_injectable")opa_config=OPAConfig(authentication=oidc_auth,opa_host=opa_host,injectables=[graphql])