mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-23 20:23:00 +00:00
Which list routes insist on an owner is the server's rule, and it moves. The deployed binary requires one on users, sessions and applications and not on roles, permissions, providers, workspaces, invitations, tokens or audit-logs; the change that resolves a listing's tenant centrally is written but unreleased. So nothing here keeps a copy of that rule. The IAM tool no longer refuses a missing owner on applications and sessions, get_applications takes an owner rather than demanding one, and no docstring or parameter description promises that leaving it off makes the credential decide — today that answers 400. A refusal now reaches the caller as the reason IAM gave rather than as a transcribed body: the RFC 9457 detail, or the envelope's msg where the route answers the envelope, which is how memberships refuses. Co-authored-by: Hanzo Dev <[email protected]>
hanzoai-iam
Identity and Access Management SDK for the Hanzo ecosystem. Organization-aware multi-tenant IAM for the Hanzo ecosystem.
The PyPI distribution is hanzoai-iam; the import path is hanzo_iam.
Installation
pip install hanzoai-iam
With FastAPI integration:
pip install hanzoai-iam[fastapi]
With KMS support for certificate management:
pip install hanzoai-iam[kms]
Quick Start
from hanzo_iam import IAMClient, IAMConfig
config = IAMConfig(
endpoint="https://iam.hanzo.ai",
client_id="your-client-id",
client_secret="your-client-secret",
org_name="HANZO",
)
client = IAMClient(config)
# Get authorization URL for user login
auth_url = client.get_auth_url(redirect_uri="https://yourapp.com/callback")
# Exchange code for tokens
tokens = client.get_token(code="auth-code-from-callback")
# Get user info
user = client.get_user_info(access_token=tokens.access_token)
Organizations
| Organization | Endpoint | Description |
|---|---|---|
| HANZO | https://iam.hanzo.ai | Hanzo AI platform |
| ZOO | https://iam.zoo.dev | Zoo Labs Foundation |
| LUX | https://iam.lux.network | Lux blockchain network |
| PARS | https://iam.pars.dev | Pars development platform |
Environment Variables
One canonical prefix — IAM_*. No upstream-brand aliases, no per-org variants.
# Required
IAM_ENDPOINT=https://hanzo.id
IAM_CLIENT_ID=your-client-id
IAM_CLIENT_SECRET=your-client-secret
# Optional (defaults shown)
IAM_ORG=hanzo
IAM_APP=app
IAM_CERT=path/to/cert.pem # PEM file or inline PEM content
FastAPI Integration
from fastapi import FastAPI, Depends
from hanzo_iam.fastapi import IAMAuth, get_current_user
from hanzo_iam import IAMConfig, User
app = FastAPI()
config = IAMConfig.from_env()
auth = IAMAuth(config)
@app.get("/protected")
async def protected_route(user: User = Depends(auth.require_user)):
return {"user": user.name, "org": user.owner}
@app.get("/optional")
async def optional_auth(user: User | None = Depends(auth.optional_user)):
if user:
return {"message": f"Hello, {user.name}"}
return {"message": "Hello, anonymous"}
Client Credentials Flow
For service-to-service authentication:
from hanzo_iam import IAMClient, IAMConfig
config = IAMConfig(
endpoint="https://iam.hanzo.ai",
client_id="service-client-id",
client_secret="service-client-secret",
org_name="HANZO",
)
client = IAMClient(config)
# Get service token
tokens = client.get_client_credentials_token()
# Use token for API calls
headers = {"Authorization": f"Bearer {tokens.access_token}"}
Async Client
import asyncio
from hanzo_iam import AsyncIAMClient, IAMConfig
async def main():
config = IAMConfig.from_env()
client = AsyncIAMClient(config)
# All methods are async
tokens = await client.get_client_credentials_token()
user = await client.get_user_info(tokens.access_token)
print(f"Authenticated as: {user.name}")
asyncio.run(main())
API Reference
| Method | Description |
|---|---|
get_auth_url(redirect_uri, state, scope) |
Generate OAuth authorization URL |
get_token(code) |
Exchange authorization code for tokens |
refresh_token(refresh_token) |
Refresh access token |
get_client_credentials_token() |
Get token via client credentials flow |
get_user_info(access_token) |
Get user info from access token |
parse_jwt(token) |
Parse and validate JWT claims |
get_user(user_id) |
Get user by ID |
get_users() |
List all users in organization |
create_user(user) |
Create new user |
update_user(user) |
Update existing user |
delete_user(user_id) |
Delete user |
get_organizations() |
List organizations |
get_organization(name) |
Get organization by name |
License
Apache-2.0