Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

904 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

any website can ask you to sign-in with authlocal.
manage identities on your device any time at authlocal.org.

Β  πŸ”‘ cryptographic. passwordless, emailless, provable.
Β  πŸ—½ user-sovereign. copy your keys as you wish.
  🏑 local-only. fully clientside, keys live on your device.
Β  πŸ₯· pseudonymous. no need for personal information.
Β  πŸ’– free and open-source. protocol, not product.

own your identity.
each identity is recoverable from a permanent seed code.
don't lose it. don't share it. it's yours, forever.

websites never see your seed code.
they only see crypto-proof of the identity you selected.

"keep it secret. keep it safe."
Β  Β  β€” gandalf, fellowship of the ring



πŸ” installation for web developers

see the https://authlocal.org/demo/

πŸ‹β€πŸŸ© basic logins for your website

  1. install and import @e280/authlocal.
    npm install @e280/authlocal
    import {Auth} from "@e280/authlocal"
  2. create the auth facility.

    see auth.ts.
    see default-auth-options.ts.

    const auth = new Auth()
  3. react to user session changes.

    see user.ts.
    auth.user is compatible with @e280/strata.

    auth.on(user => console.log(
      user
        ? `logged in: ${user.id}`
        : `logged out`
    ))
  4. start by remembering a previous user session.
    await auth.remember()
  5. perform a login flow with authlocal.

    call this from a button click, or you'll get popup blocked.
    see session-options.ts.

    await auth.loginViaPopup()
  6. logout immediately.
    await auth.logout()

πŸ‹β€πŸŸ© web components

  • the widget has a little login/logout ux, if you like.

    it's the widget you see at https://authlocal.org/demo/
    @e280/sly view exported as Widget.

    import {makeAuthWidget} from "@e280/authlocal"
    
    customElements.define("auth-widget", makeAuthWidget(auth))
    then you put this html on your page:
    <auth-widget>Sign in</auth-widget>

πŸ‹β€πŸŸ© end-to-end encryption for the user

  • encrypt.ts
    const original = new Uint8Array([0xDE, 0xAD, 0xBE, 0xEF])
    const ciphertext = user.encrypt(original)
  • decrypt.ts
    const cleartext = user.decrypt(ciphertext)

πŸ‹β€πŸŸ© sign and verify claims for the user

  • sign a claim token, containing any data you like.

    see options.ts.

    const token = user.signClaim({myAction: "getMyInfo"})
  • verify a claim token, on your server or elsewhere. (note the import path)

    see claim/verifications.ts.

    import {verifyClaim} from "@e280/authlocal/core"
    
    // we verify that the data was signed by a valid delegate
    const {claim, proof} = verifyClaim(token, {
    
      // your frontend app origin (required)
      allowedIssuers: ["https://app.e280.org"],
    })
    
    console.log(claim)
      // {myAction: "getMyInfo"}
    
    console.log(proof.id) // user id
      // "efe064a4ed1ec1763293612627424c0721b82acd009fc666e6915d8edcfe89e6"

πŸ‹β€πŸŸ© address for friendly names

  • address(id) -- encode a user id hex into a friendly format.
    import {address} from "@e280/authlocal"
    address("efe064a4ed1ec1763293612627424c0721b82acd009fc666e6915d8edcfe89e6")
      // "calwak_curlex_H9Nts5YRurzidb8mQHkHH323mMT8d3oReimRzxeLgwRw"
  • addressId(addr) -- decode an address back into a user id.
  • addressEmoji(id) -- derive a friendly emoji from a user id.
  • addressColor(id) -- derive a css color string from a user id.
  • addressMoniker(id) -- get the first part of the address.

πŸ‹β€πŸŸ© mocks for testing

  • produce a mock auth facility that generates a random fake user.
    import {MockAuth, mockUser, mockOrigin} from "@e280/authlocal"
    const auth = new MockAuth()
    await auth.loginViaPopup()
    • MockAuth doesn't touch localstorage etc.
    • mockUser generates a fake user.
    • mockOrigin is the string "https://e280.org".



πŸ” questions and answers

🫐 how local is authlocal?

  • https://authlocal.org/ is a fully-static clientside single-page application that operates without any remote services or databases.
  • despite being totally clientside, authlocal acts as a federated identity provider for third-party websites, communicating cross-origin via popup postmessage api.

🫐 what's really going on, cryptographically?

  • authlocal depends on paul miller's noble cryptography libraries.
  • every authlocal identity is an ed25519 keypair. we call the private key a secret, and the public key an id.
  • third-party websites open a popup to authlocal and ask for "delegates", which are ed25519 keypairs derived from the user's secret key (and also bound to the app origin and provided purpose and scope).
  • a delegate comes with a "proof" token signed by the user secret, which includes the user id and proves that the delegate is legitimate.
  • a delegate can sign new "claim" tokens on behalf of the user, which include the proof token, and thus have a verifiable chain-of-custody back to the user. claims can contain any arbitrary data (such as a request like "read my private profile"), which a third-party server can verify.
  • in the default standard login flow, websites ask for two delegates: one ephemeral "auth" delegate that expires in 30 days, and one stable "crypt" delegate with a secret for end-to-end encryption.

🫐 why not passkeys?

  • unlike passkeys, authlocal lets you see your seed. you can put it on paper.
  • passkeys have a pairwise design with separate credentials for each app. instead, authlocal lets users carry a stable identity across apps. it's a tradeoff.
  • in the future, authlocal might use passkeys as another way to recover identities.



https://e280.org/

Releases

Used by

Contributors

Languages