zanii-id
Python SDK for Zanii ID — OAuth 2.1 / OpenID Connect sign-in for products in the Zanii ecosystem.
Authorization Code flow with mandatory PKCE, offline ID-token verification against the issuer's JWKS, and a FastAPI integration that mounts the whole login round-trip for you.
pip install zanii-id
Use it
Configuration comes from ZANII_ISSUER, ZANII_CLIENT_ID, ZANII_CLIENT_SECRET and
ZANII_REDIRECT_URI, and is validated eagerly so a misconfigured deployment fails at
startup rather than on a user's first login.
from zanii_id import ZaniiClient
zanii = ZaniiClient()
req = zanii.get_authorization_url() # keep req.state / req.nonce / req.verifier in session
# ... redirect the user to req.url, then on your callback route:
tokens = await zanii.exchange_code(code, req, received_state)
claims = zanii.verify_id_token(tokens.id_token, nonce=req.nonce)
user = await zanii.get_user(tokens.access_token)
FastAPI
from zanii_id import ZaniiClient
from zanii_id.integrations.fastapi import build_auth_router, install_zanii, require_zanii_auth
zanii = ZaniiClient()
install_zanii(app, zanii, session_secret=SECRET)
app.include_router(build_auth_router(zanii, session_secret=SECRET))
@app.get("/dashboard")
async def dashboard(user = Depends(require_zanii_auth)):
return {"zanii_user_id": user.zanii_user_id}
That mounts /auth/login, /auth/callback and /auth/logout. require_zanii_auth
refreshes a stale access token once and rotates the session cookie before giving up.
Provisioning users locally
sub is an immutable zanii_user_id. Upsert on it — never on email, which users change:
INSERT INTO users (zanii_user_id, ...) VALUES ($1, ...)
ON CONFLICT (zanii_user_id) DO NOTHING;
Agent activity
If your product records agent receipts on the Zanii ledger, stamp them with the user's subject tag so they can audit their own slice:
from zanii_id.activity import subject_tag, fetch_activity # pip install 'zanii-id[subject]'
tag = subject_tag(user.did, client_id) # pass to record(..., subject_tag=tag)
entries = await fetch_activity(tag) # every receipt verified offline
Invalid receipts come back with verified=False and a flag_reason rather than being
dropped — a truncated slice appends its own flagged entry, so a cut page never reads as
complete.
Notes
algis pinned from the discovery document, never trusted from the token header.- Token POSTs are never retried; grants are single-use.
- The JWKS cache refetches exactly once on an unseen
kid, then fails hard.
Licence
Apache-2.0. See 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 zanii_id-0.1.0.tar.gz.
File metadata
- Download URL: zanii_id-0.1.0.tar.gz
- Upload date:
- Size: 18.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
935c2907bc692b1c6c2885223814ccd1b1b13c09db2ebc7f2b3ec977bcfa3367
|
|
| MD5 |
71e74373d6379075e138739a2733b66e
|
|
| BLAKE2b-256 |
ae800e3dd583425cad93be5449e4eba4939db53e5e0484fa3b446c96eb71f63a
|
File details
Details for the file zanii_id-0.1.0-py3-none-any.whl.
File metadata
- Download URL: zanii_id-0.1.0-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baaf84fc70be42aaf11cd64ae7154f76d8e710a3c4145da4d9ceee1feb5fa73f
|
|
| MD5 |
0367c1d1ce3ae4a8979fb27d7ee0b2b3
|
|
| BLAKE2b-256 |
8a608c6a654075043edbe9a5324c151fa3d5ebd76140e275cc3243032bf31ed5
|