Code Monkey home page Code Monkey logo

fastapi-opa's Introduction

Open Policy Agent Middleware for FastAPI

Table of Contents

Made with contributors-img.

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.

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

๐Ÿ’ก 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
}

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.

The example in How to get started provides an example for the implementation of the OIDC 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)

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

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

opa_config = OPAConfig(
    authentication=oidc_auth, opa_host=opa_host, injectables=[fancy_inj]
)

For GraphQL there is a ready to use injectable in fastapi_opa.opa.enrichment.graphql_enrichment.GraphQLInjectable

fastapi-opa's People

Contributors

morestanna avatar tracywr avatar dependabot[bot] avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.