Conversation
Can we just send an additional delegation along with this invocation? The issuer of the Separately, maybe: is the retrieval is an effect? It appears to be part of the process of |
Yes in this case we can do that assuming we're ok with charging the user for egress. It's a bunch of work to add to two clients, the upload service and the indexing service though...
Um yeah I guess it is an effect, but it's not async - it'll have been completed by the time the response is received. I don't think this has bearing on passing authority like you say. |
|
Just want to check my understanding here. The idea is that services can request capabilities on-demand from other service using Aim here is to replace pre-configuring long-lived delegations, like what we do in piri for the indexing, upload, and egress service? |
|
I'm not really following how this will work - could you add an example of the full flow somewhere to really spell it out? I think the client will need to send an |
Ah, and there's the rub. Are we? Are we not? Is there something so special about this principal retrieving the index data that it shouldn't incur a charge? Or is there something special about index data such that it should be freely egress-able? Or is the amount of egress here so minimal that it's not worth making exceptions?
It certainly is, but this sounds like a lot of work too. I'm not sure there's a way around that. |
Or we can filter out receipts/invocation during egress consolidation that are related to these sorts of events. |
I think it's possible, but not easy to distinguish. |
hannahhoward
left a comment
There was a problem hiding this comment.
Broadly I agree with all of this.
One thing we don't get into here are session lengths -- IOW, if I call access/authorize, how long lived is my delegation? I believe for the original protocol access/authorize on the upload service issues a delegation that is quite long lived. I would think there there's not a huge issue in continuing to re-authorized periodically.
Overall, very reasonable direction I concur.
rfc/service-auth.md
Outdated
|
|
||
| ### Add `blob/retrieve` "service" capability | ||
|
|
||
| I'm proposing `blob/retrieve` as a new capability that allows retrieving a blob in full. It will be used for internal operations like replication, repair, indexing and filecoin onboarding - egress MUST NOT be recorded for these invocations. |
There was a problem hiding this comment.
the current replication protocol contains a blob/replica/transfer invocation, which is issued as a fork in the receipt for blob/replica/allocate. was the intent there to have that be actually send from the node that will receive the replica to the source node in order to replicate? If so maybe for at least that case no new capability is needed. I never was quite sure what blob/replica/transfer was for (other than maybe it was to simply track the copying)
There was a problem hiding this comment.
It is for tracking the copying.
The storage node has no authority to invoke blob/replica/transfer on the node hosting the data, so we still need to get a delegation for doing so.
In this case (from the review here) Hannah is ok with the customer paying egress. The point is more that there are instances where it "is intended" to be free, or where the customer isn't around to provide a new delegation - like a new filecoin SP retrieving data because a deal has expired and the previous SP is not taking deals anymore (i.e. you can't "re-use" the data).
Not more so than, for example, it being free because you asked for it to be replicated. i.e. this would be - it was free because you asked for it to be indexed. It seems a little arbitrary - personally I would always charge the customer for egress. However there does seem to be a need to authorize access to data that does not originate from the client. Or rather, a mechanism that isn't a long lived delegation from the customer made in advance. Determining whether we charge for the invocation is not the goal of this RFC. Holding a long lived delegation ties us in knots - we have to keep it safe forever ($$$) and when we need to change that delegation (add a new capability for example) we can't bring everyone with us, because we can't simply "get a new one" from all the customers. The idea here is that we're leveraging authority over data by virtue of holding (hosting) it. This is different from the customers' authority over the data. 🤷♂️ perhaps it's a bad idea, but the proposal to mitigate concerns is that delegations would be issued only when the context is known and verified i.e. the
Yes I anticipate around the same amount of work either way but I'm betting on doing this saving us work, maintenance and problems in the future. |
Typically you'd use the delegation you receive as proof in an invocation. So yes, you'd be "sending them back", but you'd also hold on to them so you can use them in subsequent invocations. Here's how it might work if the indexing service were to request an authorization from a storage node for accessing an index for caching and adding to IPNI: sequenceDiagram
participant customer
participant uploadService
participant indexingService
participant storageNode
customer->>uploadService: space/index/add
uploadService->>indexingService: assert/index
indexingService->>storageNode: access/authorize { can: "blob/retrieve", cause: cid(assert/index) }
storageNode->>indexingService: { ok: Delegation(blob/retrieve) }
indexingService->>storageNode: blob/retrieve { blob: zQm... }
storageNode->>indexingService: bytes(sharded DAG index)
indexingService->>uploadService: { ok: {} }
uploadService->>customer: { ok: {} }
Subsequent invocations from the indexing service to the same storage node can use the same delegation. |
Yes, good question. IIRC the eventual attestation is valid for 1 year. For this I was thinking to delegate for a much shorter time - 1 hour seems reasonable. |
Yes correct. I actually thought of this because of your comment here #67 (comment)
I would say it's a welcome side effect. |
|
I like this proposal, thank you for putting it together. A couple ideas that come up:
{
iss: 'did:key:zStorageNode',
aud: 'did:web:billing.storacha.network',
att: [{
can: 'access/authorize',
with: 'did:key:zStorageNode',
nb: {
// requested capabilities
// Note: `with` is implied (did:web:billing.storacha.network)
att: [{
can: 'space/egress/track',
nb: {
// can be specific or open ended
}
}],
}]
}I see the billing service querying the registrar service to know whether the node is properly registered in the network before authorizing egress tracking. |
frrist
left a comment
There was a problem hiding this comment.
Love this.
Maintaining long-lived delegations in Piri's config has been a pain, so I'm really happy to move away from this pattern. We might even be able to remove the delegator/registrar entirely, or at least strip out the piece where it generates and receives delegations from nodes.
On session length, this seems like our main lever for improving request latency. I'd rather not re-authorize on every retrieval request since that could add hundreds of milliseconds or even full seconds, which feels like a non-starter.
|
Ohhhh. I misread the RFC. I understand now:
As for the expiration date, I think we could arguably make them non-expiring, or at least expiring far in the future. The only principal who cares is the storage node itself. If it decides to stop trusting the invoking service at some point and wants to revoke its delegation, it won't have any trouble telling itself about the revocation. That should make this extra loop negligible in performance cost. |
|
Oh, also notable: you don't actually need to include the delegation, just the CID. That means the invoking service doesn't need to store or send the whole delegation, if we can expect the service nodes to retain them themselves. Technically, they don't even need to send the whole delegation over in the first place, not that it's many more bytes for something that happens very occasionally. |
refs storacha/RFC#68 Since `access/authorize` is a capability that already exists and has semantics that vary slightly from what is proposed in the RFC I have named the capability `access/grant` which is roughly similar but different enough that we won't confuse the two. --------- Co-authored-by: Vicente Olmedo <vicente@storacha.network>
Adds the `blob/retrieve` capability as proposed here storacha/RFC#68
This PR add a `blob/retrieve` capability handler for service retrievals (see storacha/RFC#68). It is very similar to the `space/content/retrieve` handler except it does accept byte range requests, only allows invocations where the resource is the service itself and is not associated with any egress billing.
This PR add server side support for authorized retrievals. This involves 2 different authorized retrieval types: 1. Users can send a delegation for retrieving data from a space (per #249) and it will now be used by the indexer to make a UCAN authorized retrieval (`space/content/retrieve`) from the relevant node (if not cached). 2. When an upload service invokes `assert/index`, the indexer will now obtain a service delegation from the node that is storing the index (using `access/grant`) before making a UCAN authorized retrieval (`blob/retrieve`) to obtain the index. See storacha/RFC#68 for details of on-demand service retrievals. --------- Co-authored-by: Vicente Olmedo <vicente@storacha.network>
This PR adds support to the client library for authorized retrievals. Essentially it allows one or more delegations to be attached to the query, that are sent in a HTTP header `X-Agent-Message`. This PR also adds server side support for authorized retrievals. This involves 2 different authorized retrieval types: 1. Users can send a delegation for retrieving data from a space (per #249) and it will now be used by the indexer to make a UCAN authorized retrieval (`space/content/retrieve`) from the relevant node (if not cached). 2. When an upload service invokes `assert/index`, the indexer will now obtain a service delegation from the node that is storing the index (using `access/grant`) before making a UCAN authorized retrieval (`blob/retrieve`) to obtain the index. See storacha/RFC#68 for details of on-demand service retrievals. --------- Co-authored-by: Vicente Olmedo <vicente@storacha.network>
|
Anything blocking this from merging? I'd like to start referencing the RFC directly in convo's 🙏 |
📖 Preview
Authorizing services to talk to each other is happening more and more often as we build out the network. Our current approach is to pre-authorize services, storing long lived delegations for use when needed.
This is becoming onerous, and this PR proposes one solution - on-demand authorization.