1. Request arrives with NIP-98 header
2. Extract pubkey from Nostr event signature
3. Fetch: nostr.social/.well-known/did/nostr/<pubkey>.json
4. Get alsoKnownAs → WebID URL
5. Fetch WebID profile
6. Check owl:sameAs === did:nostr:<pubkey>
7. Bidirectional match? → Authenticated as WebID
Implementation
// src/auth/did-nostr.js (~50 lines)exportasyncfunctionresolveNostrToWebId(pubkey){// Fetch DID documentconstres=awaitfetch(`https://nostr.social/.well-known/did/nostr/${pubkey}.json`);constdidDoc=awaitres.json();// Get WebID from alsoKnownAsconstwebid=didDoc.alsoKnownAs?.[0];if(!webid)returnnull;// Verify backlink in WebID profileconstprofile=awaitfetch(webid,{headers: {'Accept': 'application/ld+json'}}).then(r=>r.json());constsameAs=profile['owl:sameAs']||profile['sameAs'];if(sameAs===`did:nostr:${pubkey}`){returnwebid;}returnnull;}
Benefits
No passwords, cryptographic signatures only
Bridges Nostr ↔ Solid identity
Works with existing NIP-07 browser extensions
Uses existing NIP-98 auth in JSS
Decentralized identity resolution via nostr.social
Related
nostr-beacon - DID resolver running on nostr.social
Activity