{"id":44312096,"url":"https://github.com/fells-code/seamless-auth-api","last_synced_at":"2026-06-01T05:00:54.413Z","repository":{"id":336793735,"uuid":"1147043346","full_name":"fells-code/seamless-auth-api","owner":"fells-code","description":"Seamless Auth is an open source passwordless authentication API","archived":false,"fork":false,"pushed_at":"2026-05-23T23:16:30.000Z","size":596,"stargazers_count":2,"open_issues_count":11,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-05-23T23:22:50.904Z","etag":null,"topics":["passwordless","passwordless-authentication","seamlessauth"],"latest_commit_sha":null,"homepage":"https://seamlessauth.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fells-code.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":"@fells-code"}},"created_at":"2026-02-01T05:04:03.000Z","updated_at":"2026-05-23T22:55:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fells-code/seamless-auth-api","commit_stats":null,"previous_names":["fells-code/seamless-auth-api"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/fells-code/seamless-auth-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fells-code%2Fseamless-auth-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fells-code%2Fseamless-auth-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fells-code%2Fseamless-auth-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fells-code%2Fseamless-auth-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fells-code","download_url":"https://codeload.github.com/fells-code/seamless-auth-api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fells-code%2Fseamless-auth-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33760658,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["passwordless","passwordless-authentication","seamlessauth"],"created_at":"2026-02-11T04:12:28.440Z","updated_at":"2026-06-01T05:00:54.403Z","avatar_url":"https://github.com/fells-code.png","language":"TypeScript","funding_links":["https://github.com/sponsors/@fells-code"],"categories":[],"sub_categories":[],"readme":"# Seamless Auth API\n\n![coverage](resources/coverage-badge.svg)\n[![Publish Docker Image](https://github.com/fells-code/seamless-auth-api/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/fells-code/seamless-auth-api/actions/workflows/docker-publish.yml)\n\n**Seamless Auth API** is the open-source core authentication server for SeamlessAuth: an exclusively passwordless authentication system designed for modern web applications.\n\nIt provides the backend services for passkeys (WebAuthn) and other passwordless flows, issuing secure sessions and tokens while giving teams full transparency into how authentication is implemented.\n\n\u003e Looking for the managed experience (hosting, upgrades, dashboards, metrics, backups, SLAs)? See **https://seamlessauth.com** for managed services.\n\n## Scope and Non-Goals\n\nSeamless Auth API is the **open-source authentication engine** that powers SeamlessAuth. Its goal is to provide secure, auditable, and self-hostable passwordless authentication primitives.\n\nThis repository intentionally focuses on **authentication only**.\n\n### What this repository includes\n\n- Passwordless authentication flows (e.g. passkeys, OTP where configured)\n- Optional OAuth login through configured external identity providers\n- Secure session and token handling\n- User registration and authentication APIs\n- WebAuthn / Passkeys support\n- WebAuthn PRF-capable passkey primitives for browser-local key derivation\n- JWKS and token verification endpoints\n- Database models and migrations required for auth\n- Local development and self-hosting support\n\nEverything in this repository can be:\n\n- Audited\n- Modified\n- Self-hosted\n- Run without any SeamlessAuth-managed services\n\n### What this repository does **not** include\n\nThe following are **intentionally out of scope** and are part of the managed SeamlessAuth service:\n\n- Admin portal or dashboard UI\n- Billing, subscriptions, or plan enforcement\n- Tenant provisioning or lifecycle management\n- Hosted metrics, analytics, or usage dashboards\n- Managed secrets storage or key rotation services\n- Automated upgrades, backups, or restore tooling\n- Managed email or SMS services. The API can send directly through configured provider adapters or\n  return external-delivery payloads to a trusted server adapter, but SeamlessAuth Managed handles the\n  operated delivery service.\n- Support SLAs or operational monitoring\n\nSelf-hosted users are free to implement any of the above on their own, but they are not required to use SeamlessAuth Managed Service.\n\n### About secrets and infrastructure\n\nSeamless Auth API expects secrets to be provided by the environment or by a user-supplied secret store.\n\nThis repository does **not** assume any specific cloud provider, billing system, or control plane.\n\n## Why Seamless Auth API\n\n- Passwordless-first design (no passwords to steal)\n- Bearer/JSON auth API with opaque refresh tokens and signed access tokens\n- WebAuthn / passkeys support\n- Optional WebAuthn PRF support for products that need browser-local key material\n- JWKS publication for access-token verification and separate service-token guards for trusted\n  server adapters\n- Built for inspection, auditability, and self-hosting\n\nThis repository contains **only the auth server**. The admin portal, billing system, and hosted control plane are proprietary and offered as a managed service.\n\n## Who this is for\n\n- Teams that want to **self-host** authentication infrastructure\n- Security-conscious organizations that require code transparency\n- Developers evaluating SeamlessAuth internals before using the hosted offering\n\nIf you want hosted auth with a full control plane and operational support, use the managed service instead.\n\n## High-level architecture\n\n- Auth server (this repository)\n- Postgres for persistence\n- Your application integrates via:\n  - SeamlessAuth server SDK (recommended)\n  - Direct HTTP APIs (advanced)\n\n## Bearer Token Contract\n\nSeamless Auth API returns JSON tokens instead of browser auth cookies.\n\n- Pre-auth flows return an ephemeral `token`; send it as `Authorization: Bearer \u003ctoken\u003e` to routes\n  marked as ephemeral-authenticated, such as OTP, magic-link, and WebAuthn continuation routes.\n- Completed login, registration, OAuth, TOTP, passkey, and refresh flows return an access `token`;\n  send it as `Authorization: Bearer \u003ctoken\u003e` to access-authenticated routes.\n- Refresh uses the opaque `refreshToken` value, not the access token.\n- Internal service tokens remain separate. They are used only by explicitly service-token-protected\n  paths or headers such as external delivery support, not as user access or ephemeral bearer tokens.\n\n---\n\n## Local Development Quickstart\n\n### Prerequisites\n\n- Node.js (LTS recommended)\n- Postgres (local, Docker, or managed)\n\n### Configuration\n\nCopy the `.env.example` to an `.env` file and populate values for your local environment.\n\nNever commit real secrets. Use `.env.example` for documentation.\n\nFor a default local Postgres instance, `.env.example` expects:\n\n```text\nDB_HOST=localhost\nDB_PORT=5432\nDB_NAME=seamless_auth\nDB_USER=myuser\nDB_PASSWORD=mypassword\n```\n\n### Run Locally\n\n```bash\nnpm install\nnpm run migrate:up\nnpm run dev\n```\n\nThe server starts on `http://localhost:5312` by default.\n\nVerify it:\n\n```bash\ncurl http://localhost:5312/health\n```\n\nIn development, OpenAPI is available at `http://localhost:5312/openapi.json` and Swagger UI is\navailable at `http://localhost:5312/docs`.\n\n### WebAuthn PRF\n\nSeamlessAuth can request PRF-capable passkeys and PRF assertions without ever receiving PRF output.\nSee [docs/webauthn-prf.md](./docs/webauthn-prf.md) for API usage, browser limitations, SDK\ncontract guidance, and local key-material handling rules.\n\n### Login Method Policy\n\nAdministrators can control which methods may continue after `/login` creates a pre-authenticated\nsession. Configure `LOGIN_METHODS` with any of `passkey`, `magic_link`, `email_otp`, `phone_otp`,\nor `oauth`. The default is `passkey,magic_link`.\n\nSet `PASSKEY_LOGIN_FALLBACK_ENABLED=false` when passkey-capable sessions should continue with\npasskeys only. When fallback is enabled, `/login` returns `loginMethods` so clients can show only\nthe allowed continuations for that user and device.\n\n### OAuth Login\n\nOAuth support lets adopters offer login with external providers such as Google, GitHub, Facebook,\nor any compatible provider that supports an authorization-code exchange and a userinfo endpoint.\nSeamless Auth still issues the final SeamlessAuth session. Provider access tokens are used only\nduring the callback to fetch the profile; they are not logged, stored, returned to clients, or\nincluded in API responses.\n\nEnable OAuth by adding `oauth` to `LOGIN_METHODS` and configuring `oauth_providers` in\n`system_config` or the `OAUTH_PROVIDERS` environment variable. `OAUTH_PROVIDERS` is JSON. Secrets\nare referenced by environment variable name through `clientSecretEnv`; do not put client secrets in\nsystem config.\n\n```json\n[\n  {\n    \"id\": \"google\",\n    \"name\": \"Google\",\n    \"enabled\": true,\n    \"clientId\": \"google-oauth-client-id\",\n    \"clientSecretEnv\": \"GOOGLE_CLIENT_SECRET\",\n    \"authorizationUrl\": \"https://accounts.google.com/o/oauth2/v2/auth\",\n    \"tokenUrl\": \"https://oauth2.googleapis.com/token\",\n    \"userInfoUrl\": \"https://openidconnect.googleapis.com/v1/userinfo\",\n    \"scopes\": [\"openid\", \"email\", \"profile\"],\n    \"redirectUri\": \"https://app.example.com/oauth/callback\",\n    \"redirectUris\": [\"https://app.example.com/oauth/callback\"],\n    \"subjectJsonPath\": \"sub\",\n    \"emailJsonPath\": \"email\",\n    \"emailVerifiedJsonPath\": \"email_verified\",\n    \"nameJsonPath\": \"name\",\n    \"allowSignup\": true,\n    \"accountLinking\": \"email\",\n    \"requireEmailVerified\": true\n  }\n]\n```\n\nThe browser/client flow is:\n\n1. `GET /oauth/providers` returns enabled public provider metadata.\n2. `POST /oauth/:providerId/start` returns a signed `state` and provider `authorizationUrl`.\n3. The browser redirects to `authorizationUrl`.\n4. The provider redirects back to your `redirectUri` with `code` and `state`.\n5. The client posts `{ code, state }` to `POST /oauth/:providerId/callback`.\n6. Seamless Auth validates state, exchanges the code, fetches userinfo, links or creates the local\n   user, and issues the normal SeamlessAuth access/refresh JSON payload.\n\nExample direct API start request:\n\n```bash\ncurl -X POST http://localhost:5312/oauth/google/start \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"redirectUri\": \"http://localhost:5173/oauth/callback\",\n    \"returnTo\": \"http://localhost:5173/dashboard\"\n  }'\n```\n\nExample callback request after the provider redirects back:\n\n```bash\ncurl -X POST http://localhost:5312/oauth/google/callback \\\n  -H 'Content-Type: application/json' \\\n  -d '{\n    \"code\": \"provider-authorization-code\",\n    \"state\": \"signed-state-from-start\"\n  }'\n```\n\nSecurity notes:\n\n- OAuth `state` is signed and expires after a short window.\n- `redirectUri` must exactly match a provider `redirectUris` entry when configured. Providers\n  without a redirect allowlist fall back to trusted configured origins.\n- `returnTo` must match configured `origins`.\n- OIDC providers that request the `openid` scope receive a nonce bound into the signed state.\n- Provider access tokens are never persisted.\n- OAuth identities are stored as provider id + provider subject in `oauth_identities`.\n- Existing users are linked by email only when `accountLinking` is `email`; set\n  `accountLinking: \"disabled\"` to require an existing provider identity.\n- New users are created only when `allowSignup` is enabled for that provider.\n- Set `requireEmailVerified: true` for providers that expose a reliable email verification claim.\n\n### Lockout Policy\n\n`LOCKOUT_POLICY` configures account lockout for identified users after repeated failed login\nattempts. The value is JSON and is also manageable through `system_config`:\n\n```json\n{\n  \"enabled\": true,\n  \"maxFailures\": 10,\n  \"windowSeconds\": 900,\n  \"lockoutSeconds\": 900\n}\n```\n\nLockout is checked after Seamless Auth has identified the target user. Keep route-level rate limits\nenabled for unknown identifiers, OTP delivery abuse, and broad IP pressure.\n\n### Admin-Assisted Device Replacement\n\nAdministrators with write access can prepare an account for device replacement with:\n\n```http\nPOST /admin/users/:userId/recovery/device-replacement\n```\n\nThe endpoint requires a fresh step-up session and can revoke active sessions, remove registered\npasskeys, and disable enabled TOTP credentials. It returns counts only; it never returns secrets,\ncredential private material, TOTP secrets, or recovery codes.\n\n### Sensitive Data Redaction\n\nSeamlessAuth redacts sensitive data from logs and auth-event metadata by default. This includes\ntokens, OTPs, magic-link URLs, PRF salts and outputs, OAuth codes/state, bearer credentials,\nconfigured secrets, email/phone fields inside audit snapshots, and legacy event metadata returned\nthrough admin endpoints.\n\nDelivery payloads that contain OTPs or magic-link/bootstrap tokens are returned only when callers\nexplicitly request external delivery with `x-seamless-auth-delivery-mode: external`. In production,\nexternal delivery also requires a valid `x-seamless-service-token` from a trusted server adapter.\nDevelopment-only bootstrap token details require `x-seamless-auth-include-sensitive: true` and are\nnever enabled in production.\n\nAdmin and user endpoints use explicit minimized response schemas. They do not return WebAuthn\npublic keys, refresh-token hashes/lookups, challenge context, verification tokens, PRF output, TOTP\nsecrets, or provider tokens.\n\n### Scoped Roles\n\nGlobal roles may be plain names such as `admin` or scoped names such as `admin:read` and\n`admin:write`. The legacy `admin` role remains a broad administrator role and grants both scoped\nadmin checks. `admin:write` also satisfies `admin:read`; `admin:read` does not satisfy write checks.\n\nUse `available_roles` to publish the assignable role catalog and `default_roles` for new users.\nRole names may contain letters, numbers, and hyphens, with optional colon-separated scope segments.\nWhitespace, underscores, slashes, and backslashes are rejected.\n\nAdmin routes are split by intent:\n\n- read routes accept `admin`, `admin:read`, or `admin:write`\n- write routes accept `admin` or `admin:write`\n- plain `admin` checks remain exact for backwards compatibility\n\n---\n\n# Docker Quickstart\n\nThis is the fastest way to run **Seamless Auth API** locally using Docker.\n\n---\n\n## Prerequisites\n\n- Docker (Docker Desktop or Docker Engine)\n- A running PostgreSQL instance (local or Docker)\n\n---\n\n## 1. Pull the public image\n\n```bash\ndocker pull ghcr.io/fells-code/seamless-auth-api:latest\n```\n\nAvailable tags:\n\n- `latest` – latest stable release\n- `nightly` – latest build from `main`\n- `vX.Y.Z` – specific versioned releases\n\n---\n\n## 2. Create an environment file\n\nCopy the example and adjust as needed:\n\n```bash\ncp .env.example .env\n```\n\n⚠️ Do not commit `.env` files. They are ignored by default.\n\n---\n\n## 3. Run PostgreSQL (example with Docker)\n\nIf you do not already have Postgres running:\n\n```bash\ndocker network create seamless-auth-local\n\ndocker run -d \\\n  --name seamless-auth-postgres \\\n  --network seamless-auth-local \\\n  -e POSTGRES_USER=myuser \\\n  -e POSTGRES_PASSWORD=mypassword \\\n  -e POSTGRES_DB=seamless_auth \\\n  -p 5432:5432 \\\n  postgres:16\n```\n\nThe one-off migration command and API container below override `DB_HOST` to the Docker network name.\n\n## 4. Run database migrations\n\nRun migrations before the first boot and after upgrades that include migrations:\n\n```bash\ndocker run --rm \\\n  --env-file .env \\\n  --network seamless-auth-local \\\n  -e DB_HOST=seamless-auth-postgres \\\n  ghcr.io/fells-code/seamless-auth-api:latest \\\n  npm run migrate:up\n```\n\n## 5. Run Seamless Auth Server\n\n```bash\ndocker run --rm \\\n  --env-file .env \\\n  --network seamless-auth-local \\\n  -e DB_HOST=seamless-auth-postgres \\\n  -p 5312:5312 \\\n  ghcr.io/fells-code/seamless-auth-api:latest\n```\n\nThe server will:\n\n- Validate required environment variables\n- Start on port `5312`\n- Expose health and authentication endpoints\n\n## 6. Verify it is running\n\n```bash\ncurl http://localhost:5312/health\n```\n\nYou should receive a healthy response.\n\n## Notes for self-hosting\n\n- Secrets are provided via environment variables\n- Development keys can be generated automatically; production signing keys should be generated,\n  rotated, and mounted or provided through environment-backed secret management\n- This image contains only the open-source authentication server\n- No admin portal, billing, or managed infrastructure is included\n\nFor production deployments:\n\n- Use HTTPS\n- Use a trusted server adapter or backend when exposing auth flows to browsers\n- Rotate signing keys\n- Back up your database\n- Monitor authentication failures\n- Treat `system_config` values as runtime configuration, not a secret store\n\nSee [docs/production-operations.md](./docs/production-operations.md) for key, secret, rotation,\nlockout, and deployment guidance.\n\n## Prefer not to self-host?\n\nSeamlessAuth managed services provides a fully managed experience built on top of this same open-source core, including hosting, upgrades, dashboards, backups, and SLAs.\n\n## Production notes\n\nAuthentication infrastructure is security-sensitive.\n\nFor production deployments:\n\n- Use HTTPS end-to-end\n- Keep access and refresh tokens out of browser-readable storage. This API does not set or read\n  browser auth cookies; browser-facing apps should integrate through a trusted server adapter or\n  backend.\n- Restrict CORS origins\n- Rotate signing keys and secrets regularly\n- Enable database backups and test restores\n- Monitor auth failures and suspicious behavior\n- Treat `system_config` values as runtime configuration, not a secret store\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## Public Docs\n\n- [AGENTS.md](./AGENTS.md) for a fast codebase briefing aimed at coding agents and maintainers\n- [docs/architecture.md](./docs/architecture.md) for runtime structure and request flow\n- [docs/oauth.md](./docs/oauth.md) for OAuth provider setup and security behavior\n- [docs/webauthn-prf.md](./docs/webauthn-prf.md) for PRF-capable passkey usage\n- [docs/admin-operations.md](./docs/admin-operations.md) for scoped admin and recovery operations\n- [docs/production-operations.md](./docs/production-operations.md) for production deployment guidance\n\n## Security\n\n**Do not open public issues for security vulnerabilities.**\n\nEmail: security@seamlessauth.com  \nInclude reproduction steps, affected versions, and impact if known.\n\n## License\n\nLicensed under **GNU Affero General Public License v3.0 (AGPL-3.0-only)**.\n\nIf you want to embed Seamless Auth Server into a proprietary product or offer it as a managed service without AGPL obligations, commercial licenses may be available.\n\nContact: support@seamlessauth.com\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffells-code%2Fseamless-auth-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffells-code%2Fseamless-auth-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffells-code%2Fseamless-auth-api/lists"}