{"id":40481859,"url":"https://github.com/e280/authlocal","last_synced_at":"2026-01-20T18:33:20.071Z","repository":{"id":257950632,"uuid":"871521924","full_name":"e280/authlocal","owner":"e280","description":"🔒 user-sovereign login system for everybody","archived":false,"fork":false,"pushed_at":"2026-01-19T10:39:43.000Z","size":1239,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-01-19T17:47:25.615Z","etag":null,"topics":["auth","authentication","user-sovereign"],"latest_commit_sha":null,"homepage":"https://authlocal.org/","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/e280.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2024-10-12T07:37:25.000Z","updated_at":"2025-11-17T09:08:56.000Z","dependencies_parsed_at":"2024-10-25T06:39:38.966Z","dependency_job_id":"d25584ca-673a-4e12-93b2-930e9db4c006","html_url":"https://github.com/e280/authlocal","commit_stats":null,"previous_names":["authduo/authduo","authlocal/authlocal","e280/authlocal"],"tags_count":45,"template":false,"template_full_name":null,"purl":"pkg:github/e280/authlocal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e280%2Fauthlocal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e280%2Fauthlocal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e280%2Fauthlocal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e280%2Fauthlocal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/e280","download_url":"https://codeload.github.com/e280/authlocal/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/e280%2Fauthlocal/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28609120,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T16:10:39.856Z","status":"ssl_error","status_checked_at":"2026-01-20T16:10:39.493Z","response_time":117,"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":["auth","authentication","user-sovereign"],"created_at":"2026-01-20T18:33:19.275Z","updated_at":"2026-01-20T18:33:20.001Z","avatar_url":"https://github.com/e280.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n![](https://i.imgur.com/Ao6piCO.png)\n\n# 🔒 Authlocal\n\n### 👉 https://authlocal.org/ 👈\n\n**Authlocal is a free login system for the web.**  \nAny website you visit can request your login by opening an Authlocal popup, but your identity seed files stay safely local on your device. You can go to the [authlocal.org](https://authlocal.org/) website any time to manage your identities.\n\n- 🗽 **User-sovereign** – you hold your own seed files  \n- 🔑 **Cryptographic** – no emails, no passwords  \n- 🥷 **Privacy-focused** – pseudonymous, device-local, no databases  \n- 💖 **Free and open-source** – zero-cost at global scale  \n\n**Own your identity.**  \nWhen you create an identity, download the seed and keep it safe. The seed *is* the identity. Don't lose it. Don't share it. Never give your seed to another person or website. It's yours, forever.\n\n\n\n\u003cbr/\u003e\u003cbr/\u003e\n\n## 🍋‍🟩 Integration Manual for Web Developers\n\n### Install Authlocal logins into your web app\n1. **Install authlocal and friends via npm**\n    ```sh\n    npm install @e280/authlocal @e280/stz\n    ```\n1. **Javascript to install Authlocal on your page**  \n    ```js\n    import authlocal from \"@e280/authlocal\"\n\n    const {auth} = await authlocal.install({\n      theme: authlocal.themes.basic,\n    })\n\n    auth.on(login =\u003e {\n      if (login) console.log(\"logged in\", login)\n      else console.log(\"logged out\")\n    })\n    ```\n1. **Put these new elements in your html `\u003cbody\u003e`**  \n    ```html\n    \u003cauth-user\u003e\u003c/auth-user\u003e\n    \u003cauth-button\u003e\u003c/auth-button\u003e\n    ```\n1. **Take it for a spin!**  \n    You should be able to login and logout via Authlocal.  \n\n### Logins\n- **Never send the login info anywhere.** Send claims instead!\n- Logins are auto persisted in localStorage for 7 days\n- Anatomy of a `login` object:\n  - `login.sessionId` — id of the login session hex string\n  - `login.nametag.id` — user identity public key hex string\n  - `login.nametag.label` — user's chosen nickname\n  - `login.expiresAt` — js timestamp of when this login expires\n  - `login.isExpired()` — returns true if the login is expired now\n  - `login.signClaim(options)` — sign a claim\n\n### Claims\nThe purpose of a `login`, is that it can sign claims on the user's behalf. You can then send those claims to your server and verify them there. A claim contains a cryptographic proof that it stems from a genuine login session signed by the user's seed.\n\nSpritually, a claim is trying to say something like *\"This user gave permission to this frontend to now say on their behalf:\"*\n- *\"we want to post this message...\"*\n- *\"we want to change their avatar...\"*\n- *\"we want to buy this microtransaction...\"*\n\n#### Sign a claim with a login, on the frontend\n```ts\nimport {Time} from \"@e280/stz\"\n\nconst claimToken = await login.signClaim({\n\n  // any json-friendly data you want\n  claim: {message: \"i love ice cream\"},\n\n  // when should this claim expire?\n  expiresAt: Time.future.hours(24),\n})\n```\n\n#### Verify a claim, on the server\n```ts\nimport {verifyClaim} from \"@e280/authlocal/core\"\n\nconst {claim, proof} = await verifyClaim({\n  claimToken,\n  appOrigins: [\"https://e280.org\"],\n    //                   |\n    //    your website origin goes here\n})\n```\n```ts\nproof.sessionId\n  // id for this login session, looks like:\n  // \"ff730fe2d725aa5210152975212d1068d7fe28ae22b5e62337a4cde42215187a\"\n```\n```ts\nproof.nametag.id\n  // user identity id, looks like:\n  // \"a08263e70a0a48a07e988a7c0931ada6b0a38fa84bf367087b810c614a4c2070\"\n```\n```ts\nproof.nametag.label\n  // user identity nickname, looks like:\n  // \"Michael Scott\"\n```\n\n### Thumbprint\n- **`Thumbprint` is an `@e280/stz` tool for visualizing 64-char ids**\n    ```ts\n    import {Thumbprint} from \"@e280/stz\"\n    ```\n- **id to full thumbprint**\n    ```ts\n    Thumbprint.fromHex(\"005636bab2c73223ccf56f8112432212f57f01ef61452762cd142acd61ed44ed\")\n      // \"dozmut.winpex.linner.forsep.KgisJ8Pdgey1HC4o8cG59NaLYSoRTiHfA\"\n    ```\n- **id to short sigil**\n    ```ts\n    Thumbprint.sigil.fromHex(\"005636bab2c73223ccf56f8112432212f57f01ef61452762cd142acd61ed44ed\")\n      // \"dozmut.winpex\"\n    ```\n- **thumbprint to id**\n    ```ts\n    Thumbprint.toHex(\"dozmut.winpex.linner.forsep.KgisJ8Pdgey1HC4o8cG59NaLYSoRTiHfA\")\n      // \"005636bab2c73223ccf56f8112432212f57f01ef61452762cd142acd61ed44ed\"\n    ```\n\n### Authlocal dev glossary\n- **Authority** — the website that provides login sessions (authlocal.org)\n  - `authorityOrigin` is the provider's origin, eg `https://authlocal.org`\n- **App** — the third party website receiving login sessions (your website)\n  - `appOrigin` is your app origin, eg `https://e280.org`\n- **Keypair** — an ed25519 keypair\n  - `.id` is the public key (64 character hex string)\n  - `.secret` is the private key (64 character hex string)\n- **Identity** — a keypair with a label string\n- **Seed** — text snippet or `.seed` file that stores an identity\n- **Nametag** — the public data associated with a user's identity\n    - `.id` is the public key (64 character hex string)\n    - `.label` is a nickname (max 32 character string)\n- **Thumbprint** — easier-to-read version of an id\n    - `thumbprint` =\u003e `dozmut.winpex.linner.forsep.KgisJ8Pdgey1HC4o8cG59NaLYSoRTiHfA`\n    - `sigil` (first two words) =\u003e `dozmut.winpex`\n    - `preview` (first four words) =\u003e `dozmut.winpex.linner.forsep`\n    - `bulk` (last part) =\u003e `KgisJ8Pdgey1HC4o8cG59NaLYSoRTiHfA`\n- **Login** — a login session\n    - is private, should never leave the user's device\n    - `.nametag` contains the identity's id and label\n    - `.expiresAt` js time of the moment this login expires\n    - `.isExpired()` returns true if the login is now expired\n    - `.signClaim(options)` sign a claim\n- **Proof** — provenance for login\n    - is a token signed by an identity\n    - is public, can be shared around\n    - `.nametag` contains the identity's id and label\n    - `.sessionId` proves a login session is blessed by an identity\n- **Claim** — arbitrary claim your frontend can make\n    - is a token signed by the login session, verifiable on your server\n    - is public, can be shared around\n    - includes the proof token (thus nametag and sessionId)\n    - includes any arbitrary claim data you want\n    - verified by `verifyClaim(options)`\n\n\n\n\u003cbr/\u003e\n\n## 🧑‍💻 Authlocal is an [e280](https://e280.org/) project\nOpen github issues or discussions if you have any questions.  \nStar us on github, it's the only way we're paid.  \nFree and open source.  \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fe280%2Fauthlocal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fe280%2Fauthlocal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fe280%2Fauthlocal/lists"}