Skip to content

Login with did:nostr #37

@melvincarvalho

Description

@melvincarvalho

Summary

Enable authentication via did:nostr:<pubkey> resolution, bridging Nostr identity to Solid WebID.

How It Works

nostr.social runs nostr-beacon which already supports alsoKnownAs in DID documents:

https://nostr.social/.well-known/did/nostr/<pubkey>.json

Step 1: User links Nostr → WebID

Add alsoKnownAs to Nostr profile (kind 0 event):

{
  "name": "alice",
  "alsoKnownAs": ["https://solid.social/alice/profile/card#me"]
}

Step 2: User links WebID → Nostr

Add owl:sameAs to WebID profile:

{
  "@id": "#me",
  "owl:sameAs": "did:nostr:<pubkey>"
}

Step 3: JSS verifies bidirectional link

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)
export async function resolveNostrToWebId(pubkey) {
  // Fetch DID document
  const res = await fetch(`https://nostr.social/.well-known/did/nostr/${pubkey}.json`);
  const didDoc = await res.json();
  
  // Get WebID from alsoKnownAs
  const webid = didDoc.alsoKnownAs?.[0];
  if (!webid) return null;
  
  // Verify backlink in WebID profile
  const profile = await fetch(webid, {
    headers: {'Accept': 'application/ld+json'}
  }).then(r => r.json());
  
  const sameAs = profile['owl:sameAs'] || profile['sameAs'];
  if (sameAs === `did:nostr:${pubkey}`) {
    return webid;
  }
  return null;
}

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
  • NIP-07: Browser extension signing
  • NIP-98: HTTP Auth (already in JSS)
  • Existing Nostr auth: src/auth/nostr.js

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