Social SSO for HawkAPI — Google, GitHub, Microsoft, Discord, Facebook, LinkedIn
Project description
hawkapi-sso
Social SSO for HawkAPI. One plugin, six providers:
- Google (OAuth2 + OIDC, PKCE)
- GitHub (OAuth2)
- Microsoft / Entra (OAuth2 + OIDC, PKCE)
- Discord (OAuth2)
- Facebook (OAuth2 + Graph API)
- LinkedIn (OAuth2 + OIDC, PKCE)
Pure-Python, async, httpx-based. CSRF-protected via HMAC-signed state cookie. PKCE applied automatically where the provider supports it.
Install
pip install hawkapi-sso
Quickstart
from hawkapi import HawkAPI
from hawkapi_sso import GoogleProvider, GitHubProvider, init_sso
app = HawkAPI()
init_sso(
app,
providers={
"google": GoogleProvider(client_id="...", client_secret="..."),
"github": GitHubProvider(client_id="...", client_secret="..."),
},
state_secret="...", # ≥16 chars; stable across restarts
)
# These routes are mounted automatically:
# GET /auth/sso/login/{provider} → redirects to the provider's authorize URL
# GET /auth/sso/callback/{provider} → handles the OAuth callback, sets `request.scope["sso_user"]`,
# then redirects to `?next=` (or success_redirect).
Reading the authenticated user
The callback handler stashes a normalized OAuthUser on the request scope. Pick it up in your downstream middleware / handlers:
@app.middleware("http")
async def persist_session(request, call_next):
response = await call_next(request)
user = request.scope.get("sso_user")
if user is not None:
# persist user, set session cookie, etc.
...
return response
You can also wire a callback hook:
async def on_login(request, user, token):
# persist, mint JWT, etc.
...
cfg = init_sso(app, providers={...}, state_secret="...")
cfg.on_success = on_login
OAuthUser
@dataclass
class OAuthUser:
provider: str # "google" / "github" / ...
sub: str # provider-issued user id (always string)
email: str # "" if not granted
email_verified: bool # only True when the provider explicitly signals it
name: str
picture: str
raw: dict # the parsed userinfo response, for advanced use
Security
- State cookie —
HttpOnly,Secure(configurable),SameSite=Lax,Max-Age=600by default. Signed with HMAC-SHA256 over the state secret. - CSRF — the callback rejects requests whose
statequery parameter does not match the state cookie byte-for-byte. - PKCE — automatically generated and verified for Google, Microsoft, LinkedIn.
- Open-redirect guard —
?next=parameter must be a path (/...); anything else falls back tosuccess_redirect. client_secret— never logged, never returned in any URL or response.- Email verification —
email_verified=Trueis set only when the provider explicitly signals it (GitHub uses the/user/emailsendpoint). Facebook does not, so it defaults toFalse.
Configuration
init_sso(
app,
providers={...},
state_secret="...",
cookie_name="hawkapi_sso_state",
cookie_secure=True,
cookie_samesite="lax",
cookie_max_age=600,
login_path_prefix="/auth/sso",
success_redirect="/",
failure_redirect="/login?error=sso",
)
Development
git clone https://github.com/ashimov/hawkapi-sso.git
cd hawkapi-sso
uv sync --extra dev
uv run pytest -q
uv run ruff check . && uv run ruff format --check .
uv run pyright src/
License
MIT.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hawkapi_sso-0.1.0.tar.gz.
File metadata
- Download URL: hawkapi_sso-0.1.0.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8664509fb9a83940d77142b4d1e616241a659f3147f681a6fc2d73556a4c172a
|
|
| MD5 |
9d061ece850b8192518bf4eff6360092
|
|
| BLAKE2b-256 |
408a849f32f8973bc905908c7f59dde3ebda1f4899536867e0adad5ca30ace0b
|
Provenance
The following attestation bundles were made for hawkapi_sso-0.1.0.tar.gz:
Publisher:
release.yml on ashimov/hawkapi-sso
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hawkapi_sso-0.1.0.tar.gz -
Subject digest:
8664509fb9a83940d77142b4d1e616241a659f3147f681a6fc2d73556a4c172a - Sigstore transparency entry: 1553896162
- Sigstore integration time:
-
Permalink:
ashimov/hawkapi-sso@f9775c071825b6f030f5d9e7245058270bba85ff -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ashimov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f9775c071825b6f030f5d9e7245058270bba85ff -
Trigger Event:
release
-
Statement type:
File details
Details for the file hawkapi_sso-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hawkapi_sso-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae1417ea2de54f05ad55892b2d996a0afa461bdd83b9a5d9ce62433b713829f9
|
|
| MD5 |
f9715b4de792eeb64c01a6b1674ddab0
|
|
| BLAKE2b-256 |
b667a9cdfb3df988f81068d2989ac21287326d2f8047dc9073a13ee59f4cf630
|
Provenance
The following attestation bundles were made for hawkapi_sso-0.1.0-py3-none-any.whl:
Publisher:
release.yml on ashimov/hawkapi-sso
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hawkapi_sso-0.1.0-py3-none-any.whl -
Subject digest:
ae1417ea2de54f05ad55892b2d996a0afa461bdd83b9a5d9ce62433b713829f9 - Sigstore transparency entry: 1553896166
- Sigstore integration time:
-
Permalink:
ashimov/hawkapi-sso@f9775c071825b6f030f5d9e7245058270bba85ff -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ashimov
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@f9775c071825b6f030f5d9e7245058270bba85ff -
Trigger Event:
release
-
Statement type: