OAuth Web Service with Python

October 20, 2025 ยท View on GitHub

This is a example project showing how to implement an Python web service which uses atproto OAuth for authentication. It uses Flask as a web framework, and sqlite as a database to store session tokens. The implementation details are best understood in combination with the OAuth Client Implementation guide, but see OAuth Introduction for a higher level overview.

There is currently a version of this deployed at https://oauth-flask.demo.bsky.dev/, though this may not be maintained long-term.

Quickstart

This demo is designed to be run on the public web, with a globally routed domain name with a valid HTTPS certificate. It uses uv to manage dependencies and requires some pre-configuration.

First install uv, then set up the project environment in this directory:

uv sync

Copy example.env to .env and update it with locally-generated secrets:

# FLASK_SECRET_KEY (for cookie session security)
uv run python3 -c 'import secrets; print(secrets.token_hex())'

# FLASK_CLIENT_SECRET_JWK (for OAuth confidential client)
uv run ./generate_jwk.py

Run the service locally:

uv run -- flask run

If you just want to test locally, you can stop here - the service will automatically use a localhost client ID.

To continue with deployment, open a public internet tunnel with a valid hostname and HTTPS using a tool like ngrok, Tailscale Funnel, or open-source equivalents:

ngrok http http://localhost:5000

Alternatively, run this on a real server and use Caddy or nginx+certbot to generate TLS certificates.