Phase 2A of #4 ("Add did:nostr SSO and Schnorr (NIP-98) authentication"), redirected onto the CID-document substrate that #386 + #397 just landed.
Problem
Today's NIP-98 path (src/auth/nostr.js) authenticates a request as did:nostr:<pubkey>. WAC then operates on that DID-shaped identity — useful for direct-did:nostr-in-ACL, but it doesn't give the user their WebID as the authenticated identity, so writes to their own profile fail unless ACLs explicitly grant did:nostr:.
#4's original Phase 2A solved this with owl:sameAs linking in the profile + a dedicated SSO endpoint. With the verificationMethod / authentication infrastructure now in place (#386 + #397/#398), there's a smaller, more uniform alternative: the same K→W lookup the LWS-CID verifier already does.
Proposed change
Augment verifyNostrAuth so that, on a successful Schnorr verification:
- Compute the resource WebID (from the request's pod / WebID URL — same logic the WAC layer already uses).
- Fetch that WebID's profile.
- Look for a
verificationMethod whose publicKeyMultibase decodes to the same Nostr pubkey we just verified, and whose VM id is referenced by authentication.
- If found → return the WebID as the authenticated identity (instead of
did:nostr:).
- If not found → return
did:nostr:<pubkey> as today (no behaviour regression).
Decode of the f-form Multikey is straightforward — strip f prefix, strip e701 multicodec, strip parity byte, take the remaining 32-byte x-only hex. The doctor's B.2 (already shipped) emits exactly this shape.
Acceptance
Why this and not the original Phase 2A design
The original design was independent of CID: link via owl:sameAs, build a dedicated SSO endpoint. With CID v1 + LWS10-CID now load-bearing for keys-in-profiles, going through the same VM mechanism:
Out of scope
- Phase 2B (Nostr-first registration with auto-pod-create) — orthogonal
- Phase 3 (relay discovery / NIP-97) — orthogonal
- The dedicated
/idp/nostr-login endpoint — separate, can be layered on top later
- The CCG f-form vs z-form Multikey debate — already settled at f-form per w3c-ccg/community#254; this issue assumes f-form
Refs
Phase 2A of #4 ("Add did:nostr SSO and Schnorr (NIP-98) authentication"), redirected onto the CID-document substrate that #386 + #397 just landed.
Problem
Today's NIP-98 path (
src/auth/nostr.js) authenticates a request asdid:nostr:<pubkey>. WAC then operates on that DID-shaped identity — useful for direct-did:nostr-in-ACL, but it doesn't give the user their WebID as the authenticated identity, so writes to their own profile fail unless ACLs explicitly grantdid:nostr:.#4's original Phase 2A solved this with
owl:sameAslinking in the profile + a dedicated SSO endpoint. With the verificationMethod / authentication infrastructure now in place (#386 + #397/#398), there's a smaller, more uniform alternative: the same K→W lookup the LWS-CID verifier already does.Proposed change
Augment
verifyNostrAuthso that, on a successful Schnorr verification:verificationMethodwhosepublicKeyMultibasedecodes to the same Nostr pubkey we just verified, and whose VM id is referenced byauthentication.did:nostr:).did:nostr:<pubkey>as today (no behaviour regression).Decode of the f-form Multikey is straightforward — strip
fprefix, stripe701multicodec, strip parity byte, take the remaining 32-byte x-only hex. The doctor'sB.2(already shipped) emits exactly this shape.Acceptance
authenticationaccepts NIP-98 requests as the WebID (notdid:nostr:)did:nostr:<pubkey>(no behaviour change for Add did:nostr SSO and Schnorr (NIP-98) authentication #4 Phase 1)did-nostr.jsWhy this and not the original Phase 2A design
The original design was independent of CID: link via
owl:sameAs, build a dedicated SSO endpoint. With CID v1 + LWS10-CID now load-bearing for keys-in-profiles, going through the same VM mechanism:Out of scope
/idp/nostr-loginendpoint — separate, can be layered on top laterRefs