Ship hackathon products fast with secure-by-default auth, RBAC, PostgreSQL readiness, and built-in LLM tooling.
Project description
h4ckath0n
Ship hackathon products fast, with secure-by-default auth, RBAC, Postgres readiness, and built-in LLM tooling.
h4ckath0n is an opinionated Python library that makes it hard to accidentally ship insecure glue code during a hackathon.
What you get by default
- API: FastAPI app bootstrap with OpenAPI docs
- Auth: passkey (WebAuthn) registration and login – no passwords required
- AuthZ: built-in RBAC with
userandadminroles, plus scoped permissions – all enforced server-side from the database - Database: SQLAlchemy 2.x + Alembic, works with SQLite (zero-config dev) and Postgres (recommended for production)
- LLM: built-in LLM client wrapper (OpenAI SDK) with safe defaults and redaction hooks
- Observability: opt-in LangSmith / OpenTelemetry tracing with trace ID propagation
- Config: environment-driven settings via pydantic-settings
Password auth and Redis-based queues/caching are available as optional extras.
Installation
Recommended (uv)
uv add h4ckath0n
Optional extras:
uv add "h4ckath0n[password]" # Argon2-based password auth (off by default)
uv add "h4ckath0n[redis]" # Redis support
pip
pip install h4ckath0n
Scaffold a full-stack project
npx h4ckath0n my-app
Quickstart
from h4ckath0n import create_app
app = create_app()
Run:
uv run uvicorn your_module:app --reload
Open docs at /docs (Swagger UI). Passkey auth routes are mounted automatically.
Auth: passkeys by default
h4ckath0n uses passkeys (WebAuthn) as the default authentication method. No passwords, no email required.
How it works
- Register:
POST /auth/passkey/register/start→ browser creates a passkey →POST /auth/passkey/register/finish→ account created, device key bound. - Login:
POST /auth/passkey/login/start→ browser signs with passkey →POST /auth/passkey/login/finish→ user identified, device key bound. Username-less by default. - Add passkey: authenticated users can add more passkeys via
POST /auth/passkey/add/start+POST /auth/passkey/add/finish. - Revoke passkey:
POST /auth/passkeys/{key_id}/revoke– but cannot revoke the last active passkey (returnsLAST_PASSKEYerror).
Request authentication
All API calls are authenticated via device-signed ES256 JWTs:
- Each browser generates a non-extractable P-256 keypair stored in IndexedDB
- The public key is registered with the backend during login/registration
- The client mints short-lived JWTs (15 min) signed with the device private key
- JWTs are held in memory only – never
localStorage,sessionStorage, or cookies - The JWT contains no privilege claims (no role, no scopes) – authorization is computed server-side from the database
ID scheme
- User IDs: 32-char base32 string starting with
u(e.g.,u3mfgh7k2n4p5q6r7s8t9v0w1x2y3z4a) - Internal key IDs: 32-char base32 string starting with
k - The browser's WebAuthn
credentialIdis stored separately and used for signature verification.
Secure-by-default endpoint protection
Protect an endpoint (requires a logged-in user):
from h4ckath0n import create_app
from h4ckath0n.auth import require_user
app = create_app()
@app.get("/me")
def me(user=require_user()):
return {"id": user.id, "role": user.role}
Admin-only endpoint:
from h4ckath0n.auth import require_admin
@app.get("/admin/dashboard")
def admin_dashboard(user=require_admin()):
return {"ok": True}
Scoped privileges (checked from user's DB record):
from h4ckath0n.auth import require_scopes
@app.post("/billing/refund")
def refund(user=require_scopes("billing:refund")):
return {"status": "queued"}
Auth routes
h4ckath0n mounts these routes by default:
Passkey (default)
POST /auth/passkey/register/start– begin passkey registration (creates account)POST /auth/passkey/register/finish– complete registration (binds device key, returns user_id + device_id)POST /auth/passkey/login/start– begin passkey login (username-less)POST /auth/passkey/login/finish– complete login (binds device key, returns user_id + device_id)POST /auth/passkey/add/start– begin adding a passkey (authenticated)POST /auth/passkey/add/finish– complete adding a passkey (authenticated)GET /auth/passkeys– list current user's passkeys (authenticated)POST /auth/passkeys/{key_id}/revoke– revoke a passkey (authenticated, blocked if last)
Password auth (optional extra)
Only available when h4ckath0n[password] is installed AND H4CKATH0N_PASSWORD_AUTH_ENABLED=true:
POST /auth/register– create account with email + password, bind device keyPOST /auth/login– authenticate with email + password, bind device keyPOST /auth/password-reset/request– request password resetPOST /auth/password-reset/confirm– confirm password reset, bind device key
Password auth is an identity bootstrap method only. It proves who the user is so a device key can be bound. After binding, all API calls use device-signed ES256 JWTs. Password auth does not return access tokens, refresh tokens, or session cookies.
Database
Zero-config default: SQLite is used if no database URL is provided.
To use Postgres (recommended for production):
H4CKATH0N_DATABASE_URL=postgresql+psycopg://user:pass@host:5432/dbname
The psycopg[binary] driver is included by default – no extra install needed.
LLM
h4ckath0n includes LLM tooling by default. Set OPENAI_API_KEY and use:
from h4ckath0n.llm import llm
client = llm()
resp = client.chat(
system="You are a helpful assistant.",
user="Summarize this in one sentence: ...",
)
print(resp.text)
Fails gracefully with a clear error message when OPENAI_API_KEY is not set.
Configuration
Everything is environment-driven (prefix H4CKATH0N_):
| Variable | Default | Description |
|---|---|---|
H4CKATH0N_ENV |
development |
development or production |
H4CKATH0N_DATABASE_URL |
sqlite:///./h4ckath0n.db |
Database connection string |
H4CKATH0N_RP_ID |
localhost (dev only) |
WebAuthn relying party ID (required in production) |
H4CKATH0N_ORIGIN |
http://localhost:8000 (dev only) |
WebAuthn expected origin (required in production) |
H4CKATH0N_WEBAUTHN_TTL_SECONDS |
300 |
Challenge expiry time (seconds) |
H4CKATH0N_USER_VERIFICATION |
preferred |
WebAuthn user verification requirement |
H4CKATH0N_ATTESTATION |
none |
WebAuthn attestation preference |
H4CKATH0N_PASSWORD_AUTH_ENABLED |
false |
Enable password auth routes (requires [password] extra) |
H4CKATH0N_BOOTSTRAP_ADMIN_EMAILS |
[] |
JSON list of emails that get admin role on registration |
H4CKATH0N_FIRST_USER_IS_ADMIN |
false |
First registered user becomes admin (dev convenience) |
OPENAI_API_KEY |
— | OpenAI API key for the LLM module |
In development mode, missing WebAuthn settings generate localhost defaults with warnings.
In production mode, missing RP_ID and ORIGIN cause a hard error.
Observability (opt-in)
Enable end-to-end tracing across FastAPI requests, LangGraph nodes, tool calls, and LLM calls.
Enable LangSmith tracing
LANGSMITH_TRACING=true
LANGSMITH_API_KEY=...
LANGSMITH_PROJECT=your-project-name
Trace IDs
When observability is enabled, h4ckath0n attaches X-Trace-Id to all responses:
from h4ckath0n import create_app
from h4ckath0n.obs import init_observability
app = create_app()
init_observability(app)
Development
git clone https://github.com/BTreeMap/h4ckath0n.git
cd h4ckath0n
uv sync
uv run pytest
Quality gates:
uv run ruff format --check .
uv run ruff check .
uv run mypy src
uv run pytest
Build:
uv build
License
MIT. See LICENSE.
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 h4ckath0n-0.1.1.dev20260210200639.tar.gz.
File metadata
- Download URL: h4ckath0n-0.1.1.dev20260210200639.tar.gz
- Upload date:
- Size: 276.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
49c3b3f0a008da55ca59c7a963abb4d3f847325e59fd3d4bf57894374c57173d
|
|
| MD5 |
d0bbfde9f1c735e19441e0dcc873b2ec
|
|
| BLAKE2b-256 |
81fe48f913bf814904d5b77bafa034bc53688e6e621e0d9e46b04015f9bab16c
|
Provenance
The following attestation bundles were made for h4ckath0n-0.1.1.dev20260210200639.tar.gz:
Publisher:
publish.yml on BTreeMap/h4ckath0n
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
h4ckath0n-0.1.1.dev20260210200639.tar.gz -
Subject digest:
49c3b3f0a008da55ca59c7a963abb4d3f847325e59fd3d4bf57894374c57173d - Sigstore transparency entry: 938291688
- Sigstore integration time:
-
Permalink:
BTreeMap/h4ckath0n@c16baed0c69b3b9b73c0992546c0f18080545704 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BTreeMap
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c16baed0c69b3b9b73c0992546c0f18080545704 -
Trigger Event:
push
-
Statement type:
File details
Details for the file h4ckath0n-0.1.1.dev20260210200639-py3-none-any.whl.
File metadata
- Download URL: h4ckath0n-0.1.1.dev20260210200639-py3-none-any.whl
- Upload date:
- Size: 32.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fb9d4195d79e819fe95f3ce855f4a960bfca6b7d3b4c9ff0db25177dbcf9b324
|
|
| MD5 |
f5fc54f7b0aea7f359881fcb04221697
|
|
| BLAKE2b-256 |
87e38d45b6e41ac4210da7cf598d85a299caed071b966935224f79d6ab71ae81
|
Provenance
The following attestation bundles were made for h4ckath0n-0.1.1.dev20260210200639-py3-none-any.whl:
Publisher:
publish.yml on BTreeMap/h4ckath0n
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
h4ckath0n-0.1.1.dev20260210200639-py3-none-any.whl -
Subject digest:
fb9d4195d79e819fe95f3ce855f4a960bfca6b7d3b4c9ff0db25177dbcf9b324 - Sigstore transparency entry: 938291694
- Sigstore integration time:
-
Permalink:
BTreeMap/h4ckath0n@c16baed0c69b3b9b73c0992546c0f18080545704 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/BTreeMap
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@c16baed0c69b3b9b73c0992546c0f18080545704 -
Trigger Event:
push
-
Statement type: