Skip to main content

Fastapi OPA middleware incl. auth flow.

Project description

Open Policy Agent Middleware for FastAPI

Table of Contents

Contributors

Thanks to all our contributors! There is no specific order and hopefully nobody was left out.

What does fastapi-opa do

fastapi-opa is an extension to FastAPI that allows you to add a login flow to your application within minutes using open policy agent and your favourite identity provider.

Flow Diagram

When a user tries to get a response from an endpoint he/she will be redirected to the identity provider for authorization. After the authentication the app validates the token provided. Once it was validated the user information is used to get an OPA decision whether the user is allowed to get any information from the endpoint.

Installation

poetry add [--extras "graphql"] [--extras "saml"] fastapi-opa 

How to get started

:bulb: Checkout the wiki for a complete environment setup with Keycloak and Open Policy Agent:
Getting Started with FastAPI app with Authentication and Authorization

The package provides a very easy way to integrate authentication and authorization. We can decide what authentication flow we inject into the OPAMiddleware to be able choosing between different flows.

There are

  • one example for oidc : fastapi_opa.example_oidc.py,
  • one example for saml: fastapi_opa.example_saml.py

Open Policy Agent

The (validated/authenticated) user token is sent to the Open Policy Agent with the additional attributes request_method and request_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 now easily create policies using user roles, routes, or request methods etc.

An example policy (from the official OPA docs) for this setup could be like:

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 Flow

There is an interface provided to easily implement the desired authentication flow and inject it into OPAMiddleware (fastapi_opa.auth.auth_interface.AuthInterface), or you can open a pull request if you would like to contribute to the package.

Also there are implementations ready to use.

OIDC Authentication

The example in How to get started provides an example for the implementation of the OIDC Authentication.

SAML Authentication

For the saml implementation create your certs using openssl req -new -x509 -days 3652 -nodes -out sp.crt -keyout sp.key and add the keys to the sp section of your settings.json. Checkout the test settings to get an idea (tests/test_data/saml/*.json). The path to your own settings.json and advanced_settings.json has to be provided in the SAMLAuthConfig like in the example below (do not use the test data in production).

from fastapi_opa import OPAConfig
from fastapi_opa.auth.auth_saml import SAMLAuthentication
from fastapi_opa.auth.auth_saml import SAMLConfig

opa_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"])

The cert has to be uploaded to your identity provider. Using Keycloak as an idp you need to configure encrypt assertion, client signature required, force POST bindings on creating the client. Also configure: Client Scopes -> role_list (saml) -> Mappers tab -> role list -> Single Role Attribute

Custom Payload Enrichment

In fastapi_opa.opa.opa_config.Injectable an interface is provided to add more information to the payload sent to OPA.

The injectables can be added to the OPAConfig. Let's look at an example:

class FancyInjectable(Injectable):
    async def extract(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]
)

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.

Graphql Enrichment

For GraphQL there is a ready to use injectable:

from fastapi_opa.opa.enrichment.graphql_enrichment import GraphQLInjectable`

graphql = GraphQLInjectable("gql_injectable")
opa_config = OPAConfig(authentication=oidc_auth, opa_host=opa_host, injectables=[graphql])

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi-opa-1.3.4.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_opa-1.3.4-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file fastapi-opa-1.3.4.tar.gz.

File metadata

  • Download URL: fastapi-opa-1.3.4.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.10.0 Linux/5.10.60.1-microsoft-standard-WSL2

File hashes

Hashes for fastapi-opa-1.3.4.tar.gz
Algorithm Hash digest
SHA256 bff99a9dbb08638374edd72c4a9ed2ebf23f5382d9b97331c78d3981e56acb8d
MD5 32310208415991ef58a9a613f5e00d25
BLAKE2b-256 378e79872f21eec03a1b3c259528be9ea58500899fdce68aeb6cbb2a4edbc37c

See more details on using hashes here.

File details

Details for the file fastapi_opa-1.3.4-py3-none-any.whl.

File metadata

  • Download URL: fastapi_opa-1.3.4-py3-none-any.whl
  • Upload date:
  • Size: 25.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.10.0 Linux/5.10.60.1-microsoft-standard-WSL2

File hashes

Hashes for fastapi_opa-1.3.4-py3-none-any.whl
Algorithm Hash digest
SHA256 c9bc19bee0173f23780017c2d232b2f81cd632fdc6e1d9d79e822aa222cff8d0
MD5 489991a13f47a08befac57e8356c4532
BLAKE2b-256 af7c20a5a8f13adc2ac51dc7f375cd0ee184772081689acf336ba7c4bf7172f2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page