---
# System prepended metadata

title: '[Proposal] DWN Tenants Interface'
tags: [' proposal', DWN, ' interface']

---

---
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