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
Flask Implementation of a login page and some basic functionality.

login_page Flask Implementation of a login page and some basic functionality. How to Run $ chmod +x run.sh setup.sh $ # run setup.sh only if the datab

3 Jun 03, 2021
Authentication testing framework

What is this This is a framework designed to test authentication for web applications. While web proxies like ZAProxy and Burpsuite allow authenticate

DigeeX 140 Jul 06, 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
FastAPI-Login tries to provide similar functionality as Flask-Login does.

FastAPI-Login FastAPI-Login tries to provide similar functionality as Flask-Login does. Installation $ pip install fastapi-login Usage To begin we hav

417 Jan 07, 2023
Authentication for Django Rest Framework

Dj-Rest-Auth Drop-in API endpoints for handling authentication securely in Django Rest Framework. Works especially well with SPAs (e.g React, Vue, Ang

Michael 1.1k Jan 03, 2023
Login-python - Login system made in Python, using native libraries

login-python Sistema de login feito 100% em Python, utilizando bibliotecas nativ

Nicholas Gabriel De Matos Leal 2 Jan 28, 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
Luca Security Concept

Luca Security Concept This is the document source of luca's security concept. Please go here for the HTML version: https://luca-app.de/securityconcept

luca 43 Oct 22, 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
Generate payloads that force authentication against an attacker machine

Hashgrab Generates scf, url & lnk payloads to put onto a smb share. These force authentication to an attacker machine in order to grab hashes (for exa

xct 35 Dec 20, 2022
Flask user session management.

Flask-Login Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users

Max Countryman 3.2k Dec 28, 2022
Simplifying third-party authentication for web applications.

Velruse is a set of authentication routines that provide a unified way to have a website user authenticate to a variety of different identity provider

Ben Bangert 253 Nov 14, 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
Mock authentication API that acceccpts email and password and returns authentication result.

Mock authentication API that acceccpts email and password and returns authentication result.

Herman Shpryhau 1 Feb 11, 2022
Django Admin Two-Factor Authentication, allows you to login django admin with google authenticator.

Django Admin Two-Factor Authentication Django Admin Two-Factor Authentication, allows you to login django admin with google authenticator. Why Django

Iman Karimi 9 Dec 07, 2022
A JSON Web Token authentication plugin for the Django REST Framework.

Simple JWT Abstract Simple JWT is a JSON Web Token authentication plugin for the Django REST Framework. For full documentation, visit django-rest-fram

Simple JWT 3.3k Jan 01, 2023
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
An introduction of Markov decision process (MDP) and two algorithms that solve MDPs (value iteration, policy iteration) along with their Python implementations.

Markov Decision Process A Markov decision process (MDP), by definition, is a sequential decision problem for a fully observable, stochastic environmen

Yu Shen 31 Dec 30, 2022
Abusing Microsoft 365 OAuth Authorization Flow for Phishing Attack

Microsoft365_devicePhish Abusing Microsoft 365 OAuth Authorization Flow for Phishing Attack This is a simple proof-of-concept script that allows an at

Optiv Security 76 Jan 02, 2023
An extension of django rest framework, providing a configurable password reset strategy

Django Rest Password Reset This python package provides a simple password reset strategy for django rest framework, where users can request password r

Anexia 363 Dec 24, 2022