Skip to content

B.3: end-to-end LWS10-CID auth — sign-in, ES256K JWK VM, JWT signing #3

@melvincarvalho

Description

@melvincarvalho

B.3 closes the loop: the doctor goes from a read-only diagnostic + key-snippet generator (B.0/B.2) to a fully end-to-end LWS10-CID auth client.

Pairs with JavaScriptSolidServer/JavaScriptSolidServer#397 (server-side LWS10-CID JWT verifier). The two will be developed together so each validates against the other's real output before merging.

What it does

  1. Sign in to the user's pod via Solid-OIDC — using solid-oidc (zero-dep, single 700-line file, ~4kb gzipped, IndexedDB session persistence, DPoP-bound `authFetch`). Imported via esm.sh CDN — no build step.
  2. Derive a JsonWebKey from the connected Nostr signer — same secp256k1 key, recovered to full-point JWK (`kty: EC, crv: secp256k1, x, y, alg: ES256K`). Uses `@noble/secp256k1` via CDN (~10kb) for point recovery.
  3. PATCH a `JsonWebKey` VM into the WebID profile — alongside (not replacing) the f-form Multikey VM from B.2. Both VMs reference the same key from different angles: Multikey for did:nostr / Schnorr-track binding, JsonWebKey for ES256K JWS signing.
  4. Persist the user's Nostr privkey in IndexedDB (initial cut: assumes user enters their nsec; future: NIP-07 doesn't expose ECDSA so signing happens locally). Encrypted-at-rest TBD.
  5. Sign a test LWS10-CID JWT — `alg: ES256K, kid: `, claims `sub === iss === client_id === `, `aud` is the target pod origin, `exp`/`iat` set. ECDSA-sign via `@noble/secp256k1`.
  6. Demo button: hit a protected endpoint on the pod with the JWT in `Authorization: Bearer` — once #397 lands, this should authenticate end-to-end.

Acceptance

  • Sign in via Solid-OIDC works on a JSS pod
  • Profile after PATCH has both the Multikey VM (from B.2) and the new JsonWebKey VM, with controller predicates intact
  • Generated JWT verifies cleanly via a Node test fixture using the same @noble/secp256k1 primitives
  • When JSS#397 is live, clicking "test auth" returns 200 from a protected resource
  • Reverting the PATCH (logout + delete VM) leaves the profile byte-stable

Out of scope

  • Schnorr signing path / NIP-07-only signers (xlogin doesn't expose ECDSA — that's a separate B.x once a NIP-07 extension or browser-side Schnorr-as-JWS exists)
  • LWS10-did:key path (separate, B.4)
  • Encrypted-at-rest privkey storage in IndexedDB (deferred — initial cut leaves this configurable)
  • WebAuthn passkey VM
  • bip340-jcs-2025 Data Integrity proofs (separate; for VC signing, not HTTP auth)

Refs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions