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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions