API-key based security utilities for FastAPI, focused on simplicity of use

Overview

FastAPI simple security

API key based security package for FastAPI, focused on simplicity of use:

  • Full functionality out of the box, no configuration required
  • API key security with local sqlite backend, working with both header and query parameters
  • Default 15 days deprecation for generated API keys
  • Key creation, revocation, renewing, and usage logs handled through administrator endpoints
  • No dependencies, only requiring FastAPI and the python standard library

Installation

pip install fastapi_simple_security

Usage

Creating an application

from fastapi_simple_security import api_key_router, api_key_security
from fastapi import Depends, FastAPI

app = FastAPI()

app.include_router(api_key_router, prefix="/auth", tags=["_auth"])

@app.get("/secure", dependencies=[Depends(api_key_security)])
async def secure_endpoint():
    return {"message": "This is a secure endpoint"} 

Resulting app is:

app

API key creation through docs

Start your API and check the logs for the automatically generated secret key if you did not provide one through environment variables.

secret

Go to /docs on your API and inform this secret key in the Authorize/Secret header box. All the administrator endpoints only support header security to make sure the secret key is not inadvertently shared when sharing an URL.

secret_header

Then, you can use /auth/new to generate a new API key.

api key

And finally, you can use this API key to access the secure endpoint.

secure endpoint

API key creation in python

You can of course automate API key acquisition through python with requests and directly querying the endpoints.

If you do so, you can hide the endpoints from your API documentation with the environment variable FASTAPI_SIMPLE_SECURITY_HIDE_DOCS.

Configuration

Environment variables:

  • FASTAPI_SIMPLE_SECURITY_SECRET: Secret administrator key
    • Generated automatically on server startup if not provided
    • Allows generation of new API keys, revoking of existing ones, and API key usage view
    • It being compromised compromises the security of the API
  • FASTAPI_SIMPLE_SECURITY_HIDE_DOCS: Whether or not to hide the API key related endpoints from the documentation
  • FASTAPI_SIMPLE_SECURITY_DB_LOCATION: Location of the local sqlite database file
    • /app/sqlite.db by default
    • When running the app inside Docker, use a bind mount for persistence.
  • FAST_API_SIMPLE_SECURITY_AUTOMATIC_EXPIRATION: Duration, in days, until an API key is deemed expired
    • 15 days by default

Contributing

Running the dev environment

The attached docker image runs a test app on localhost:8080 with secret key TEST_SECRET. Run it with:

git clone https://github.com/mrtolkien/fastapi_simple_security.git . && docker-compose build && docker-compose up

Needed contributions

  • Unit tests
  • More options with sensible defaults
  • Logging per API key?
  • More back-end options for API key storage?
Comments
  • Error while runing

    Error while runing

    I was trying to run the sample code in the Readme. I got an error

    Traceback (most recent call last):
      File "pdfkitv2.py", line 8, in <module>
        from fastapi_simple_security import api_key_router, api_key_security
      File "D:\enviorments\pdfkit\lib\site-packages\fastapi_simple_security\__init__.py", line 1, in <module>
        from fastapi_simple_security.endpoints import api_key_router
      File "D:\enviorments\pdfkit\lib\site-packages\fastapi_simple_security\endpoints.py", line 7, in <module>
        from fastapi_simple_security._security_secret import secret_based_security
      File "<fstring>", line 1
        (SECRET=)
    

    I think there is an error in the file _security_secret.py Line 18.

    opened by devildani 4
  • Loosen fastapi dependency requirements

    Loosen fastapi dependency requirements

    pip install -r requirements.txt fails to resolve dependencies, because fastapi_simple_security is trying to force an older version of fastapi.

    I Momentarily solved it by manually installing an older fastapi version in my application, but I see no reason why this should be the way to go (new versions don't introduce breaking changes).

    Thanks!

    opened by zetoichi 3
  • sqllite unable to open database file

    sqllite unable to open database file

    Also reported in #1 here

    Running the script like described in the readme results in a

     File "/home/kai/PycharmProjects/fdm-api/app/main.py", line 5, in <module>
        from fastapi_simple_security import api_key_router, api_key_security
      File "/home/kai/PycharmProjects/fdm-api/venv/lib/python3.9/site-packages/fastapi_simple_security/__init__.py", line 1, in <module>
        from fastapi_simple_security.endpoints import api_key_router
      File "/home/kai/PycharmProjects/fdm-api/venv/lib/python3.9/site-packages/fastapi_simple_security/endpoints.py", line 8, in <module>
        from fastapi_simple_security._sqlite_access import sqlite_access
      File "/home/kai/PycharmProjects/fdm-api/venv/lib/python3.9/site-packages/fastapi_simple_security/_sqlite_access.py", line 218, in <module>
        sqlite_access = SQLiteAccess()
      File "/home/kai/PycharmProjects/fdm-api/venv/lib/python3.9/site-packages/fastapi_simple_security/_sqlite_access.py", line 21, in __init__
        self.init_db()
      File "/home/kai/PycharmProjects/fdm-api/venv/lib/python3.9/site-packages/fastapi_simple_security/_sqlite_access.py", line 24, in init_db
        with sqlite3.connect(self.db_location) as connection:
    sqlite3.OperationalError: unable to open database file
    

    Tried with Python 3.6 as well as 3.9

    opened by Herrner 2
  • Access api key from function

    Access api key from function

    Thank you for this great library. I have a question. Is there a way to access the API key that was used to request a secure endpoint when the dependency is used globally? For example:

    app.include_router(myrouter, prefix='/myrouter', dependencies=[Depends(api_key_security)])
    
    @myrouter.get('/secured-endpoint/')
    async def secured_endpoint():
        return {'key': 'api-key'}
    

    Does the request state contain the API key or it isn't passed anywhere? If the key isn't available in any context, we will have to use the dependency in each function like this:

    from fastapi.security.api_key import APIKey
    
    
    @app.get('/secured-endpoint/')
    async def secured_endpoint(api_key: APIKey = Depends(api_key_security)):
        return {'key': api_key}
    

    Please let me know if there's a possibility to use the dependency globally on a router and still get the API key value in all sub-routes.

    opened by rehmatworks 2
  • Update dependency coverage to v7

    Update dependency coverage to v7

    Mend Renovate

    This PR contains the following updates:

    | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | coverage | ^6.5.0 -> ^7.0.0 | age | adoption | passing | confidence |


    Release Notes

    nedbat/coveragepy

    v7.0.1

    Compare Source

    • When checking if a file mapping resolved to a file that exists, we weren't considering files in .whl files. This is now fixed, closing issue 1511_.

    • File pattern rules were too strict, forbidding plus signs and curly braces in directory and file names. This is now fixed, closing issue 1513_.

    • Unusual Unicode or control characters in source files could prevent reporting. This is now fixed, closing issue 1512_.

    • The PyPy wheel now installs on PyPy 3.7, 3.8, and 3.9, closing issue 1510_.

    .. _issue 1510:https://github.com/nedbat/coveragepy/issues/15100 .. _issue 1511https://github.com/nedbat/coveragepy/issues/151111 .. _issue 151https://github.com/nedbat/coveragepy/issues/1512512 .. _issue 15https://github.com/nedbat/coveragepy/issues/15131513

    .. _changes_7-0-0:

    v7.0.0

    Compare Source

    Nothing new beyond 7.0.0b1.

    .. _changes_7-0-0b1:


    Configuration

    📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update abatilo/actions-poetry action to v2.2.0

    Update abatilo/actions-poetry action to v2.2.0

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | abatilo/actions-poetry | action | minor | v2.1.6 -> v2.2.0 |


    Release Notes

    abatilo/actions-poetry

    v2.2.0

    Compare Source

    Features

    Configuration

    📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Update actions/setup-python action to v4

    Update actions/setup-python action to v4

    Mend Renovate

    This PR contains the following updates:

    | Package | Type | Update | Change | |---|---|---|---| | actions/setup-python | action | major | v2 -> v4 |


    Release Notes

    actions/setup-python

    v4

    Compare Source

    v3

    Compare Source


    Configuration

    📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

    🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

    Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

    🔕 Ignore: Close this PR and you won't be reminded about this update again.


    • [ ] If you want to rebase/retry this PR, check this box

    This PR has been generated by Mend Renovate. View repository job log here.

    opened by renovate[bot] 1
  • Reopen #11: loosen pip requirements on fastAPI...

    Reopen #11: loosen pip requirements on fastAPI...

    when using pip (and not poetry...) the error is

    The conflict is caused by:

    • The user requested fastapi==0.75.2
    • fastapi-simple-security 1.0.1 depends on fastapi<0.71 and >=0.70

    From the package on pypi

    fastapi_simple_security-1.0.1.dist-info/METADATA:Requires-Dist: fastapi (>=0.70,<0.71) The only other ref to fastapi in your repo is

    [[package]] name = "fastapi" version = "0.70.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" category = "main" optional = false python-versions = ">=3.6.1"

    opened by plocher 1
  • typo error in _security_secret.py

    typo error in _security_secret.py

     warnings.warn(
         f"ENVIRONMENT VARIABLE 'FASTAPI_SIMPLE_SECURITY_SECRET' NOT FOUND\n"
         f"\tGenerated a single-use secret key for this session:\n"
         f"\t{SECRET=}"
    

    )

    opened by bijonguha 1
  • unable to open sqlite db path

    unable to open sqlite db path

    Using: fastapi==0.68.0

    After setup, setting the FASTAPI_SIMPLE_SECURITY_DB_LOCATION does not change the path from the default of /app/sqlite.db as expected. Instead getting hit with this error sqlite3.OperationalError: unable to open database file Looking at the _sqlite_access.py definition doing this instead: def __init__(self): try: self.db_location = os.environ["FASTAPI_SIMPLE_SECURITY_DB_LOCATION"] except KeyError: self.db_location = ""

    seems to work.

    opened by ejakait 1
  • Replaced underscore with hyphen in SECRET_KEY_NAME

    Replaced underscore with hyphen in SECRET_KEY_NAME

    Because nginx by default drops headers with underscores.

    Missing (disappearing) HTTP Headers

    If you do not explicitly set underscores_in_headers on;, NGINX will silently drop HTTP headers with underscores (which are perfectly valid according to the HTTP standard). This is done in order to prevent ambiguities when mapping headers to CGI variables as both dashes and underscores are mapped to underscores during that process. https://www.nginx.com/nginx-wiki/build/dirhtml/start/topics/tutorials/config_pitfalls/

    While it seems possible to reconfigure nginx to accept underscored headers, just getting to the bottom of the issue could take some time (it did for me) and it might be desirable to avoid jumping through hoops by simply replacing the underscore with a hyphen in the SECRET_KEY_NAME, to be secret-key.

    opened by yourkin 1
  • Dependency Dashboard

    Dependency Dashboard

    This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

    Ignored or Blocked

    These are blocked by an existing closed PR and will not be recreated unless you click a checkbox below.

    Detected dependencies

    docker-compose
    docker-compose.yml
    dockerfile
    Dockerfile
    github-actions
    .github/workflows/pr_python_tests.yml
    • actions/checkout v3
    • actions/setup-python v4
    • abatilo/actions-poetry v2.2.0
    .github/workflows/push_sanity_check.yml
    • actions/checkout v3
    • actions/checkout v3
    • actions/setup-python v4
    poetry
    pyproject.toml
    • fastapi >=0.70
    • urllib3 >=1.26.12
    • pytest ^7.0.0
    • black ^22.3.0
    • requests ^2.26.0
    • pre-commit ^2.20.0
    • pylint ^2.15.4
    • isort ^5.10.1
    • coverage ^6.5.0

    • [ ] Check this box to trigger a request for Renovate to run again on this repository
    opened by renovate[bot] 0
Releases(1.2.0)
Owner
Tolki
Data Analyst in Esports.
Tolki
OAuth2 goodies for the Djangonauts!

Django OAuth Toolkit OAuth2 goodies for the Djangonauts! If you are facing one or more of the following: Your Django app exposes a web API you want to

Jazzband 2.7k Dec 31, 2022
A flask extension for managing permissions and scopes

Flask-Pundit A simple flask extension to organize resource authorization and scoping. This extension is heavily inspired by the ruby Pundit library. I

Anurag Chaudhury 49 Dec 23, 2022
Pingo provides a uniform API to program devices like the Raspberry Pi, BeagleBone Black, pcDuino etc.

Pingo provides a uniform API to program devices like the Raspberry Pi, BeagleBone Black, pcDuino etc. just like the Python DBAPI provides an uniform API for database programming in Python.

Garoa Hacker Clube 12 May 22, 2022
This app makes it extremely easy to build Django powered SPA's (Single Page App) or Mobile apps exposing all registration and authentication related functionality as CBV's (Class Base View) and REST (JSON)

Welcome to django-rest-auth Repository is unmaintained at the moment (on pause). More info can be found on this issue page: https://github.com/Tivix/d

Tivix 2.4k Jan 03, 2023
Foundation Auth Proxy is an abstraction on Foundations' authentication layer and is used to authenticate requests to Atlas's REST API.

foundations-auth-proxy Setup By default the server runs on http://0.0.0.0:5558. This can be changed via the arguments. Arguments: '-H' or '--host': ho

Dessa - Open Source 2 Jul 03, 2020
Python library for generating a Mastercard API compliant OAuth signature.

oauth1-signer-python Table of Contents Overview Compatibility References Usage Prerequisites Adding the Library to Your Project Importing the Code Loa

23 Aug 01, 2022
A Python package, that allows you to acquire your RecNet authorization bearer token with your account credentials!

RecNet-Login This is a Python package, that allows you to acquire your RecNet bearer token with your account credentials! Installation Done via git: p

Jesse 6 Aug 18, 2022
Alisue 299 Dec 06, 2022
API with high performance to create a simple blog and Auth using OAuth2 ⛏

DogeAPI API with high performance built with FastAPI & SQLAlchemy, help to improve connection with your Backend Side to create a simple blog and Cruds

Yasser Tahiri 111 Jan 05, 2023
Authentication with fastapi and jwt cd realistic

Authentication with fastapi and jwt cd realistic Dependencies bcrypt==3.1.7 data

Fredh Macau 1 Jan 04, 2022
OpenStack Keystone auth plugin for HTTPie

httpie-keystone-auth OpenStack Keystone auth plugin for HTTPie. Installation $ pip install --upgrade httpie-keystone-auth You should now see keystone

Pavlo Shchelokovskyy 1 Oct 20, 2021
An open source Flask extension that provides JWT support (with batteries included)!

Flask-JWT-Extended Features Flask-JWT-Extended not only adds support for using JSON Web Tokens (JWT) to Flask for protecting views, but also many help

Landon Gilbert-Bland 1.4k Jan 04, 2023
Out-of-the-box support register, sign in, email verification and password recovery workflows for websites based on Django and MongoDB

Using djmongoauth What is it? djmongoauth provides out-of-the-box support for basic user management and additional operations including user registrat

hao 3 Oct 21, 2021
Simple implementation of authentication in projects using FastAPI

Fast Auth Facilita implementação de um sistema de autenticação básico e uso de uma sessão de banco de dados em projetos com tFastAPi. Instalação e con

3 Jan 08, 2022
Accounts for Django made beautifully simple

Django Userena Userena is a Django application that supplies your Django project with full account management. It's a fully customizable application t

Bread & Pepper 1.3k Sep 18, 2022
Django-registration (redux) provides user registration functionality for Django websites.

Description: Django-registration provides user registration functionality for Django websites. maintainers: Macropin, DiCato, and joshblum contributor

Andrew Cutler 920 Jan 08, 2023
Use this to create (admin) personal access token in gitlab database. Mainly used for automation.

gitlab-personal-access-token Ensure PAT is present in gitlab database. This tool is mainly used when you need to automate gitlab installation and conf

CINAQ Internet Technologies 1 Jan 30, 2022
A JOSE implementation in Python

python-jose A JOSE implementation in Python Docs are available on ReadTheDocs. The JavaScript Object Signing and Encryption (JOSE) technologies - JSON

Michael Davis 1.2k Dec 28, 2022
Connect-4-AI - AI that plays Connect-4 using the minimax algorithm

Connect-4-AI Brief overview I coded up the Connect-4 (or four-in-a-row) game in

Favour Okeke 1 Feb 15, 2022
python-social-auth and oauth2 support for django-rest-framework

Django REST Framework Social OAuth2 This module provides OAuth2 social authentication support for applications in Django REST Framework. The aim of th

1k Dec 22, 2022