---
tags: DWN, proposal, interface
---
# [Proposal] DWN Tenants Interface
DWNs are multi-tenanted which means that a single DWN instance can receive/store messages associated to many DIDs. When sending a request to a DWN, the intended recipient is provided as the value of the `target` property. e.g.
```json=
{
"target": "did:ex:alice",
"messages": [...]
}
```
So, how does the receiving DWN know whether `did:ex:alice` is a tenant? More generally, how are tenants added/removed from a DWN? In order to support multi-tenancy, I think it may be helpful to introduce the concept of an **Operator**. An operator, identified by a DID, can be seen as an entity or individual that can add or remove tenants through an interface.
**How is the Operator DID provided to a DWN?**
As a configuration property
**How does authentication work for the operator?**
by including a signature as the value for the `authorization` property in the message. The signature must be a General JWS that meets the following requirements:
* The decoded payload must be a JSON object that contains `descriptorCid`
* `descriptorCid` must be a cbor-encoded, sha256-hashed v1 CID of the message `descriptor`
* the protected header must include:
* `kid` to lookup the respective public key in the operator's DID document
* `alg` to identify the algorithm intended for use with the key
* the signature must be produced with a key whose public key is present as a `verificationMethod` in the operator's DID document
## Interface Methods
### `TenantsAdd`
```json=
{
"descriptor": {
"method": "TenantsAdd",
"tenant": "did:ex:clifford"
},
"authorization": {
"payload": { "descriptorCid": CID(descriptor) },
"signatures": [{
"protected": {
"kid": "did:ex:operator#keys-1",
"alg": "OKP"
},
"signature": "..."
}]
}
}
```
* Sucessfully adding a tenant should produce a `201: Created` message result.
* Failure to provide `authorization` should produce a `401: Unauthorized` message result
* Failed auth should produce a `403: Forbidden` message result.
* Attemping to add a tenant that has already been added should produce a:
* `200: OK` :question:
* `400: Bad Request` :question:
### `TenantsRemove`
```json=
{
"descriptor": {
"method": "TenantsRemove",
"tenant": "did:ex:clifford"
},
"authorization": {
"payload": { "descriptorCid": CID(descriptor) },
"signatures": [{
"protected": {
"kid": "did:ex:operator#keys-1",
"alg": "OKP"
},
"signature": "..."
}]
}
}
```
* Successfully removing a tenant should produce a `200: OK` message result
* Failure to provide `authorization` should produce a `401: Unauthorized` message result
* Failed auth should produce a `403: Forbidden` message result.
* Attempting to remove a tenant that doesn't exist should produce a `400: Bad Request` message result.
## Tenant Authentication
Tenants of a DWN are not required to invoke capabilities in order to send any messages to that DWN. Similar to Operator authentication, a tenant must include a signature as the value for the `authorization` property in the message. The signature must be a General JWS that meets the following requirements:
* The decoded payload must be a JSON object that contains `descriptorCid`
* `descriptorCid` must be a cbor-encoded, sha256-hashed v1 CID of the message `descriptor`
* the protected header must include:
* `kid` to lookup the respective public key in the operator's DID document
* `alg` to identify the algorithm intended for use with the key
* the signature must be produced with a key whose public key is present as a `verificationMethod` in the operator's DID document
## Open Questions
**Who should the Intended Recipient be? a.k.a `request.target`**
The operator DID?
- That makes sense to me
**Should a tenant be able to remove themselves using `TenantsRemove`**?
I think so
- If they are added as a DID with data in the node, then we should treat it the same as any other
**What other Interface Methods might be useful and why?**
- TenantsLock: Disallow further activity in relation to a given DID, but retain the data/state
- TenantsBlock: wipe a DID, if data is present, and block it from having any presence in the node