Skip to main content

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 cookieHttpOnly, Secure (configurable), SameSite=Lax, Max-Age=600 by default. Signed with HMAC-SHA256 over the state secret.
  • CSRF — the callback rejects requests whose state query 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 to success_redirect.
  • client_secret — never logged, never returned in any URL or response.
  • Email verificationemail_verified=True is set only when the provider explicitly signals it (GitHub uses the /user/emails endpoint). Facebook does not, so it defaults to False.

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hawkapi_sso-0.1.0.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hawkapi_sso-0.1.0-py3-none-any.whl (17.9 kB view details)

Uploaded Python 3

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

Hashes for hawkapi_sso-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8664509fb9a83940d77142b4d1e616241a659f3147f681a6fc2d73556a4c172a
MD5 9d061ece850b8192518bf4eff6360092
BLAKE2b-256 408a849f32f8973bc905908c7f59dde3ebda1f4899536867e0adad5ca30ace0b

See more details on using hashes here.

Provenance

The following attestation bundles were made for hawkapi_sso-0.1.0.tar.gz:

Publisher: release.yml on ashimov/hawkapi-sso

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for hawkapi_sso-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ae1417ea2de54f05ad55892b2d996a0afa461bdd83b9a5d9ce62433b713829f9
MD5 f9715b4de792eeb64c01a6b1674ddab0
BLAKE2b-256 b667a9cdfb3df988f81068d2989ac21287326d2f8047dc9073a13ee59f4cf630

See more details on using hashes here.

Provenance

The following attestation bundles were made for hawkapi_sso-0.1.0-py3-none-any.whl:

Publisher: release.yml on ashimov/hawkapi-sso

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page