CARVIEW |
This specification defines a Decentralized Identifier (DID)[[DID-CORE]] method for the Nostr protocol. Nostr is an open-source protocol that utilizes the W3C WebSockets standard.
This document is a draft specification produced by the W3C Nostr Community Group. It is not a W3C Standard nor is it on the W3C Standards Track.
This specification is intended to provide a stable foundation for implementing Nostr-based Decentralized Identifiers. Feedback and contributions are encouraged through the GitHub repository.
This document is a work in progress and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
Introduction
Decentralized Identifiers (DIDs) are a new type of identifier that enables verifiable, decentralized digital identity. The Nostr DID method connects the emerging W3C DID standard with the Nostr protocol, allowing Nostr keypairs to be used as the foundation for decentralized identifiers.
Nostr is a simple, open protocol that enables a truly censorship-resistant and global social network. By creating a DID method for Nostr, this specification enables Nostr identities to participate in the broader decentralized identity ecosystem, supporting verifiable credentials, authentication, and other identity use cases.
This specification describes how to create, read, and use Nostr DIDs, along with the expected behavior of conforming implementations. The method is designed to be simple, requiring minimal processing overhead while maintaining compatibility with existing Nostr tooling and infrastructure.
Core Concepts
Nostr DID Scheme
The Nostr DID scheme `did:nostr:pubkey` is based on the encoding of a
public key. The public key is represented as a 64-character, lowercase
string. The prefix did:nostr
should be in lowercase, as
per the DID specification.
All DID documents MUST include a type
field with the value "DIDNostr"
to enable proper linked data processing and disambiguation per httpRange-14.
Example Nostr DID:
did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
.
Relationship with Nostr npubs
In the Nostr ecosystem, public keys are often displayed as "npubs" (e.g., npub1...
),
which are Bech32 encoded versions of the raw public keys for human-friendly display.
It is important to note that Nostr DIDs use the raw 64-character hexadecimal public key, not the npub format. npubs should be considered display-only identifiers to improve readability in user interfaces.
When implementing the DID Nostr method, applications SHOULD accept raw public keys for DID creation. For display in user interfaces, applications MAY choose to show the corresponding npub alongside the DID.
Example mapping:
- Raw public key:
124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
- DID:
did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
- Display npub:
npub1cpxejnc58zpcuyh0pt8gvkzpv34qxceu0sqp7jec2nk9nut7p5zs4zyx4c
Example DID Documents
Minimal DID Document (Offline Resolution)
The following minimal DID document can be generated from the public key alone, without network access:
{ "@context": ["https://w3id.org/did", "https://w3id.org/nostr/context"], "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "alsoKnownAs": [ "https://alice.example.com/#me", "https://social.example.com/@alice", "at://alice.bsky.social" ], "type": "DIDNostr", "verificationMethod": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1", "type": "Multikey", "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2" } ], "authentication": ["#key1"], "assertionMethod": ["#key1"] }
This minimal document provides full cryptographic functionality for identity verification and authentication using the standardized Multikey format.
Enhanced DID Document (With Relay Services)
When enhanced through relay queries, additional service endpoints can be included:
{ "@context": ["https://w3id.org/did", "https://w3id.org/nostr/context"], "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "alsoKnownAs": [ "https://alice.example.com/#me", "https://social.example.com/@alice", "at://alice.bsky.social" ], "type": "DIDNostr", "verificationMethod": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1", "type": "Multikey", "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2" } ], "authentication": ["#key1"], "assertionMethod": ["#key1"], "service": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#relay1", "type": "Relay", "serviceEndpoint": "wss://some-nostr-relay.org/" } ] }
This enhanced document includes service endpoints discovered through optional relay queries.
Complete DID Document (With Profile and Social Graph)
A fully enhanced DID document can include profile information and social relationships:
{ "@context": ["https://w3id.org/did", "https://w3id.org/nostr/context"], "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "alsoKnownAs": [ "https://alice.example.com/#me", "https://social.example.com/@alice", "at://alice.bsky.social" ], "type": "DIDNostr", "verificationMethod": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#key1", "type": "Multikey", "controller": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2", "publicKeyMultibase": "fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2" } ], "authentication": ["#key1"], "assertionMethod": ["#key1"], "service": [ { "id": "did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2#relay1", "type": "Relay", "serviceEndpoint": "wss://relay.damus.io/" } ], "profile": { "name": "Alice", "about": "Building the decentralized web", "picture": "https://example.com/alice.jpg", "timestamp": 1737906600 }, "follows": [ "did:nostr:32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245", "did:nostr:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184147700e3a8" ] }
This complete document enables social applications to resolve identity, profile, relays, and social graph information in a single operation.
For identities with large follow lists, the service array could include a FollowsEndpoint for complete access to thousands of follows without bloating the DID document.
Additional Terminology
The term relay refers to a Nostr relay.
Multikey Verification Method
Nostr DIDs use the Multikey verification method to provide a standardized way to encode secp256k1 public keys for Data Integrity implementations. This method transforms the x-only BIP-340 public key from the DID identifier into a format compatible with W3C Verifiable Credentials Data Integrity specifications.
The transformation process for creating the Multikey representation is as follows:
- Start with the x-only public key (32 bytes) from the DID identifier
- Construct a 33-byte secp256k1 compressed public key by prepending a parity byte:
- Use
0x02
for even y-coordinate (standard default) - Use
0x03
for odd y-coordinate (when applicable for Nostr keys)
- Use
- Prepend the multicodec varint for secp256k1 compressed public keys (
0xe7, 0x01
) - Encode the result using multibase with base16-lower encoding (
f
prefix) - Place the encoded value in the
publicKeyMultibase
field
For example, given the x-only public key:
124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
The transformation steps would be:
- Compressed key:
02124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
- With multicodec varint:
e70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
- Multibase base16-lower encoded:
fe70102124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
Note on Parity Bytes: While most implementations default to the 0x02 prefix for even y-coordinates, Nostr applications may generate keys with either 0x02 or 0x03 prefixes. Implementations should handle both cases when constructing the compressed public key format.
Service Field for Relays
The DID Document SHOULD include a service field to explicitly define relevant relays. This provides a standardized approach for applications resolving a DID document to discover the relays associated with the identity.
Each relay is represented as a service entry with type "Relay" and a
serviceEndpoint that specifies the WebSocket URL of the relay.
Relay URLs at the origin level MUST include a trailing slash (e.g., wss://relay.example.com/
).
Multiple relays can be included in the service array.
Also Known As Field (Optional)
DID Documents MAY include an alsoKnownAs
field as defined in the
DID Core specification.
This field contains an array of identifiers that are asserted to refer to the same entity
as the DID subject. These can be other DIDs or different types of URIs representing the
same identity across various platforms and protocols.
"alsoKnownAs": [ "https://alice.example.com/#me", // WebID "https://social.example.com/@alice", // ActivityPub/Mastodon handle "at://alice.bsky.social", // Bluesky AT Protocol identifier "did:key:z6MkpTHR8VNsBxYAAWHut2Geadd9jSwuBV8xRoAnwWsdvktH", // Another DID "https://twitter.com/alice", // Social media profile "https://github.com/alice" // Developer profile ]
The alsoKnownAs
property enables cross-platform identity linking and verification.
Common use cases include:
- Linking a Nostr identity to a WebID for Solid applications
- Connecting to ActivityPub identities for federated social networks
- Associating with Bluesky AT Protocol handles
- Referencing traditional social media profiles
- Establishing equivalence with other DIDs
- Linking to professional or developer profiles
Important: Including an identifier in the alsoKnownAs
field
represents a claim by the DID controller. Applications SHOULD verify these claims when
possible, such as checking for reciprocal references or using platform-specific verification
mechanisms.
Nostr Integration: Users can include the alsoKnownAs
field in their
Nostr kind 0 profile metadata event. This creates a cryptographically signed public attestation
of the identity linkages, leveraging Nostr's built-in signature verification. When the field is
present in a kind 0 event, it provides stronger assurance of the claimed associations since the
attestation is signed by the user's private key and can be independently verified by any client.
Privacy Consideration: The alsoKnownAs
field creates public
linkages between identities. Users should carefully consider privacy implications before
associating identities across different platforms, as this information becomes part of the
publicly resolvable DID document.
Profile Field (Optional)
DID Documents MAY include a profile
field containing public profile information
that the user has chosen to share. This enables social applications to display profile
information without requiring relay queries.
"profile": { "name": "Alice", "about": "Building the decentralized social web", "picture": "https://example.com/alice.jpg", "nip05": "alice@example.com", "lud16": "alice@getalby.com", "website": "https://alice.example.com", "timestamp": 1737906600 }
The timestamp
field contains the created_at
value from the latest Nostr profile event (Unix seconds),
allowing clients to determine profile freshness and implement intelligent caching strategies.
Note: For Nostr developers: the timestamp
field contains the same value as
event.created_at
from the most recent kind 0 profile event. This allows clients to determine
if their cached profile data is newer or older than what's in the DID document without querying relays.
Note: While DID Core generally recommends against including personally identifiable information, social networking represents a specific use case where users explicitly publish profile information for discovery. This field is optional and should only contain information the user has chosen to make public.
Follows Field (Social Graph)
DID Documents MAY include a follows
field containing a list of DIDs that the identity follows,
enabling the construction of decentralized social graphs. This field enhances the DID document with
social relationship information discoverable through standard DID resolution.
"follows": [ "did:nostr:32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245", "did:nostr:46fcbe3065eaf1ae7811465924e48923363ff3f526bd6f73d7c184147700e3a8", "did:nostr:82341f882b6eabcd2ba7f1ef90aad961cf074af15b9ef44a09f9d2a8fbfbe6a2" ]
Each entry in the follows array is a DID that represents an identity this DID follows. The follows field is derived from Nostr kind 3 "contact list" events, providing a standardized way to expose social graph relationships through DID resolution.
The follows
field enables applications to:
- Build social graphs from DID resolution alone
- Discover mutual connections between identities
- Implement social discovery features
- Cache social relationships for offline operation
Note: The follows field mirrors the public contact list already published in Nostr kind 3 events, making this social graph data available through standard DID resolution.
Scalability Consideration: For identities with large follow lists (thousands of follows), implementations SHOULD use a hybrid approach:
- Include a truncated list (e.g., first 100-500 most recent follows)
- Provide a service endpoint for complete follow list retrieval
"follows": [ "did:nostr:32e182...", // First 100 follows included "did:nostr:46fcbe...", // ... up to 100 entries ], "service": [ { "id": "#follows-api", "type": "FollowsEndpoint", "serviceEndpoint": "https://api.example.com/did/follows/{did}" } ]
This hybrid approach provides immediate access to recent follows while maintaining document size limits and offering complete data access when needed. This pattern addresses the scalability challenge shared with other social protocols like ActivityPub.
This document defines a DID method for Nostr. Implementations MUST conform to the DID Core specification [[DID-CORE]] and the requirements specified in this document.
Operations
Create (Register)
Creating a did:nostr identifier involves the following steps:
- Generate a secp256k1 key pair using a cryptographically secure random number generator
- Extract the public key (32 bytes)
- Encode the public key as a 64-character lowercase hexadecimal string
- Prefix the encoded public key with "did:nostr:" to form the complete DID
For example, if the generated public key in hex is:
124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
The corresponding DID would be:
did:nostr:124c0fa99407182ece5a24fad9b7f6674902fc422843d3128d38a0afbee0fdd2
Note: No on-chain registration is required as the security and uniqueness are derived from the key generation process.
Read (Resolve)
DID resolution for did:nostr
identifiers follows this strategy:
- HTTP Resolution - Check
https://<domain>/.well-known/did/nostr/<pubkey>.json
- Offline-first Resolution - Generate minimal DID document from public key alone
- Enhanced Resolution - Optionally query Nostr relays for additional metadata
HTTP Resolution
Servers can host complete DID documents at:
https://example.com/.well-known/did/nostr/<pubkey>.json
Where <pubkey>
is the 64-character lowercase hex public key. The endpoint SHOULD return a complete DID document (minimal or enhanced).
When serving DID documents via HTTP, servers SHOULD include the following headers:
Nostr-Timestamp: 1737906600
Cache-Control: max-age=3600
Last-Modified: Sun, 26 Jan 2025 15:30:00 GMT
The Nostr-Timestamp
header contains the Unix timestamp when the DID document was generated or refreshed. This enables clients to check freshness without parsing the JSON body, allowing for efficient caching strategies.
This enables fast, cacheable resolution without requiring cryptographic computation or relay queries. Servers can serve minimal documents for offline-first scenarios or enhanced documents with service endpoints and profile metadata.
Note: Resolvers MAY check NIP-05 endpoints for a didResolver
field to locate HTTP-hosted DID documents before querying relays.
Minimal Resolution
A conforming resolver MUST be able to generate a valid DID document using only the public key from the DID identifier, without requiring network access to Nostr relays.
The minimal resolution process involves:
- Parse the identifier to extract the 64-character hexadecimal public key
- Construct a DID Document with the following required properties:
- Set the
id
field to the full DID - Set the
type
field to"DIDNostr"
- Include a Multikey verification method, transforming the x-only public key following the multicodec/multibase encoding process
- Set appropriate authentication and assertionMethod references to the verification method
- Set the
This minimal DID document provides full functionality for cryptographic verification and identity assertion without requiring network connectivity.
Enhanced Resolution with Relay Queries
Optionally, resolvers MAY query known Nostr relays to enhance the DID document with additional metadata and service endpoints.
The enhanced resolution process adds:
- Query known Nostr relays for metadata about the public key
- Include discovered relay endpoints in the service section of the DID Document
- Add any additional metadata found in kind 0 (profile) events
- Include social graph information from kind 3 (contact list) events in the follows field
The resolved DID Document will follow the template shown in the "Example DID" section above.
For relay discovery during enhanced resolution, implementations SHOULD:
- Check a local cache of known relays for the public key
- Query a set of default relays with a filter for kind 0 (metadata) and kind 3 (contact list) events by the target public key
- Include discovered relays in the service section of the DID Document
- Transform kind 3 contact pubkeys to DIDs and include in the follows field
Note that relay queries and metadata integration are OPTIONAL enhancements to the basic resolution process. Implementations MUST support minimal resolution without network access.
Update (Replace)
This DID Method does not support updating the DID Document.
Delete (Revoke)
This DID Method does not support deactivating the DID Document.
Security & Privacy
Security Considerations
The security of the did:nostr method relies on the security properties of the underlying Nostr protocol and its public key cryptography. The following security considerations apply:
Key Management
The private keys corresponding to Nostr DIDs MUST be kept secure. Loss of private keys will result in permanent loss of control over the identifier. Implementers SHOULD employ strong key management practices, including secure key generation, storage, and backup procedures.
Relay Security
Nostr DIDs interact with the Nostr network through relays. These relays may have different security properties and trust models. Implementers SHOULD:
- Use TLS (wss://) connections to relays to prevent eavesdropping and man-in-the-middle attacks
- Consider using multiple relays for redundancy and to mitigate denial of service risks
- Be aware that relays may choose to filter or modify events, potentially affecting DID resolution
Cryptographic Considerations
The Nostr DID method uses Schnorr signatures over the secp256k1 curve, which is considered cryptographically secure at the time of writing. However, cryptographic methods may become vulnerable over time. Implementers should stay informed about advancements in cryptanalysis that might affect the security of these signatures.
For additional security requirements, refer to W3C Decentralized Identifiers 8.3.
Privacy Considerations
The did:nostr method has several privacy implications that implementers and users should be aware of:
Identifier Correlation
A Nostr DID directly incorporates a public key that may be used across multiple contexts in the Nostr ecosystem. This creates a potential correlation vector where activities under the same DID can be linked across different services or applications. Users should understand that a single did:nostr identifier does not provide compartmentalization of identity across different contexts.
To mitigate correlation risks, users may consider:
- Using different DIDs for different contexts or services
- Creating purpose-specific DIDs rather than using a single DID for all activities
Public Nature of Nostr
Information associated with a Nostr DID is typically stored on public relays where it can be accessed by anyone. Users should be aware that DID Documents and associated Nostr events are public information. Private or sensitive data should not be included in DID Documents or directly associated with did:nostr identifiers.
Service Endpoints
The service endpoints (relays) listed in a DID Document may reveal information about a user's network participation and potentially their geographic region or service preferences. Implementers should be cautious about what information might be inferred from service endpoints included in DID Documents.
For additional privacy requirements, refer to W3C Decentralized Identifiers 8.4.
Implementations
Block, Inc. previously developed a related implementation of the did:nostr method in Rust, but this work has been discontinued and archived. The archived repository can be found at https://github.com/TBD54566975/did-nostr.
Resources
- Nostr Protocol Specification - The official specification of the Nostr protocol
- W3C Decentralized Identifiers (DIDs) v1.0 - The W3C Recommendation for Decentralized Identifiers
- DID:Nostr Method GitHub Repository - Source code and issue tracker for this specification
- TBD54566975 Rust Implementation - Reference implementation of the did:nostr method in Rust
- Nostr Implementation Possibilities (NIPs) - Nostr protocol extension proposals
- RFC 6979 - Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)