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.