Summary
Design and implement the member/device ownership model that enables:
- Personal device meshes (Alice's devices talk to each other via her own DWN)
- Organizational membership (Alice joins Org X, proposes devices, org approves)
- Org-provisioned devices (Org X creates devices it owns, assigns them to members)
- Cross-org device sharing (Org X shares a server with Org Y, retaining full control)
All of this is built on a single principle: every device is owned by exactly one DWN, and cross-DWN visibility is controlled by Permission Grants.
Core Model
Every DID has a DWN with the mesh protocol
The mesh protocol is installed identically on every DWN — personal or organizational. There is no structural difference between a "personal mesh" and an "org mesh." They are the same protocol at different scales.
The base structure is:
network
├── member ($role: true, recipient = member DID)
│ ├── nodeRequest (member writes — proposes a device)
│ └── node (network owner creates on approval)
│
├── node ($role: true, recipient = node DID — owner-provisioned devices)
│ ├── nodeInfo (node self-writes)
│ └── endpoint (node self-writes)
│
├── aclPolicy
└── relay
- Alice's DWN: Alice is the owner. Her devices are nodes. She can also invite members (e.g., her friend Bob) — same protocol, same structure.
- Org X's DWN: Org X is the owner. Org-owned servers are top-level nodes. Members (employees) are invited and propose their personal devices.
A DWN with just the owner's devices and no members is the simplest case. Adding a member is just "granting another person access to your mesh." The protocol scales from one person's devices to a large organization without structural changes.
Device ownership is DWN-local
A device's authoritative records (nodeInfo, endpoint) always live on one DWN — the DWN of whoever owns that device. Alice's personal laptop writes to Alice's DWN. An Org X corporate server writes to Org X's DWN. Devices never move between DWNs.
Cross-DWN visibility uses Permission Grants
When a device needs to be visible on a foreign network, the device's owner creates a Permission Grant on their DWN, allowing the foreign network to read that device's data. The foreign network creates a reference record pointing to the device on the source DWN. No data is copied or mirrored — the source DWN remains authoritative.
Authorization Model
Intra-DWN: Roles handle everything
Within a single DWN, no explicit Permission Grants are needed. The protocol's role system handles authorization:
member record (recipient = Alice's DID) → gives Alice the network/member role
member/node record (recipient = device DID) → gives the device the network/member/node role
node record (recipient = device DID) → gives the device the network/node role (for owner-provisioned devices)
These roles grant read access to the records they need via $actions:
{ "role": "network/member", "can": ["read"] }
{ "role": "network/member/node", "can": ["read"] }
{ "role": "network/node", "can": ["read"] }
Write access for devices comes from recipient authorization:
{ "who": "recipient", "of": "network/node", "can": ["create", "update"] }
{ "who": "recipient", "of": "network/member/node", "can": ["create", "update"] }
Cross-DWN: Delegated grants for member devices reading a foreign DWN
Alice is a member of Org X. Alice's member record gives her the network/member role on Org X's DWN. But Alice's devices have their own DIDs — they are not Alice. A device cannot directly invoke Alice's role.
Solution: Alice delegates read-only grants to her devices. When Alice provisions a device for Org X's mesh, she creates a delegated grant allowing the device to read from Org X's DWN acting as Alice. The device signs the request with its own key, includes the delegated grant, and the DWN resolves the author as Alice.
This delegation is read-only. Devices never write to Org X's DWN acting as Alice. Their write operations (nodeInfo, endpoint) go to Alice's own DWN using their own recipient of network/node authorization.
Cross-DWN: Permission Grants for foreign DWNs reading device data
Org X's nodes need to read Alice's device's nodeInfo and endpoint from Alice's DWN. Org X doesn't have a role on Alice's DWN.
Solution: Alice creates a Permission Grant on her DWN allowing Org X to read the device's subtree. Alice creates this grant at the same time as the nodeRequest (see flow below), so Org X can immediately read the device's nodeInfo to make an informed approval decision.
Authorization summary
| Operation |
How authorized |
Where |
| Device reads Org X's mesh peers |
Delegated read grant from Alice (acts as Alice) |
Org X's DWN |
| Device writes its own nodeInfo/endpoint |
recipient of network/node (device's own role) |
Alice's DWN |
| Org X reads device nodeInfo/endpoint |
Permission Grant created by Alice |
Alice's DWN |
| Org owner manages members, approves devices |
author of network (owner authority) |
Org X's DWN |
| Member proposes/withdraws devices |
recipient of network/member |
Org X's DWN |
Permission Grants are only needed for cross-DWN reads. Within a single DWN, the role system handles everything.
Membership and Device Approval
Joining a network — full flow
Step 1: Network owner invites member
Org X's admin creates a member record on Org X's DWN:
recipient: Alice's DID
- Data:
{ label: "Alice", addedAt: "..." }
- This assigns Alice the
network/member role on Org X's DWN
Step 2: Alice proposes a device
Alice does two things simultaneously:
a) Writes a nodeRequest record under her member record on Org X's DWN:
- Authorized by:
{ "who": "recipient", "of": "network/member", "can": ["create", "delete"] }
- Data:
{ nodeDID: "did:jwk:aliceLaptop...", sourceDWN: "https://alice.dwn.example" }
b) Creates a Permission Grant on her own DWN:
recipient: Org X's DID
scope: { interface: "Records", method: "Read", protocol: meshProtocolURI, contextId: "aliceNetworkRecord/laptopNodeRecord" }
delegated: true (so Org X can sub-delegate to individual mesh nodes)
Because Alice creates the grant up front, Org X can immediately read the device's nodeInfo (hostname, OS, capabilities) from Alice's DWN to make an informed approval decision — e.g., using the hostname as the label.
Step 3: Org approves
Org X's admin creates a node record under Alice's member record on Org X's DWN:
- Authorized by:
{ "who": "author", "of": "network", "can": ["create", "update", "delete"] }
recipient: the device's DID (did:jwk:aliceLaptop)
- Data:
{ meshIP: "10.200.x.x", sourceDWN: "https://alice.dwn.example", addedAt: "..." }
- The mesh IP is assigned by the org within their CIDR
Step 4: Operational
Alice creates a delegated read-only grant for her laptop, derived from her network/member role on Org X's DWN. The laptop uses this to read Org X's peer data. Alice manages this delegation herself — the org never needs to interact with individual device DIDs for read access.
Adding more devices later
- Alice writes a new
nodeRequest on Org X's DWN + creates a Permission Grant on her DWN for the new device's subtree
- Org X approves by creating a
member/node record
- Alice creates a delegated read grant for the new device — no action needed from Org X
Owner-provisioned devices
For devices the org owns directly (corporate laptop, server):
- Org X creates a
node record at the top level (network/node) on Org X's DWN
- The device writes its own
nodeInfo and endpoint to Org X's DWN (authorized as recipient of network/node)
- No Permission Grants needed — everything is on one DWN
- The org can optionally associate the device with a member for organizational purposes
Member removal
When Org X removes Alice:
- Org X co-prunes Alice's
member record → cascading deletion of all nodeRequest and node records under it
- Alice's
network/member role is revoked → her delegated grants become invalid
- Alice's devices immediately lose read access to Org X's DWN
- Org X's nodes lose the ability to act on Alice's device grants (Alice can also explicitly revoke them)
Either side can independently sever the relationship.
Cross-Organization Device Sharing
Org X owns a server. Org X wants Org Y's members to be able to reach it.
Constraint: Org X can only share devices they own (nodes on Org X's DWN). They cannot share Alice's personal devices — only Alice can grant access to those.
Sharing flow
Step 1: Org X grants access
Org X creates a Permission Grant on Org X's DWN:
recipient: Org Y's DID
scope: { interface: "Records", method: "Read", protocol: meshProtocolURI, contextId: "orgXNetworkRecord/serverNodeRecord" }
delegated: true (Org Y can sub-delegate to their nodes)
Step 2: Org Y accepts and references
Org Y creates a reference record on Org Y's DWN (a sharedNode or similar record type under network):
- Data:
{ nodeDID: "did:jwk:server...", sourceAnchorDID: "did:jwk:orgX...", sourceDWN: "https://orgx.dwn.example", meshIP: "10.200.x.x" }
- The mesh IP is assigned by Org Y within their CIDR
Step 3: Org Y grants reciprocal access
Org Y creates a Permission Grant on Org Y's DWN:
recipient: the shared server's DID (or Org X's DID, delegatable)
scope: scoped to the specific node subtrees the server should see
- The server should NOT see Org Y's full topology — only the specific nodes it needs to communicate with
Step 4: Operational
- Org Y's nodes read their own DWN → find sharedNode → use delegated grant to read server's nodeInfo + endpoint from Org X's DWN
- The server reads Org X's DWN → finds sharing config → uses grant to read the specific Org Y peer endpoints from Org Y's DWN
Revocation
- Org X revokes: Deletes the Permission Grant → Org Y can no longer read server data → server vanishes from Org Y's mesh
- Org Y revokes: Deletes the sharedNode reference and their reciprocal grant → their nodes stop looking for the server
Either side can unilaterally revoke.
Quarantine
Shared devices are quarantined by default:
- The shared server can receive connections from Org Y's nodes
- The shared server cannot initiate connections to Org Y's nodes
- Enforced by ACL packet filter rules on both sides
- Org Y can explicitly relax quarantine in their ACL policy
Runtime Network Map Construction
For an owner-provisioned device on Org X
Reads from Org X's DWN:
- Native org nodes (top-level
network/node) → read nodeInfo + endpoint directly
- Member devices (
network/member/node) → follow sourceDWN pointer, use delegated grant to read nodeInfo + endpoint from member's personal DWN
- Shared nodes from other orgs → follow
sharedNode reference, use delegated grant to read from source org's DWN
For Alice's personal laptop (member of Org X)
Participates in multiple meshes:
- Alice's personal mesh: reads Alice's DWN → discovers her other personal devices and any members she's invited
- Org X's mesh: uses delegated read grant (acting as Alice) to read Org X's DWN → discovers Org X peers
Each mesh has its own CIDR, so there's no address conflict. The engine builds a combined network map.
For a device shared from Org X into Org Y
Reads from Org X's DWN (its home DWN):
- Native Org X peers → normal read
- Org Y peers (from sharing arrangement) → uses grant to read specific peer data from Org Y's DWN
Protocol $actions Summary
| Record |
Who writes |
Authorization |
network |
DWN owner |
Owner authority |
member |
DWN owner |
{ "who": "author", "of": "network", "can": ["create", "update", "co-delete", "co-prune"] } |
nodeRequest |
Member (person) |
{ "who": "recipient", "of": "network/member", "can": ["create", "delete"] } |
member/node |
DWN owner (on approval) |
{ "who": "author", "of": "network", "can": ["create", "update", "delete"] } |
node (owner-provisioned) |
DWN owner |
{ "who": "author", "of": "network", "can": ["create", "update", "delete"] } |
nodeInfo |
Device |
{ "who": "recipient", "of": "network/node", "can": ["create", "update"] } (or of: network/member/node) |
endpoint |
Device |
{ "who": "recipient", "of": "network/node", "can": ["create", "update"] } (or of: network/member/node) |
Reading
All roles get read access to the records they need:
{ "role": "network/member", "can": ["read"] }
{ "role": "network/member/node", "can": ["read"] }
{ "role": "network/node", "can": ["read"] }
Cross-DWN reads use delegated grants (for member devices reading a foreign mesh) or Permission Grants (for foreign DWNs reading device data).
Relationship to Other Issues
Open Questions
-
Grant lifecycle automation: When Alice writes a nodeRequest, she creates the grant on her DWN simultaneously. When she provisions a device, she creates the delegated read grant. The meshd client should automate both. How much should be automatic vs. user-prompted?
-
Multi-mesh routing: A device in multiple meshes has multiple CIDRs. The WireGuard engine needs routing for all of them. This is a runtime/engine concern.
-
Context key delivery across DWNs: Encrypted records on a foreign DWN require context keys. The foreign DWN owner may need to deliver context keys to granted parties. The key-delivery protocol may need extension.
-
Subscription across DWNs: For live updates, devices need to subscribe to foreign DWNs using Permission Grants with method: "Subscribe". The meshd subscription watcher needs to support multiple DWN connections.
-
Shared node reference record type: The exact record type and schema for cross-org shared node references needs detailed design. Must contain source DWN endpoint, source anchor DID, device DID, and local mesh IP assignment.
-
Read visibility scope: For v1, all members see all other members and all nodes. Finer-grained visibility (team-scoped access) is a future enhancement.
-
Delegated grant mechanics: We are designing with the assumption that Alice can create delegated grants directly from her network/member role authority — no explicit Permission Grant from Org X needed. The DWN should accept the delegation, resolve the author to Alice, and check her role. Spec clarification tracked in enboxorg/dwn-spec#49.
Summary
Design and implement the member/device ownership model that enables:
All of this is built on a single principle: every device is owned by exactly one DWN, and cross-DWN visibility is controlled by Permission Grants.
Core Model
Every DID has a DWN with the mesh protocol
The mesh protocol is installed identically on every DWN — personal or organizational. There is no structural difference between a "personal mesh" and an "org mesh." They are the same protocol at different scales.
The base structure is:
A DWN with just the owner's devices and no members is the simplest case. Adding a member is just "granting another person access to your mesh." The protocol scales from one person's devices to a large organization without structural changes.
Device ownership is DWN-local
A device's authoritative records (
nodeInfo,endpoint) always live on one DWN — the DWN of whoever owns that device. Alice's personal laptop writes to Alice's DWN. An Org X corporate server writes to Org X's DWN. Devices never move between DWNs.Cross-DWN visibility uses Permission Grants
When a device needs to be visible on a foreign network, the device's owner creates a Permission Grant on their DWN, allowing the foreign network to read that device's data. The foreign network creates a reference record pointing to the device on the source DWN. No data is copied or mirrored — the source DWN remains authoritative.
Authorization Model
Intra-DWN: Roles handle everything
Within a single DWN, no explicit Permission Grants are needed. The protocol's role system handles authorization:
memberrecord (recipient = Alice's DID) → gives Alice thenetwork/memberrolemember/noderecord (recipient = device DID) → gives the device thenetwork/member/noderolenoderecord (recipient = device DID) → gives the device thenetwork/noderole (for owner-provisioned devices)These roles grant read access to the records they need via
$actions:{ "role": "network/member", "can": ["read"] } { "role": "network/member/node", "can": ["read"] } { "role": "network/node", "can": ["read"] }Write access for devices comes from recipient authorization:
{ "who": "recipient", "of": "network/node", "can": ["create", "update"] } { "who": "recipient", "of": "network/member/node", "can": ["create", "update"] }Cross-DWN: Delegated grants for member devices reading a foreign DWN
Alice is a member of Org X. Alice's
memberrecord gives her thenetwork/memberrole on Org X's DWN. But Alice's devices have their own DIDs — they are not Alice. A device cannot directly invoke Alice's role.Solution: Alice delegates read-only grants to her devices. When Alice provisions a device for Org X's mesh, she creates a delegated grant allowing the device to read from Org X's DWN acting as Alice. The device signs the request with its own key, includes the delegated grant, and the DWN resolves the author as Alice.
This delegation is read-only. Devices never write to Org X's DWN acting as Alice. Their write operations (nodeInfo, endpoint) go to Alice's own DWN using their own
recipient of network/nodeauthorization.Cross-DWN: Permission Grants for foreign DWNs reading device data
Org X's nodes need to read Alice's device's nodeInfo and endpoint from Alice's DWN. Org X doesn't have a role on Alice's DWN.
Solution: Alice creates a Permission Grant on her DWN allowing Org X to read the device's subtree. Alice creates this grant at the same time as the
nodeRequest(see flow below), so Org X can immediately read the device's nodeInfo to make an informed approval decision.Authorization summary
recipient of network/node(device's own role)author of network(owner authority)recipient of network/memberPermission Grants are only needed for cross-DWN reads. Within a single DWN, the role system handles everything.
Membership and Device Approval
Joining a network — full flow
Step 1: Network owner invites member
Org X's admin creates a
memberrecord on Org X's DWN:recipient: Alice's DID{ label: "Alice", addedAt: "..." }network/memberrole on Org X's DWNStep 2: Alice proposes a device
Alice does two things simultaneously:
a) Writes a
nodeRequestrecord under hermemberrecord on Org X's DWN:{ "who": "recipient", "of": "network/member", "can": ["create", "delete"] }{ nodeDID: "did:jwk:aliceLaptop...", sourceDWN: "https://alice.dwn.example" }b) Creates a Permission Grant on her own DWN:
recipient: Org X's DIDscope:{ interface: "Records", method: "Read", protocol: meshProtocolURI, contextId: "aliceNetworkRecord/laptopNodeRecord" }delegated: true(so Org X can sub-delegate to individual mesh nodes)Because Alice creates the grant up front, Org X can immediately read the device's nodeInfo (hostname, OS, capabilities) from Alice's DWN to make an informed approval decision — e.g., using the hostname as the label.
Step 3: Org approves
Org X's admin creates a
noderecord under Alice'smemberrecord on Org X's DWN:{ "who": "author", "of": "network", "can": ["create", "update", "delete"] }recipient: the device's DID (did:jwk:aliceLaptop){ meshIP: "10.200.x.x", sourceDWN: "https://alice.dwn.example", addedAt: "..." }Step 4: Operational
Alice creates a delegated read-only grant for her laptop, derived from her
network/memberrole on Org X's DWN. The laptop uses this to read Org X's peer data. Alice manages this delegation herself — the org never needs to interact with individual device DIDs for read access.Adding more devices later
nodeRequeston Org X's DWN + creates a Permission Grant on her DWN for the new device's subtreemember/noderecordOwner-provisioned devices
For devices the org owns directly (corporate laptop, server):
noderecord at the top level (network/node) on Org X's DWNnodeInfoandendpointto Org X's DWN (authorized asrecipient of network/node)Member removal
When Org X removes Alice:
memberrecord → cascading deletion of allnodeRequestandnoderecords under itnetwork/memberrole is revoked → her delegated grants become invalidEither side can independently sever the relationship.
Cross-Organization Device Sharing
Org X owns a server. Org X wants Org Y's members to be able to reach it.
Constraint: Org X can only share devices they own (nodes on Org X's DWN). They cannot share Alice's personal devices — only Alice can grant access to those.
Sharing flow
Step 1: Org X grants access
Org X creates a Permission Grant on Org X's DWN:
recipient: Org Y's DIDscope:{ interface: "Records", method: "Read", protocol: meshProtocolURI, contextId: "orgXNetworkRecord/serverNodeRecord" }delegated: true(Org Y can sub-delegate to their nodes)Step 2: Org Y accepts and references
Org Y creates a reference record on Org Y's DWN (a
sharedNodeor similar record type undernetwork):{ nodeDID: "did:jwk:server...", sourceAnchorDID: "did:jwk:orgX...", sourceDWN: "https://orgx.dwn.example", meshIP: "10.200.x.x" }Step 3: Org Y grants reciprocal access
Org Y creates a Permission Grant on Org Y's DWN:
recipient: the shared server's DID (or Org X's DID, delegatable)scope: scoped to the specific node subtrees the server should seeStep 4: Operational
Revocation
Either side can unilaterally revoke.
Quarantine
Shared devices are quarantined by default:
Runtime Network Map Construction
For an owner-provisioned device on Org X
Reads from Org X's DWN:
network/node) → readnodeInfo+endpointdirectlynetwork/member/node) → followsourceDWNpointer, use delegated grant to readnodeInfo+endpointfrom member's personal DWNsharedNodereference, use delegated grant to read from source org's DWNFor Alice's personal laptop (member of Org X)
Participates in multiple meshes:
Each mesh has its own CIDR, so there's no address conflict. The engine builds a combined network map.
For a device shared from Org X into Org Y
Reads from Org X's DWN (its home DWN):
Protocol
$actionsSummarynetworkmember{ "who": "author", "of": "network", "can": ["create", "update", "co-delete", "co-prune"] }nodeRequest{ "who": "recipient", "of": "network/member", "can": ["create", "delete"] }member/node{ "who": "author", "of": "network", "can": ["create", "update", "delete"] }node(owner-provisioned){ "who": "author", "of": "network", "can": ["create", "update", "delete"] }nodeInfo{ "who": "recipient", "of": "network/node", "can": ["create", "update"] }(orof: network/member/node)endpoint{ "who": "recipient", "of": "network/node", "can": ["create", "update"] }(orof: network/member/node)Reading
All roles get read access to the records they need:
{ "role": "network/member", "can": ["read"] } { "role": "network/member/node", "can": ["read"] } { "role": "network/node", "can": ["read"] }Cross-DWN reads use delegated grants (for member devices reading a foreign mesh) or Permission Grants (for foreign DWNs reading device data).
Relationship to Other Issues
nodeInfo/endpointsplit and{ "who": "recipient" }authorizationnodeRequest→ approval flow — a pre-auth key automates the approval stepOpen Questions
Grant lifecycle automation: When Alice writes a
nodeRequest, she creates the grant on her DWN simultaneously. When she provisions a device, she creates the delegated read grant. The meshd client should automate both. How much should be automatic vs. user-prompted?Multi-mesh routing: A device in multiple meshes has multiple CIDRs. The WireGuard engine needs routing for all of them. This is a runtime/engine concern.
Context key delivery across DWNs: Encrypted records on a foreign DWN require context keys. The foreign DWN owner may need to deliver context keys to granted parties. The key-delivery protocol may need extension.
Subscription across DWNs: For live updates, devices need to subscribe to foreign DWNs using Permission Grants with
method: "Subscribe". The meshd subscription watcher needs to support multiple DWN connections.Shared node reference record type: The exact record type and schema for cross-org shared node references needs detailed design. Must contain source DWN endpoint, source anchor DID, device DID, and local mesh IP assignment.
Read visibility scope: For v1, all members see all other members and all nodes. Finer-grained visibility (team-scoped access) is a future enhancement.
Delegated grant mechanics: We are designing with the assumption that Alice can create delegated grants directly from her
network/memberrole authority — no explicit Permission Grant from Org X needed. The DWN should accept the delegation, resolve the author to Alice, and check her role. Spec clarification tracked in enboxorg/dwn-spec#49.