Skip to main content

fastapi-trusted-devices

Trusted-device management and session security for FastAPI.

Bind every authenticated session to a known device, list and revoke devices, and detect suspicious activity — without locking your app into a specific auth library or ORM.

Status

0.1.0 — Alpha. Core device registry + management endpoints. The public API may change before 1.0. See CHANGELOG.md and the roadmap.

Why

FastAPI gives you authentication primitives but no notion of which device a token belongs to. fastapi-trusted-devices adds that layer:

  • Associate each session with a device_uid.
  • List a user's active devices and revoke any of them.
  • Per-device permissions (who may update/revoke other devices).
  • Hooks for "new device", "device revoked", and (from 0.2) suspicious-login and session-hijack events.

It is auth-agnostic (you keep your own login/JWT flow) and storage abstracted behind a DeviceRepository protocol (SQLAlchemy 2.0 async adapter included).

Install

pip install fastapi-trusted-devices
# optional extras:
pip install "fastapi-trusted-devices[geo]"   # httpx geolocation backend (0.2+)
pip install "fastapi-trusted-devices[jwt]"   # PyJWT token helpers

Quickstart

from fastapi import Depends, FastAPI
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine

from fastapi_trusted_devices import (
    Base,
    TrustedDevices,
    TrustedDeviceConfig,
)

engine = create_async_engine("sqlite+aiosqlite:///./devices.db")
sessionmaker = async_sessionmaker(engine, expire_on_commit=False)

td = TrustedDevices(
    config=TrustedDeviceConfig(max_devices_per_user=10),
    sessionmaker=sessionmaker,
    # tell the library how to identify the caller + their device from a request:
    get_user_id=lambda request: request.headers["x-user-id"],
    get_device_uid=lambda request: request.headers.get("x-device-uid"),
)

app = FastAPI()
app.include_router(td.router, prefix="/trusted-devices", tags=["devices"])
td.install_exception_handlers(app)


@app.on_event("startup")
async def _startup() -> None:
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)


@app.get("/me", dependencies=[Depends(td.require_trusted_device)])
async def me() -> dict[str, str]:
    return {"ok": "this route requires a recognized device"}

Endpoints

Method Path Purpose
GET / List the current user's devices
PATCH /{device_uid} Rename / change permissions of a device
DELETE /{device_uid} Revoke a specific device
POST /logout Revoke the current device
POST /revoke-all Revoke every device except the current one

Roadmap

  • 0.1 — core registry, CRUD endpoints, dependencies, SQLAlchemy adapter.
  • 0.2 — geolocation backend + cache, X-Forwarded-For parsing, suspicious-login detection.
  • 0.3 — concurrent-session/hijack detection, max-device eviction policies, rate limiting, PyJWT helpers, docs site.
  • 1.0 — API freeze + semver guarantee.

License

MIT — see LICENSE.

Metadata

Release files for fastapi-trusted-devices 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fastapi-trusted-devices 0.1.0
File Size Uploaded
fastapi_trusted_devices-0.1.0.tar.gz 14.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fastapi-trusted-devices 0.1.0
File Interpreter ABI Platform
fastapi_trusted_devices-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 30.3 kB

Release files / fastapi_trusted_devices-0.1.0.tar.gz

Download URL fastapi_trusted_devices-0.1.0.tar.gz
Size 14.9 kB
Tags Source
SHA-256 checksum
How to use checksums
06579f82e21b5dc6ff7726da57153ed9abf9dff659cbf34169e8d4d88f8f71b9
BLAKE2b-256 checksum
How to use checksums
c7a28b7359add2223cf5c758c68fc46f152d7540a35e3922027cb600afcdeb5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

Release files / fastapi_trusted_devices-0.1.0-py3-none-any.whl

Download URL fastapi_trusted_devices-0.1.0-py3-none-any.whl
Size 15.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
268dc0a077ed51c96b239e1b89128c911adaf2456ab568048e76cd9054534f0d
BLAKE2b-256 checksum
How to use checksums
d395faa41211665cc17113810733cb6c7d793975a56dba7a41200641fe50c1d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page