This NIP proposes a foundational decentralized identity model for Agents (representing users, services, or other autonomous entities) within the ecosystem. It enables a single master Decentralized Identifier (DID) to manage multiple operational keys (e.g., device-specific keys, application-specific keys, or service instance keys). The model aims to ensure consistent and verifiable identities, key isolation, permission control, and secure revocability across multiple devices and application contexts. The model supports various DID methods (which could be anchored to different Verifiable Data Registries, including blockchains) presented as potential examples for anchoring DID documents.
To establish a consistent and secure identity framework for all participating entities (Agents, including users and service providers) within the ecosystem, a standardized approach to DID management is needed. This NIP defines a decentralized identity model based on a “single master identity + multiple operational sub-keys” concept. This allows an Agent, whether an end-user managing multiple devices and applications, or a service provider managing different operational instances or keys, to operate under a unified DID. It aims to provide a robust and flexible identity foundation for Agents in the ecosystem, enabling secure interactions and verifiable claims without compromising core digital identities or creating identity fragmentation across various devices and application environments.
did:example:123
; for implementations on a specific network, like did:<method>:<entity1>
), representing their unique digital persona or service identity and associated digital assets/memories/configurations. Control over this DID is held by one or more Master Key(s).verificationMethod
entry in the DID document associated with the master DID.id
of a verificationMethod
to different verification relationships (e.g., authentication
, assertionMethod
, capabilityInvocation
, capabilityDelegation
), the permission scope of each key can be precisely controlled.id
of the verificationMethod
).did:key
method, where the key material is derived from a WebAuthn Passkey. This initial key SHOULD be listed in both the authentication
and capabilityDelegation
verification relationships of the did:key
document, granting the user full control from inception.It is important to distinguish between a verificationMethod
entry and a verification relationship. A verificationMethod
entry primarily describes key material (e.g., the public key and its type). The verification relationship arrays (such as authentication
, assertionMethod
, capabilityInvocation
, capabilityDelegation
) declare the purpose or authorized uses of a specific key, referencing the id
of a verificationMethod
entry.
To further clarify the common verification relationships used in DID documents (as defined in the W3C DID Core specification) and their relevance within this NIP and related protocols (like CADOP):
authentication
:
verificationMethod
listed under authentication
is used to prove that the DID subject is performing an action under their control. Examples include signing a message to log into a service, establishing a secure session, or authorizing operations such as sending messages or initiating general on-chain transactions from an account associated with the DID.authentication
(and capabilityDelegation
) to grant them control.assertionMethod
:
verificationMethod
listed here is authorized to sign credentials or other statements on behalf of the DID subject.keyAgreement
:
capabilityInvocation
:
verificationMethod
listed here authorizes the key to make such invocations, essentially acting on behalf of the DID subject for specific operations.capabilityInvocation
, is authorized to call its own service endpoint in the context of that user (as per CADOP). This relationship is also used to authorize keys for managing the service
entries themselves, as per NIP-1 permission rules.capabilityDelegation
:
verificationMethod
listed here is authorized to grant capabilities to other keys or DIDs. This relationship signifies a higher level of authority, often including the ability to manage other verification methods and their relationships within the DID document.capabilityDelegation
itself), and, under standard NIP-1 rules, for changing the DID controller
.These verification relationships are fundamental for defining the security model and operational semantics of a DID, dictating what actions are permissible with different cryptographic keys associated with the DID.
This Agent model is designed to be compatible with any W3C compliant DID method. An Agent’s master DID can, in principle, adopt any such method (e.g., did:key
, did:web
, did:ethr
, did:ion
). The choice of DID method determines how and where the DID document is stored and managed (i.e., the Verifiable Data Registry or VDR).
Crucially, for an Agent to support advanced on-chain functionalities such as payments, state channel creation (e.g., as detailed in NIP-4), or other direct blockchain interactions, its chosen DID method must be one that is anchored to a blockchain (i.e., an “on-chain DID”). This implies that the DID is associated with a specific on-chain account or address that can receive funds, initiate transactions, and interact with smart contracts necessary for these functionalities. The specific on-chain address to be used for a particular interaction (like a payment channel) would then be discoverable or communicated as part of the relevant protocol (e.g., within NIP-4 messages).
However, for these advanced functionalities within the ecosystem, such as on-chain interactions including payments (e.g., as might be detailed in NIP-4 for state channels) or other forms of direct blockchain engagement by an Agent, the underlying VDR (the blockchain to which the on-chain DID is anchored) associated with the chosen DID method (or at least the VDR used for operational keys involved in such transactions) must meet specific requirements:
verificationMethod
entries) to authorize and initiate transactions on behalf of the Agent’s primary on-chain identity or account. This is crucial for enabling an Agent to act through its various operational contexts (devices, services) without directly using its master key(s) for every transaction.Therefore, while NIP-1 provides a flexible identity superstructure, the practical choice of DID methods and their underlying VDRs for Agents participating in advanced on-chain operations will be influenced by the technical capabilities of those VDRs to support the required transactional semantics and key management models. Implementers should evaluate VDR capabilities when designing solutions that leverage this NIP for on-chain activities.
Secure management and reliable recovery of master keys are critical.
controller
field of the DID document must point to the entity holding the Master Key(s), which is typically the DID subject itself.A core principle for the ecosystem is to enable simple and standardized discovery of services offered by Agents. NIP-1 establishes the use of the service
property within a DID document as the standard mechanism for service declaration and discovery.
service
array of its DID document.Standardized Service Types: Each NIP that defines a specific service (e.g., a Fiat Proxy service as in NIP-5, an LLM Gateway as in NIP-9) MUST specify a unique type
string for that service (e.g., "FiatProxyServiceNIP5"
, "LLMGatewayNIP9"
, "CadopCustodianService"
, "CadopWeb2ProofService"
, "CadopIdPService"
). This type
is used in the service.type
field of the service entry.
To ensure clarity and uniqueness, service types within this ecosystem should follow one of the following naming conventions:
type
should be prefixed with an abbreviation or a well-known name of the protocol, followed by the specific role of the service. Example: CadopCustodianService
, where “Cadop” refers to the Custodian-Assisted DID Onboarding Protocol.type
should combine a descriptive name of the service concept with a suffix indicating the NIP number that defines it. Example: FiatProxyServiceNIP5
, indicating a Fiat Proxy service as defined in NIP-5.This approach ensures that service types are both descriptive and directly linkable to their defining specifications.
service
entry in the DID document. The serviceEndpoint
property typically defines the primary interaction endpoint for the service.service
array in the DID document, looking for entries with the desired service.type
.serviceEndpoint
and other service-specific metadata to interact with the service.This approach ensures a consistent and decentralized way for services to be announced and discovered, leveraging the existing DID infrastructure.
Below is an example of a DID document conforming to this NIP. This example uses did:example
as a placeholder for a concrete DID method.
Key points illustrated in the example:
id
field (e.g., did:example:alice
) represents the Agent’s unique DID. This Agent could be an end-user, a service, or another autonomous entity. The specific nature of the Agent can be further clarified by other properties within the DID document, such as the service
property.verificationMethod
represents an operational key.
id
within a verificationMethod
entry (e.g., did:example:alice#key-1
) is a generic identifier for that specific key.type
(e.g., EcdsaSecp256k1VerificationKey2019
) specifies the cryptographic suite of the key. Other types like Ed25519VerificationKey2020
are also permissible.authentication
, assertionMethod
, capabilityInvocation
, and capabilityDelegation
link to specific key id
s from the verificationMethod
array to define their permissions.
capabilityDelegation
is typically reserved for Master Keys or other high-privilege keys authorized to delegate capabilities.service
array is used to define service endpoints. This is particularly important for service Agents (e.g., custodians, gateways) to declare how they can be interacted with. The type
property within a service entry (e.g., "FiatProxyServiceNIP5"
, "LLMGatewayNIP9"
) should be used to specify the kind of service, as defined by relevant NIPs. The serviceEndpoint
provides the primary URL for interacting with the service, and other properties within the service entry will contain service-specific metadata as defined by the NIP for that service type
.{
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/suites/ed25519-2020/v1"],
"id": "did:example:alice",
"controller": "did:example:alice",
"verificationMethod": [
{
"id": "did:example:alice#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "did:example:alice",
"publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPV"
},
{
"id": "did:example:alice#key-2",
"type": "Ed25519VerificationKey2020",
"controller": "did:example:alice",
"publicKeyMultibase": "zH3C2AVvLMv6gmMNam3uVAjZpfkcJCwDwnZn6z3wXmqPZ",
}
],
"authentication": [
"did:example:alice#key-1"
],
"assertionMethod": [
"did:example:alice#key-1"
],
"capabilityInvocation": [
"did:example:alice#key-1",
"did:example:alice#key-2"
],
"capabilityDelegation": [
"did:example:alice#key-1"
],
"service": [
{
"id": "did:example:alice#llm-gateway",
"type": "LLMGatewayNIP9",
"serviceEndpoint": "https://alice.example.com/llm",
"llmCapabilities": {
"supported_models": ["gpt-4", "claude-3-opus"],
"pricing_info_url": "https://alice.example.com/llm/pricing"
}
},
{
"id": "did:example:alice#social-profile",
"type": "SocialWebProfile",
"serviceEndpoint": "https://social.example.com/alice"
}
]
}
Each signature operation initiated by an Agent device or service instance should result in a structure (example uses did:example
as a placeholder):
{
"signed_data": {
"operation": "...",
"params": { ... },
"nonce": "random_nonce_123",
"timestamp": 1715600000
},
"signature": {
"signer_did": "did:example:alice",
"key_id": "did:example:alice#key-1",
"value": "0x...."
}
}
Verification Process:
timestamp
.nonce
.signer_did
.verificationMethod
for key_id
.signature.value
with the public key.key_id
against verification relationships for the specific operation.Recommended strategies:
service
endpoint points to a policy service.Recommendation: Prioritize Verification Relationship-Based, combinable with Capability Objects.
To ensure clarity and consistent implementation, this NIP specifies the following mapping between DID document update operations and the required verification relationships. Any update to the DID document MUST be authorized by a signature from a key that is listed in the appropriate verification relationship array within the current version of the DID document being updated.
capabilityDelegation
):
verificationMethod
entry (i.e., registering a new key).verificationMethod
entry (i.e., revoking a key).verificationMethod
entry (e.g., type
, publicKeyMultibase
).authentication
, assertionMethod
, capabilityInvocation
, capabilityDelegation
itself).capabilityDelegation
. Typically, only Master Key(s) or specifically designated high-privilege keys will possess this capability.capabilityInvocation
):
service
entry to the service
array.service
entry from the service
array.service
entry (e.g., changing serviceEndpoint
, type
, or service-specific metadata).capabilityInvocation
allows designated keys to manage these service declarations.controller
field of the DID document.authentication
and capabilityDelegation
rights and represents the authority of the current controller
. The specific mechanism for controller updates may also be further defined by the DID method itself.Implementers MUST ensure that any attempt to update the DID document is validated against these permission requirements. An update operation MUST be rejected if the authorizing signature does not originate from a key possessing the necessary verification relationship as defined above.
This section outlines a high-level protocol for adding a new operational key (for a device, application, or other operational context) to the DID document.
Participants: Agent (User or Service Admin), New Instance/Device/Application, Authorizing Instance/Device/Mechanism, Controller/Management Service, VDR.
Protocol Flow (Example: Authentication via an Authorized Key/Device/Application):
newPubKey
, newPrivKey
.targetDid
, newPubKey
, desired relationships, requestNonce
, requestTimestamp
.authChallenge
.authChallenge
with its authorized key, sends authProof
.authProof
, constructs VDR update transaction, submits to VDR.(Security considerations for this protocol are detailed in the “Security Considerations” section below).
did:rooch
(for the Rooch Network) or established methods like did:ethr
are examples of concrete possibilities for anchoring DIDs.authentication
, assertionMethod
, etc.) for basic permissioning is chosen for its standards compliance and interoperability. More complex authorization can be layered on top (e.g., ZCAP-LD).key_id
in signatures is crucial for verifiers to identify the specific key used, look it up in the DID document, and apply the correct policies.This NIP proposes a new identity model.
Test cases should cover, at a minimum:
key_id
has authentication
permission.key_id
has capabilityInvocation
but not authentication
permission.nonce
and timestamp
.(Specific test vectors and a test suite are to be developed alongside a reference implementation.)
While this NIP promotes DID method agnosticism to allow for identity representation across various Verifiable Data Registries (VDRs), including different blockchains, a multi-chain DID strategy introduces several challenges that implementations and the broader ecosystem need to consider:
verificationMethod
entries are anchored to different blockchains with distinct cryptographic requirements. This can increase the burden of key generation, storage, backup, and recovery.verificationMethod
entries are interpreted consistently across different chains and platforms is essential. Lack of such consistency can lead to security vulnerabilities or interoperability failures.Addressing these challenges will be crucial for realizing the full potential of a flexible, multi-chain identity ecosystem based on this NIP.
The official reference implementation for TypeScript/JavaScript environments is @nuwa-ai/identity-kit
. It provides:
IdentityKit
class for managing the full lifecycle of a DID, including operational key management (add/remove verificationMethod
) and service endpoint management, compliant with NIP-1.did:key
and did:rooch
.KeyManager
for handling cryptographic keys, with default storage backends for browsers (LocalStorage
, IndexedDB
) and Node.js (Memory
).This SDK serves as the canonical implementation of the NIP-1 model.
This section incorporates and expands upon the “Security Policies” from the original NIP-1.
signer_did
(or key_id
) to prevent replay. This requires stateful verifiers.signed_data
structure must be canonicalized before signing to prevent ambiguity.authChallenge
must be unique, unpredictable, and tied to the specific request.controller
of the DID should be able to update it.key_id
fragments.did:key
) for bootstrapping DIDs offers excellent usability, implementers should be aware of the potential for Sybil attacks if Passkey creation is too unconstrained. Pairing Passkey-based DID onboarding with mechanisms like proof-of-uniqueness or resource commitment, such as those that can be indicated by a Custodian-Assisted DID Onboarding Protocol (CADOP) provider (e.g., through its sybilLevel
metadata or associated Web2ProofServiceCADOP
), is recommended to mitigate this risk, especially for services sensitive to such attacks.Copyright and related rights waived via CC0.