# W3 Identifiers
## Spaces
We identify **mutable** spaces via [DID] URIs, because unlike any other identifier they have provable ownership, which is really important for mutating them in an open, trustless protocol. Specifically only owner of the space can authorize mutation by delegating capabilities through [UCAN]s.
> ℹ️ Space is just collaboration tool allowing groups of agents to cooperate on. It is a **name** space and not a memory space or a compute space, although those could be abilities that space can aquire through `memory` and `compute` providers.
>
> In order to enable cooperation participating actors need to prove they had been invited to do so by space owner, which is why we need provable ownership.
I think it is a good idea to think of the space as an [IPNS] or an [MFS] - A mutable pointer to an IPLD DAG. We may not have an actual materialized IPLD DAG for a space but we do define set of capabilities for querying and updating mutable pointer to transformed revisions.
> You can think of compute as a sub-DAG, a map where keys are invocation CIDs and values are results of that computation.
In theory anyone could query CID _(that space corresponds to)_ using same set of capabilities without owners permission. It is resolving and updating a pointer what requires permissions.
### Rationale
For example consider following UCAN delegation and ponder how can arbitrary validator tell whether `iss` is owner of the resource `file:///alice/photos/` to issue such a delegation ?
```json
{
"iss": "did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi",
"aud": "did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob",
"att": [
{
"with": "file:///alice/photos/",
"can": "file/write"
}
]
}
```
On the other hand following delegation is self-evident to any validator, because resource (`with`) matches issuer (`iss`) and UCAN signature must be from the issuer key, wihch provides cryptographic proof that resource owner has authorized the delegation.
```json
{
"iss": "did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi",
"aud": "did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob",
"att": [{
"with": "did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi",
"can": "file/write",
"nb": { "at": "/alice/photos/" }
}]
}
```
> ℹ️ Also note that in the first example we had captured space semantics (like "file system" as opposed to "communication system") in both URI schema `file://` and UCAN ability namespace `file/`
### Considered alternatives
We could have addressed resource ownership in a different way for example using autority fragment of the [URI] like illustarted in the following example
```json
{
"iss": "did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi",
"aud": "did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob",
"att": [
{
"with": "file://z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi@/alice/photos/",
"can": "file/write"
}
]
}
```
With such approach validator can still deduce that issuer (`iss`) has authority over a resource (`with`) because issuer key matches resource authority (`z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi`).
However this approach has couple of downsides:
1. It makes it possible to have invalid delegations e.g. `file://` resource (`with`) coupled with `message/send` ability (`can`). In other words it would create more error surface to deal with.
Note that use of [DID] in resource does not have that problem because semantics are in the ability namespace `file/` and not in the resource.
2. Some URIs do not have authority (despite URIs specification), in pratice this means built-in parsers normalize some by stripping authority out which can lead to problems in the wild. E.g. browsers will normalize URI from the example into `file:///alice/photos/`.
3. In the end we still have to parse URI to exract `authority` & `path` from it. Our approach is basically parsed version `authority` is a resource (`with`) and `path` is the `nb.at` eliminating problems that could arise through incompatible parsers across languages and limitations around what character set can be used in `auhority`.
Finally there is one other alternative that has been considered which avoids some of the issuen from the above
```json
{
"iss": "did:key:z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi",
"aud": "did:key:z6MkffDZCkCTWreg8868fG1FGFogcJj5X6PY93pPcWDn9bob",
"att": [
{
"with": "https://z6Mkk89bC3JrVqKie71YEcc5M1SMVxuCgNx6zLZ8SYJsxALi@web3.storage/alice/photos/",
"can": "file/write"
}
]
}
```
Because it is an HTTP(S) URL authority semantics are well defined which we can embrace to avoid URI parsing issues and we avoided enconding semantics in the resource which gives us robustness. However we still end up just encoding path in the resource which needs to be parsed out as opposed to just encoding parsed version.
More importantly we have also introduced depndency on DNS, which implies that we can not represent capability of writing a file into my laptop which does not have domain name. This is not moot point as it turns protocol from trustless to one requiring it & limits participation.
We could define another URL schema e.g. `space://` that requires no DNS (and is similar to `ipns://`), but it's unclear what it will get us besides whole lot of work for specing and standardizing it. It would allow us to encode `authority` and `path` together but introducing additional parse is somewhat questionable benefit, not to mention that for some capabilities `path` may not even make sense.
#### Provable ownership in data
It is worth calling that important detail is provable ownership & that is certainly possible to do it at the data layer. For example IPLD DAG could encode permissions at each node which can be consulted to validate ownership. In fact [DID] documents could also be resolved to identify who can modify it (even if spec is bit fuzzy on how).
While it's very reasonable to go this route, it does introduce a mutable state into a system. Ownership becomes non-straigtfoward one needs to do out-of-bound resolution to decide, furthermore mutable owenership in untrusted settings would often require centralization to handle races and network partitions.
Added complexity does outweight the benefits for the web3.storage. It seems better to pursue some of those benefits in a different way e.g. we could embed permissioning into DAGs by introducing interior mutability through [did:key] pointers.
[DID]:https://www.w3.org/TR/did-core/
[did:key]:https://w3c-ccg.github.io/did-method-key/
[UCAN]:https://github.com/ucan-wg/spec/
[URI]:https://en.wikipedia.org/wiki/Uniform_Resource_Identifier
[Robustness principle]:https://en.wikipedia.org/wiki/Robustness_principle
[namespace]:https://en.wikipedia.org/wiki/Namespace
[MFS]:https://docs.ipfs.tech/concepts/file-systems/
[IPNS]:https://docs.ipfs.tech/concepts/ipns/