Phzyx Auth — secure-by-default identity, sessions, JWT, API keys, RBAC (Forge battery)
Project description
phzyx-auth
Secure-by-default authentication & authorization for Phzyx apps and AdminBoard.
Public battery for Forge (depends on phzyx-forge on PyPI).
uv add 'phzyx-forge[auth]'
# or
uv add 'phzyx-auth[fastapi]'
Status (0.1.0)
Phase A + B shipped (memory backends; ORM-backed stores next):
| Area | What you get |
|---|---|
| Passwords | Argon2id, policy min length |
| Sessions | Opaque cookie sessions (hashed at rest), idle + absolute TTL |
| JWT | HS256 access + rotating refresh |
| API keys | phx_ prefix, scopes, list/revoke |
| RBAC | Groups/Permissions models, Principal, ensure_* + Depends + decorators |
| Lockout | Failed-login counter + rate limits + audit log |
| Reset / change | Forgot/reset (anti-enum), change password, revoke sessions |
| Email verify | Token issue + verify (email_verified flag) |
| CSRF | Double-submit cookie + X-CSRF-Token for session mutations |
| WebSocket | websocket_principal (cookie / Bearer / API key, close 4401) |
| AdminBoard | PhzyxAuthz permission bridge |
| CLI | phzyx-auth create-superuser |
Later: OAuth IdPs (Phase D stub in oauth.py), MFA/passkeys (E), orgs (F), Redis rate limit, ORM session store.
Quick start (FastAPI)
from fastapi import Depends, FastAPI
from phzyx.auth import AuthConfig, AuthService, Principal
from phzyx.auth.adapters.fastapi import mount_auth, require_user
app = FastAPI()
svc = AuthService(
config=AuthConfig(
secret="use-PHZYX_AUTH_SECRET-32+bytes-in-prod!!",
production=False,
cookie_secure=False,
)
)
mount_auth(app, svc)
@app.get("/private")
async def private(user: Principal = Depends(require_user)):
return {"email": user.email}
# create staff superuser (in-memory unless you wire persistence)
phzyx-auth create-superuser --email admin@example.com --password 'longpassword1'
SPA cookie flow
POST /auth/login→ setsphzyx_session(HttpOnly) +phzyx_csrf+ returnscsrf_token- Mutating requests with the session cookie must send header
X-CSRF-Token: <csrf_token> - Bearer JWT /
X-API-Keyskip CSRF
In-body checks (no middleware)
from phzyx.auth.guards import ensure_authenticated, ensure_permissions
p = svc.resolve_principal(session_token=cookie, authorization=authz, api_key=key)
user = ensure_authenticated(p)
ensure_permissions(user, ["posts:create"])
Security defaults
- Argon2id hashing
- Secrets ≥ 32 bytes (HS256 / pepper)
- Opaque sessions + short JWT access
- API keys hashed at rest
- Lockout + IP/email rate limits
- Password reset anti-enumeration
- Extensible
AbstractUser
Research (do not re-derive): research/plan/20_phzyx_auth.md
Tracker: PHZYX_ROADMAP.html track AUTH.
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 phzyx_auth-0.1.0.tar.gz.
File metadata
- Download URL: phzyx_auth-0.1.0.tar.gz
- Upload date:
- Size: 43.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c406285deebbe1e67ff1e0272a1d2a905ffa670ee00d05ff0c0d7ca826ef04c
|
|
| MD5 |
85300c9ae38938c7026224dc12e1a543
|
|
| BLAKE2b-256 |
4572510706c59c75ef0de2a0dc4631c9e23a485125b872323e8f8a8b58780e24
|
Provenance
The following attestation bundles were made for phzyx_auth-0.1.0.tar.gz:
Publisher:
publish.yml on phzyxyz/forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
phzyx_auth-0.1.0.tar.gz -
Subject digest:
7c406285deebbe1e67ff1e0272a1d2a905ffa670ee00d05ff0c0d7ca826ef04c - Sigstore transparency entry: 2269264162
- Sigstore integration time:
-
Permalink:
phzyxyz/forge@c954d727f719bfe6754c1b91aa7acd9682def480 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/phzyxyz
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c954d727f719bfe6754c1b91aa7acd9682def480 -
Trigger Event:
push
-
Statement type:
File details
Details for the file phzyx_auth-0.1.0-py3-none-any.whl.
File metadata
- Download URL: phzyx_auth-0.1.0-py3-none-any.whl
- Upload date:
- Size: 47.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
595e1c5755f56fb3d8f8549f195307994b10a33909bb8c60e634f352581e925c
|
|
| MD5 |
4f6a39ab01722d94f5c1524f4f3e7bc0
|
|
| BLAKE2b-256 |
2120257cdd8082e0bc1fbaf7782b8bdb7e119b4d153e4dbf82048a0371261775
|
Provenance
The following attestation bundles were made for phzyx_auth-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on phzyxyz/forge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
phzyx_auth-0.1.0-py3-none-any.whl -
Subject digest:
595e1c5755f56fb3d8f8549f195307994b10a33909bb8c60e634f352581e925c - Sigstore transparency entry: 2269264333
- Sigstore integration time:
-
Permalink:
phzyxyz/forge@c954d727f719bfe6754c1b91aa7acd9682def480 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/phzyxyz
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c954d727f719bfe6754c1b91aa7acd9682def480 -
Trigger Event:
push
-
Statement type: