So, we have this very reasonable feature request (#560), people want to delete things.
The only problem is, a few people have been putting their API tokens in their web frontends. Not a lot, but enough of them that we don’t want to go and give those keys the ability to destroy user data and we doubt this pattern of behavior will go away no matter how many warnings we might try to put on it.
We also have another very reasonable feature request (#571), people want to do a one-time-use signature for an upload so they can guard their token in their backend without having to proxy the upload.
We’ve also wanted to get wallet auth for a long time (https://github.com/nftstorage/nft.storage/issues/619) and we’ve made progress on a prototype for a MetaPlex integration (https://github.com/nftstorage/nft.storage/issues/431) that is giving us a much better understanding of the developer ergonomics.
We also have a bunch of finer grained permissions we’d like to do that we’ve explored as token scoping (#314).
We’ve also had requests for a feature, similar to Pinata metadata, that would allow users to tag their uploads with metadata they can query against in the service.
Finally, we want to get an API going for mutable references and keep it open to multiple decentralized mutable naming/reference systems in the future (#511).
API PubKeys
- Users create a public/private keypair locally and add the public key to their account as an API PubKey.
- An API PubKey is tied to an account, same as a token is today.
- An API PubKey is given explicit permission grants for each service feature it can use:
- PUT
- DELETE
- TAG:{NAMESPACE} (details below)
- The signer signs a message with even more fine grained permissions and tags (see below) that functions as a one-time-use token.
- PUT:{CID}:{CARHASH}
- DELETE:{CID}:{CARHASH}
- TAG:{NAMESPACE}:{ USERNAME | USER WALLET ADDRESS | CHAIN | ETC }
- TIMESTAMP
This resolves #571 (one-time-signature), #560 (deletes), and has pretty obvious future extensions to handle everything in #314 (token scoping).
Tagging
Since tags have to be in the signature they are secured by the developer’s private key and can’t be tampered with by the end-user.
The thing that sucks about tagging is that it’s in our database, which is not decentralized. But, we could just write this data to a chain. It’s quite small.
Since the TAG:{NAMESPACE}
is an explicit permission grant the developer sets in their acocunt, we could allow developers to configure our service to write data into specific protocols set on each namespace.
I can easily imagine a feature in which we mint an NFT for each USER/TAG:{NAMESPACE}
and use https://github.com/Gozala/ipnftx/blob/main/Readme.md to write this into the chain. Then developers can use the DID of the NFT as a reference rather than anything specific to our service, and if they ever leave the service we can just transfer the NFT to them. You could imagine doing the same thing if you wanted to attach an IPNS or ENS client to a tag namespace, but we’d need to do some key custody for that so we shouldn’t take it lightly (maybe next year).
I’ve been talking about these as “tags” but we could also have a feature called /last
which would function as a mutable reference to the last tag.
In the integrations we do like Metaplex, we could embed the wallet address and signature and all the other data we want to use in order to control abuse in these endpoints that are open to any wallet signature.
This may sound like a bunch of features all jammed together, and therefor a lot of work, but it’s actually not. This is actually pretty simple and relatively boring security (we should consider just using hawk https://github.com/mozilla/hawk).
It also has some obvious incremental steps we can break it into and deliver user value along each step without getting stuck in a long timeline, and some good alignment with where we want to go long term (everything in the service is just a passthrough to a decentralized protocol or an index of it).
kind/enhancement need/triage need/go-nogo-decision stack/api-protocols