{"id":48858697,"url":"https://github.com/zccz14/auth-mini","last_synced_at":"2026-04-15T14:12:39.505Z","repository":{"id":348294512,"uuid":"1193413313","full_name":"zccz14/auth-mini","owner":"zccz14","description":"Minimal Authorization and Authentication Modules for Any App. Support Email, WebAuthn (Passkey), Ed25519 (EdDSA) and JWT. Using Hono HTTP Server and SQLite Database","archived":false,"fork":false,"pushed_at":"2026-04-11T18:55:20.000Z","size":1052,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-11T19:11:29.150Z","etag":null,"topics":["authentication","authorization","sqlite"],"latest_commit_sha":null,"homepage":"http://auth-mini.zccz14.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zccz14.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-27T07:38:22.000Z","updated_at":"2026-04-11T18:55:24.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zccz14/auth-mini","commit_stats":null,"previous_names":["zccz14/mini-auth","zccz14/auth-mini"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/zccz14/auth-mini","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zccz14%2Fauth-mini","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zccz14%2Fauth-mini/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zccz14%2Fauth-mini/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zccz14%2Fauth-mini/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zccz14","download_url":"https://codeload.github.com/zccz14/auth-mini/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zccz14%2Fauth-mini/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31844579,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-15T13:28:40.153Z","status":"ssl_error","status_checked_at":"2026-04-15T13:28:29.396Z","response_time":63,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","authorization","sqlite"],"created_at":"2026-04-15T14:12:38.745Z","updated_at":"2026-04-15T14:12:39.488Z","avatar_url":"https://github.com/zccz14.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# auth-mini\n\n\u003e **Authentication** is a critical subsystem to prove who users are, while **Authorization** is another critical subsystem to control what users can do.\n\nMinimal, opinionated authentication server for apps that just need a solid authentication core.\n\n[Live demo](https://auth-mini.zccz14.com/#/setup?auth-origin=https%3A%2F%2Fauth.zccz14.com) | [Docs](docs/) | [GitHub](https://github.com/zccz14/auth-mini)\n\n✅ Good fit for authentication system needs:\n\n- 🔒 Password-less Authentication\n  - 📧 Email One-Time Password (OTP) sign-in\n  - 🔑 Passkey (WebAuthn) sign-in\n  - 🔐 Ed25519 (EdDSA) sign-in for non-browser clients without WebAuthn support\n- 🔄 Session Management\n  - Issue JSON Web Token (JWT) access tokens for backend stateless verification\n  - CURRENT/STANDBY JWKS key pairs for smooth key rotation\n  - Issue opaque refresh tokens for long-term sessions and easy revocation while keeping JWTs short-lived\n- You control the server and data. Not Google. Not AWS. Not Auth0. You.\n  - Simple SQLite storage without extra Database servers (no Postgres, MySQL, Redis, etc. required)\n  - CORS included for accessing from cross-origin front-ends.\n- UUID-based user ID keeps it simple and opaque, and could be foreign keys for your app's user records if you want.\n\n❌ Not trying to include: (But you can build these on top if you want!)\n\n- Authorization features like ACLs, RBAC, ABAC, roles, permissions, groups, etc.\n- Social Login like \"Sign in with Google/Facebook/GitHub/etc.\"\n- SMS or TOTP 2FA factors.\n- User profiles like names, avatars, bios, etc.\n- User management features like admin dashboards, user search etc.\n\n## Main user journeys\n\n### Email OTP sign-in\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor User\n    participant Frontend\n    participant Auth as Auth Mini Server\n\n    User-\u003e\u003eFrontend: Enter email and request sign-in\n    Frontend-\u003e\u003eAuth: POST /email/start\n    Auth--\u003e\u003eUser: Send OTP email\n    User-\u003e\u003eFrontend: Enter OTP\n    Frontend-\u003e\u003eAuth: POST /email/verify\n    Auth--\u003e\u003eFrontend: session_id + access token + refresh token\n    Frontend-\u003e\u003eAuth: GET /me\n    Auth--\u003e\u003eFrontend: Current user + active credentials/sessions\n```\n\n### Passkey registration and sign-in\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor User\n    participant Frontend\n    participant Auth as Auth Mini Server\n\n    Note over User,Auth: Register passkey after email sign-in\n    Frontend-\u003e\u003eAuth: POST /webauthn/register/options\n    Auth--\u003e\u003eFrontend: request_id + publicKey\n    Frontend-\u003e\u003eUser: Browser shows passkey creation prompt\n    User--\u003e\u003eFrontend: Approve with authenticator\n    Frontend-\u003e\u003eAuth: POST /webauthn/register/verify\n    Auth--\u003e\u003eFrontend: Credential saved\n\n    Note over User,Auth: Later sign in with a discoverable passkey\n    Frontend-\u003e\u003eAuth: POST /webauthn/authenticate/options\n    Auth--\u003e\u003eFrontend: request_id + publicKey\n    Frontend-\u003e\u003eUser: Browser/OS shows available passkeys\n    User--\u003e\u003eFrontend: Choose passkey and approve\n    Frontend-\u003e\u003eAuth: POST /webauthn/authenticate/verify\n    Auth--\u003e\u003eFrontend: session_id + access token + refresh token\n```\n\n### Device sign-in with Ed25519 keys\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor User\n    participant Device\n    participant Auth as Auth Mini Server\n\n    Note over User,Device: User may generate an Ed25519 key pair and keep the private key on the device\n    Note over User,Auth: While already signed in via email OTP or passkey\n    Device-\u003e\u003eAuth: POST /ed25519/credentials (public_key)\n    Auth--\u003e\u003eDevice: credential_id\n\n    Note over Device,Auth: Later sign in with the saved private key + credential_id\n    Device-\u003e\u003eAuth: POST /ed25519/start\n    Auth--\u003e\u003eDevice: request_id + challenge\n    Device-\u003e\u003eDevice: Sign challenge with saved private key\n    Device-\u003e\u003eAuth: Complete auth flow with request_id + signature + credential_id\n    Auth-\u003e\u003eAuth: Verify signature with stored public key\n    Auth--\u003e\u003eDevice: Ed25519 session_id + access token + refresh token\n```\n\n### Frontend -\u003e backend -\u003e `/jwks` verification\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor User\n    participant Frontend\n    participant Auth as Auth Mini Server\n    participant Backend\n\n    User-\u003e\u003eFrontend: Complete sign-in\n    Frontend-\u003e\u003eAuth: Login / verify request\n    Auth--\u003e\u003eFrontend: session_id + access token + refresh token\n    Frontend-\u003e\u003eBackend: App API request (Bearer access token)\n    Backend-\u003e\u003eAuth: GET /jwks\n    Auth--\u003e\u003eBackend: Public signing keys\n    Backend-\u003e\u003eBackend: Verify JWT signature and claims\n    Backend--\u003e\u003eFrontend: Protected resource\n```\n\n## Quick Start\n\nPre-requisites:\n\n- Node.js 20.10.0+\n- SMTP service credentials for email OTP. (Most email providers have SMTP options, or you can use transactional email services like SendGrid, Mailgun, etc.)\n\nMinimal CLI setup:\n\n```bash\nnpx auth-mini init ./auth-mini.sqlite\n```\n\nSetup SMTP config:\n\n```bash\nnpx auth-mini smtp add ./auth-mini.sqlite  --from-email 'sample@your-domain.com' --from-name 'sample-name' --host 'smtp.sample.com' --port 465 --secure --username 'sample@your-domain.com' --password '\u003csmtp-password\u003e'\n```\n\nSetup Origin config:\n\n```bash\nnpx auth-mini origin add ./auth-mini.sqlite --value 'https://frontend.your-domain.com'\n```\n\nNo need to add backend API origins.\n\nStart the server:\n\n```bash\nnpx auth-mini start ./auth-mini.sqlite --port 7777 --issuer 'https://auth.your-domain.com'\n```\n\nThen deploy it with Cloudflare Tunnel or your preferred hosting method.\n\nMinimal browser SDK usage:\n\n```ts\nimport { createBrowserSdk } from 'auth-mini/sdk/browser';\n\nconst sdk = createBrowserSdk('https://auth.your-domain.com');\n\nsdk.session.onChange((state) =\u003e {\n  console.log('auth status:', state.status);\n});\n```\n\nMinimal device SDK usage:\n\n```ts\nimport { createDeviceSdk } from 'auth-mini/sdk/device';\n\nconst sdk = createDeviceSdk({\n  serverBaseUrl: 'https://auth.your-domain.com',\n  credentialId: '550e8400-e29b-41d4-a716-446655440000',\n  privateKeySeed: '7rANewlCLceTsUo9feN0DLjnu-ayYsdhkVWvHT4FelM',\n});\n\nawait sdk.ready;\n```\n\nMinimal backend JWT verification (jose example):\n\n```js\nimport { createRemoteJWKSet, jwtVerify } from 'jose';\n\nconst issuer = 'https://auth.your-domain.com';\nconst JWKS = createRemoteJWKSet(new URL(`/jwks`, issuer));\n\nasync function verifyAccessToken(token) {\n  try {\n    const { payload } = await jwtVerify(token, JWKS, { issuer });\n    console.log('Token is valid. Payload:', payload);\n  } catch (err) {\n    console.error('Invalid token:', err);\n  }\n}\n```\n\nFrom there, typical integration looks like this:\n\n- add your app origin with the CLI\n- start auth-mini with your issuer\n- configure SMTP, then sign in via email OTP and optionally register a passkey\n- send the access token to your backend and verify it with `/jwks`\n\n## Docs and next steps\n\n`docs/` is the canonical static reference source. `examples/demo/` is the current interactive demo source and Pages publish target, while the deployed live demo remains the easiest way to try the browser flows end-to-end.\n\n- Device SDK integration: [docs/integration/device-sdk.md](docs/integration/device-sdk.md)\n- Browser SDK integration: [docs/integration/browser-sdk.md](docs/integration/browser-sdk.md)\n- WebAuthn integration: [docs/integration/webauthn.md](docs/integration/webauthn.md)\n- Backend JWT verification: [docs/integration/backend-jwt-verification.md](docs/integration/backend-jwt-verification.md)\n- HTTP API reference: [docs/reference/http-api.md](docs/reference/http-api.md)\n- CLI and operations: [docs/reference/cli-and-operations.md](docs/reference/cli-and-operations.md)\n- Docker + Cloudflared deployment: [docs/deploy/docker-cloudflared.md](docs/deploy/docker-cloudflared.md)\n\nFor the one-container Cloudflare Tunnel path, see [docs/deploy/docker-cloudflared.md](docs/deploy/docker-cloudflared.md). Deployment details live there.\n\n## Philosophy\n\n### Why not a full auth platform?\n\nIf your project only needs authentication, a larger backend platform can be unnecessary overhead. auth-mini focuses on the auth slice so you can keep users, sessions, SMTP config, and signing keys understandable.\n\n### Why email OTP + passkeys?\n\nEmail is familiar and useful for recovery and communication. Passkeys then provide phishing-resistant, username-less sign-in with discoverable credentials instead of another password system.\n\n### Why SQLite?\n\nAuth data is usually small, and operational simplicity matters. SQLite is easy to run, back up, inspect, and move without introducing another server just because auth sounds important.\n\n### Why access + refresh tokens?\n\nAccess tokens stay short-lived and verifiable by APIs through `/jwks`; refresh tokens stay revocable and database-backed. That keeps backend verification simple without pretending leaked JWTs are easy to revoke.\n\n## Development\n\nRun `npm run format`, `npm run lint`, `npm run typecheck`, and `npm test`.\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzccz14%2Fauth-mini","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzccz14%2Fauth-mini","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzccz14%2Fauth-mini/lists"}