hypershub-sso
Typed synchronous and asynchronous OAuth 2.0 / OpenID Connect client for HypersHub SSO. It implements Authorization Code + PKCE for Python backends and BFFs, verifies ID Tokens, and manages refreshable server-side sessions.
Use this package only in a trusted Python server. Never expose the OAuth client secret, PKCE verifier, authorization code, access token, or refresh token to browser code.
Requirements
- Python 3.11 or newer
- An SSO client registration with an exact HTTPS redirect URI
- A server-side session store such as Redis, Valkey, or a database
- A high-entropy opaque browser session identifier in a host-only
HttpOnly; Secure; SameSite=Laxcookie
Install
python -m pip install hypershub-sso
Synchronous client
Use SsoClient with Flask, Django, or another synchronous application:
import os
from hypershub_sso import (
KeyValueStore,
SsoClient,
create_encrypted_session_store,
)
class RedisStore(KeyValueStore):
def get(self, key: str) -> str | None:
value = redis.get(key)
return value.decode() if value is not None else None
def set(self, key: str, value: str, ttl_seconds: int) -> None:
redis.set(key, value, ex=ttl_seconds)
def delete(self, key: str) -> None:
redis.delete(key)
session_store = create_encrypted_session_store(
RedisStore(),
os.environ["SSO_SESSION_ENCRYPTION_KEY"],
)
sso = SsoClient(
issuer="https://main.example.com/sso",
client_id=os.environ["SSO_CLIENT_ID"],
client_secret=os.environ["SSO_CLIENT_SECRET"],
redirect_uri="https://project.example.com/auth/callback",
store=session_store,
)
Asynchronous client
Use AsyncSsoClient with FastAPI, Starlette, Quart, or another asyncio
application. The raw store methods must also be async:
from hypershub_sso import (
AsyncSsoClient,
create_async_encrypted_session_store,
)
session_store = create_async_encrypted_session_store(
async_redis_store,
os.environ["SSO_SESSION_ENCRYPTION_KEY"],
)
sso = AsyncSsoClient(
issuer="https://main.example.com/sso",
client_id=os.environ["SSO_CLIENT_ID"],
client_secret=os.environ["SSO_CLIENT_SECRET"],
redirect_uri="https://project.example.com/auth/callback",
store=session_store,
)
Close a client during application shutdown with sso.close() or
await sso.aclose(). A caller-supplied httpx.Client or httpx.AsyncClient
remains owned by the caller and is not closed by the SDK.
Route integration
The SDK does not own framework cookies or responses. Your application supplies
the opaque browser session ID as key:
# GET /auth/login
return redirect(sso.begin_login(session_id, "/dashboard"))
# GET /auth/callback?code=...&state=...
result = sso.handle_callback(session_id, request.args)
return redirect(result.return_to)
# Before a protected handler
session = sso.require_session(session_id)
user_subject = session.principal.sub
# POST /auth/logout; protect this route with normal CSRF controls
sso.logout(session_id)
clear_session_cookie()
For AsyncSsoClient, await each method. Only the opaque session ID belongs in
the cookie; token-bearing SsoSession objects remain in server-side storage.
Encryption key
Generate a 256-bit key once, then store it in your secret manager:
python -c "from hypershub_sso import generate_session_encryption_key as g; print(g())"
The encrypted adapters use AES-256-GCM and authenticate the storage key to prevent ciphertext swapping. Rotating the key requires a key-ring migration or invalidating existing local sessions. Never commit it to source control.
For multi-process deployments, the raw store may implement with_lock using a
Redis SET NX lock and owner-token checked Lua release. The encrypted adapter
automatically exposes it to the client as a distributed refresh lock.
Errors
Expected failures are SsoClientError instances with stable codes:
from hypershub_sso import SsoClientError
try:
session = sso.require_session(session_id)
except SsoClientError as error:
if error.code == "AUTH_REAUTH_REQUIRED":
return redirect("/auth/login")
if error.retriable:
return service_unavailable()
raise
AUTH_REAUTH_REQUIRED: the local or refresh session is invalid; begin login.SSO_TEMPORARILY_UNAVAILABLE: network, timeout, rate-limit, JWKS, or SSO 5xx failure. Return 503 or retry later; do not log the user out.SSO_STATE_MISMATCH,SSO_NONCE_MISMATCH,SSO_ID_TOKEN_INVALID: reject the callback and do not create an application session.SSO_TOKEN_ERROR: the token endpoint rejected a non-retryable request.
Messages do not include credentials or tokens. Optional SDK logs contain only fixed text and non-sensitive error metadata.
Defaults
| Option | Default | Purpose |
|---|---|---|
refresh_ahead_seconds |
300 |
Refresh before access-token expiry |
session_idle_seconds |
43200 |
Sliding local-session idle lifetime |
session_absolute_seconds |
2592000 |
Maximum local-session lifetime |
refresh_max_attempts |
3 |
Attempts for transient refresh failures |
refresh_retry_base_delay |
0.2 |
Initial exponential delay in seconds |
request_timeout |
10 |
Token, revocation, and JWKS timeout |
clock_tolerance_seconds |
60 |
ID Token clock-skew tolerance |
validate_return_to |
relative paths only | Prevent open redirects |
Remote JWKS honor bounded Cache-Control: max-age caching. An unknown kid
causes one immediate refresh. Plain HTTP is rejected except for loopback
development hosts unless allow_insecure_http=True is explicitly set.
License
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 hypershub_sso-0.1.0.tar.gz.
File metadata
- Download URL: hypershub_sso-0.1.0.tar.gz
- Upload date:
- Size: 67.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1a1b8c36f34bb21f98eb51f79cec64642105687199aceecd5928e0aabde068dd
|
|
| MD5 |
219312b01bfb4b7b2c366d038738d014
|
|
| BLAKE2b-256 |
5fb690f9f4f77adfe11e64b1fda25ba5183e839044ca1046a6a5005a8781efc6
|
File details
Details for the file hypershub_sso-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hypershub_sso-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a2cf342a4675f9ca043a4b471361905d4791412e38b80e186602198335ab584
|
|
| MD5 |
cbacff9135e21541f2d8de1b7be234e1
|
|
| BLAKE2b-256 |
364a757cbb2577229159a6ca93fd04897f205b07980a656275f0b6bf0c738b6b
|