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 a secure FastAPI bootstrap and passkey-first authentication.
What you get
- FastAPI app factory with passkey routes mounted by default
- Device signed ES256 JWT authentication and server-side RBAC (user, admin, scopes)
- SQLAlchemy 2.x models with automatic table creation on startup
- LLM wrapper around the OpenAI SDK with timeouts and retries
- Optional password auth extra for email and password flows
- Optional Redis extra that only adds the dependency, no integration is provided yet
- Trace ID middleware and LangSmith environment wiring via
init_observability - Full stack scaffold CLI that produces an API and web template
Installation
Recommended (uv)
uv add h4ckath0n
Optional extras:
uv add "h4ckath0n[password]" # Argon2 based password auth
uv add "h4ckath0n[redis]" # Redis dependency only
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
OpenAPI docs
- Interactive docs live at
/docswhen the app is running. - Public routes like passkey start and finish work without auth.
- Protected routes require an
Authorization: Bearer <device_jwt>header that the web template can mint after login.
Built-in routes
GET /— welcome message confirming the app is reachable.GET /health— returns{"status": "healthy"}for load balancer and deployment checks.
Session
GET /auth/session— returns the current user session details.
Background Jobs
GET /jobs— list jobs.POST /jobs— enqueue a background job.GET /jobs/{job_id}— get the status and result of a job.
Uploads
GET /uploads— list uploaded files.POST /uploads— upload a new file.GET /uploads/{upload_id}— get metadata for a specific upload.GET /uploads/{upload_id}/download— download the uploaded file.
LLM Chat
POST /llm/chat— send a message to the language model.POST /llm/chat/stream— stream responses from the language model.
Auth model
Passkeys by default
The default authentication path uses passkeys (WebAuthn). The core flows are:
POST /auth/passkey/register/startandPOST /auth/passkey/register/finishPOST /auth/passkey/login/startandPOST /auth/passkey/login/finishPOST /auth/passkey/add/startandPOST /auth/passkey/add/finishfor adding devicesGET /auth/passkeys,POST /auth/passkeys/{key_id}/revoke, andPATCH /auth/passkeys/{key_id}for management
Device signed JWTs
After login or registration, the client binds a device key and mints short lived ES256
JWTs. The server uses the kid header to load the device public key and verifies the
signature and aud claim. JWTs contain only identity and time claims, no roles or
scopes.
ID scheme
- User IDs are 32 characters and start with
u - Passkey IDs are 32 characters and start with
k - Device IDs are 32 characters and start with
d - Password reset tokens use UUID hex, not the base32 scheme
Secure endpoint protection
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 permissions:
from h4ckath0n.auth import require_scopes
@app.post("/billing/refund")
def refund(user=require_scopes("billing:refund")):
return {"status": "queued"}
Password auth (optional)
Password routes mount only when the password extra is installed and
H4CKATH0N_PASSWORD_AUTH_ENABLED=true.
POST /auth/registerPOST /auth/loginPOST /auth/password-reset/requestPOST /auth/password-reset/confirm
Password auth is only an identity bootstrap. It binds a device key but does not return access tokens, refresh tokens, or cookies.
Configuration
All settings use the H4CKATH0N_ prefix unless noted.
| Variable | Default | Description |
|---|---|---|
H4CKATH0N_ENV |
development |
development or production |
H4CKATH0N_DATABASE_URL |
sqlite:///./h4ckath0n.db |
SQLAlchemy connection string |
H4CKATH0N_AUTO_UPGRADE |
false |
Auto-run packaged DB migrations to head on startup |
H4CKATH0N_RP_ID |
localhost in development |
WebAuthn relying party ID, required in production |
H4CKATH0N_ORIGIN |
http://localhost:8000 in development |
WebAuthn origin, required in production |
H4CKATH0N_WEBAUTHN_TTL_SECONDS |
300 |
WebAuthn challenge TTL in seconds |
H4CKATH0N_USER_VERIFICATION |
preferred |
WebAuthn user verification requirement |
H4CKATH0N_ATTESTATION |
none |
WebAuthn attestation preference |
H4CKATH0N_PASSWORD_AUTH_ENABLED |
false |
Enable password routes when the extra is installed |
H4CKATH0N_PASSWORD_RESET_EXPIRE_MINUTES |
30 |
Password reset token expiry in minutes |
H4CKATH0N_BOOTSTRAP_ADMIN_EMAILS |
[] |
JSON list of emails that become admin on password signup |
H4CKATH0N_FIRST_USER_IS_ADMIN |
false |
First password signup becomes admin |
OPENAI_API_KEY |
empty | OpenAI API key for the LLM wrapper |
H4CKATH0N_OPENAI_API_KEY |
empty | Alternate OpenAI API key for the LLM wrapper |
In development, missing RP_ID and ORIGIN fall back to localhost defaults with
warnings. In production, missing values raise a runtime error when passkey flows start.
Postgres readiness and migrations
Set a Postgres database URL to run against Postgres:
H4CKATH0N_DATABASE_URL=postgresql+psycopg://user:pass@host:5432/dbname
create_app() calls Base.metadata.create_all on startup.
h4ckath0n also ships an operator CLI and packaged Alembic migrations:
h4ckath0n db ping
h4ckath0n db migrate upgrade --to head --yes
If startup or db ping reports that the database schema is behind, run:
h4ckath0n db migrate upgrade --to head --yes
If startup or db ping reports that the database was initialized without Alembic versioning,
run:
h4ckath0n db migrate stamp --to <baseline> --yes
h4ckath0n db migrate upgrade --to head --yes
For legacy create_all deployments in current releases, use <baseline>=head.
LLM usage
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)
The wrapper raises a RuntimeError if no API key is configured.
Observability
init_observability(app) adds an X-Trace-Id header to responses and can set
LangSmith environment variables if ObservabilitySettings.langsmith_tracing is true.
It does not instrument FastAPI, LangChain, or OpenAI calls by itself.
from h4ckath0n import create_app
from h4ckath0n.obs import ObservabilitySettings, init_observability
app = create_app()
init_observability(app, ObservabilitySettings(langsmith_tracing=True))
Compatibility and operational notes
- Passkeys require HTTPS in production.
localhostis allowed for development. H4CKATH0N_RP_IDmust match your production domain andH4CKATH0N_ORIGINmust include the scheme and host.- The last active passkey cannot be revoked. Add a second passkey first.
Development
git clone https://github.com/BTreeMap/h4ckath0n.git
cd h4ckath0n
uv sync --locked --all-extras
Quality gates:
uv run --locked ruff format --check .
uv run --locked ruff check .
uv run --locked mypy src
uv run --locked pytest -v
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.10.dev20260417.tar.gz.
File metadata
- Download URL: h4ckath0n-0.1.10.dev20260417.tar.gz
- Upload date:
- Size: 407.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a7a86f8279d4d92527d4b41be14009469f6929eacd9597c570d7197a8c60260
|
|
| MD5 |
52a073e1fcc06e2bf0ef0282d9ddcded
|
|
| BLAKE2b-256 |
461c6accef17bd2ce5ded8df3c3486b906af939aec60125362e2c2882a98ff86
|
Provenance
The following attestation bundles were made for h4ckath0n-0.1.10.dev20260417.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.10.dev20260417.tar.gz -
Subject digest:
5a7a86f8279d4d92527d4b41be14009469f6929eacd9597c570d7197a8c60260 - Sigstore transparency entry: 1325585342
- Sigstore integration time:
-
Permalink:
BTreeMap/h4ckath0n@ac4900929710a6f6832958c4235dd2869adc7281 -
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@ac4900929710a6f6832958c4235dd2869adc7281 -
Trigger Event:
schedule
-
Statement type:
File details
Details for the file h4ckath0n-0.1.10.dev20260417-py3-none-any.whl.
File metadata
- Download URL: h4ckath0n-0.1.10.dev20260417-py3-none-any.whl
- Upload date:
- Size: 72.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5807019d149c50fcb34d7836aecb7b1faff51245295b0bd76289a341f59e3a41
|
|
| MD5 |
1a345537942b1c4632992842dbfe46e2
|
|
| BLAKE2b-256 |
d166888cd7436a304c0e23a7a7f6fba2c9a0825eaed339746e85586cf1da0e67
|
Provenance
The following attestation bundles were made for h4ckath0n-0.1.10.dev20260417-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.10.dev20260417-py3-none-any.whl -
Subject digest:
5807019d149c50fcb34d7836aecb7b1faff51245295b0bd76289a341f59e3a41 - Sigstore transparency entry: 1325585438
- Sigstore integration time:
-
Permalink:
BTreeMap/h4ckath0n@ac4900929710a6f6832958c4235dd2869adc7281 -
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@ac4900929710a6f6832958c4235dd2869adc7281 -
Trigger Event:
schedule
-
Statement type: