Thanks for considering a contribution. ZeroAuth is built in the open and we welcome bug reports, fixes, integrations, and ideas.
- Found a bug? Open an issue.
Include reproduction steps, expected vs. actual behaviour, and your
environment (
node -v, OS, Docker version). - Have a feature in mind? Start a discussion before opening a PR — we'd rather agree on direction first.
- Found a security vulnerability? Do not open a public issue. See SECURITY.md.
git clone https://github.com/zeroauth-dev/ZeroAuth.git
cd ZeroAuth
npm run setup # installs all workspaces, builds everything
cp .env.example .env # local env (uses Base Sepolia testnet by default)
npm test # 45 jest tests should pass
npm run dev # tsx watch mode on :3000For docker-based development:
./scripts/deploy.sh dev # brings up app + Redis + Postgres with hot reloadBefore opening a PR:
-
npm testpasses (45/45 with zero data-storage invariant intact). -
npx tsc --noEmitis clean. - You have not introduced any code path that persists raw biometric data
or proof inputs. The
dataStored: falseinvariant in tests must hold. - No new inline event handlers /
eval/Function()— the production CSP is strict (script-src-attr 'none'). - If you added an endpoint, it has tests and is listed in docs/reference/api-reference.md.
- If you changed an env var, it is documented in .env.example and docs/reference/environment-variables.md.
- Commits are signed-off if you can (
git commit -s).
- TypeScript with
strict: true. Noanywithout a comment explaining why. - Prefer
async/awaitover.thenchains. - Errors flow up to the central
error-handler; don't
try/catchto swallow. - Logs go through the winston logger; don't
console.log. - Solidity changes need a corresponding Hardhat test + redeploy script update.
These are the hills we will die on:
- Zero biometric data persistence. Templates exist in memory only long
enough to compute their SHA-256 / Poseidon commitment, then are
deleted. No code path writes them to disk, DB, or logs. - API keys are never logged or returned after creation. Only the SHA-256 hash is stored; the raw key is shown once.
- Public inputs are bound to nonces. Replay protection is non-optional; verification failures are silent (no oracle leakage).
- All requests are tenant-scoped. No global API state — every read/write includes a tenant ID derived from the API key.
Pull requests that weaken any of these will be rejected.
Tagged on the main branch. We follow SemVer:
MAJOR— breaking API change or removal of an endpoint.MINOR— new endpoints, scopes, or non-breaking flags.PATCH— bug fixes, dependency bumps, doc-only changes.
Thank you for making ZeroAuth better.