Open dlongley opened 3 years ago
we already use POST
/documents for creating documents, so we need another endpoint ... which is what POST /query is for. All we are really doing, however, is trying to do a GET /documents with some parameters that filter what we're reading.
Be that as it may - we still need to model a capability for running queries. There is no GET {vaultID}/documents
endpoint for the reasons you stated. We still need to protect this /query
endpoint. We could add the /query
endpoint as an invocation target to the zcap.
How POST /encrypted-data-vaults/{vaultID}/query
composes with GET /encrypted-data-vaults/{vaultID}/documents/{docID}
is another question. Should they?
We are interested in the reversed use case compared to the one you described: a third party has been delegated a capability to read
a subset of documents in the EDV. For efficiency's sake:
If an invoker is NOT capable of query
then their invocation of /query
is simply rejected.
The more interesting question is - what should be the behavior if an invoker has the capability to query
but only read
a certain subset of the matching documents? I assume allowedAction
are orthogonal among themselves and should be composeable (we sorely lack a ZCAP spec for this....). How do we protect the EDV from unnecessary work?
https://github.com/decentralized-identity/confidential-storage/pull/156 adds example implementation with a single method "verifyInvocation" which can be configured to handle all endpoints that are supposed to be protected.
@llorllale can you propose the structure of the requested capability that would be invoked by the third party in JSON on this thread?
Discussed on July 8, 2021 WG call:
I would say that the expected root capability for querying would be the same as the one for the /documents endpoint; you must be able to read all documents to be permitted to perform a query. So, if you have a capability to read from
/documents
you can use that capability for querying. I don't think it needs to be more complicated than that. And, IIRC, this is how current implementations handle it.I think this is only a little bit tricky because of HTTP mechanics and the ever present debate over patterns/anti-patterns in RESTful architectures. To perform a query, we need to be able to send our query somewhere. But the query may be too large, or it just too awkward, to include that query in the URL itself as query parameters. This means using an HTTP body. But we already use
POST <edvId>/documents
for creating documents, so we need another endpoint ... which is whatPOST <edvId>/query
is for. All we are really doing, however, is trying to do aGET <edvId>/documents
with some parameters that filter what we're reading. This is why having the ability to "read" from<edvId>/documents
fits with querying.