storacha-network / w3cli

💾 w3 command line interface
Other
30 stars 7 forks source link

feat: add ability to generate delegations from spaces #180

Open travis opened 4 months ago

travis commented 4 months ago

We needed to generate some delegations from the nft storage spaces to the nft storage agent principal.

This patch adds a --use-space-recovery-key option to the delegation create command. This option must be passed a "recovery key" generated during the space creation process. When used, delegation create will only be able to generate delegations that use the space as both the issuer and resource of all specified capabilities.

For example:

w3 delegation create --issuer-recovery-key "hamburger fiction this is not a real recovery key juice champion" did:key:z6MkkSc... --can 'upload/add' --can 'store/add' --can 'upload/get' --can 'filecoin/info' --base64

mAYIEALMc....

I'm not sure this is the right design - particularly interested in @gozala's take on https://github.com/web3-storage/w3cli/pull/180/files#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R359 - right now we need to sort of fake-out the w3client instance and I'm concerned it's resulting in larger-than-necessary proofs...

TODO

Gozala commented 4 months ago

Generally speaking asking user to provide a recovery key is probably a bad idea as it increases risk of it being compromised. That said I can not think of any better option since we do not want to manage private keys. Maybe we could hide the option from appearing in the --help so it can be used only in the rarest of cases where it is precisely the right thing to do.

alanshaw commented 4 months ago

Hmm, what about w3 space recover <key>? Take the key, delegate authority to the current agent and add the space i.e. do the remainder of the process that happens at space creation after the recovery key is generated.

Alternatively w3 space add --recover <key>?

Then you can just create delegations as usual?

travis commented 4 months ago

Generally speaking asking user to provide a recovery key is probably a bad idea

Hmm, what about w3 space recover <key>?

SO - what if w3 space recover either:

  1. prompts for a key unless the user passes a --recovery option that is discouraged in the documentation (recommended only for use in non-interactive cases like CI) OR
  2. reads from stdin when the user passes --no-prompt

Neither of these lets me create a delegation directly from the space, but maybe that's ok? It is probably generally better to have the delegation flow through a user agent principal, so we have a record, I guess?

In any case adding w3 space recover addresses my immediate need and can - I think - address @Gozala's concerns - what do you two think?

Gozala commented 4 months ago

Neither of these lets me create a delegation directly from the space, but maybe that's ok? It is probably generally better to have the delegation flow through a user agent principal, so we have a record, I guess?

I think it really depends on the use case. If you're ok with agent potentially revoking that delegation in the future, that sure that is how I would go about it. However I was under impression that is what we did not want, in which case agent in the middle is a bad idea.

The rule of thumb I would say is if you aud is did:mailto you probably don't want agent in the middle. If it is did:key likely agent in the middle is ok.

In any case adding w3 space recover addresses my immediate need and can - I think - address @Gozala's concerns - what do you two think?

Do we have nft.storage agent keys if so probably it would be best to make agent with that key and then do space recovery that way you'll end up with space → nft.storage. If we do not have keys and you're own agent is going to be in the middle space → travis → nft.storage that is probably not a good idea. You could also do a one off agent to do this and discard keys in which case space → proxy → nft.storage is probably fine.

P.S. please note that I think by default space authorized agent for 1 year or so if we want indefinite auth we probably need to go about this differently.

Gozala commented 4 months ago

More broadly if we want to do this kind of thing space → proxy → target without introducing potential security risk one could go about it in a following way

const payload = new TextEncoder().encode(`WELL KNOWN NONCE ${target.did()}`)
const secret = await space.signer.sign(payload)
const proxy = await ED25519.derive(secret.raw.subarray(-32))

This way we've derived a proxy that we can derive in the future as long have space keys. So it's effectively a direct delegation except more anonymous

alanshaw commented 4 months ago

More broadly if we want to do this kind of thing space → proxy → target without introducing potential security risk one could go about it in a following way

I'm not sure I understand the security risk?

I think it's important to be able to restore a space, separate to the immediate issue. If we can't restore a space I don't really understand why we have the UX in the CLI of generating mnemonics. So adding this functionality allows Travis to get what he needs to do done, not bother me anymore AND benefit the community. I feel this is win all round.

Since we have the private key for the space, I assume we can revoke anything travis (or proxy or anyone else) delegates, right?

We also (obviously) have the private key for the agent used in the NFT.Storage API...but I don't think we have any functionality for loading it in the w3 CLI. Maybe Travis could add that as well but I'd wager we'd consider that scope creep and I would say that adding w3 space recover and restoring the space under travis' agent (or preferably a throwaway agent i.e. use W3_STORE_NAME to create a new one) is probably good enough for now.

Gozala commented 4 months ago

I'm not sure I understand the security risk?

More links in the chain means more potential for one of them getting compromised. It is probably a bad idea to have middle node that belongs to someone unrelated to both origin or target.

I'm not opposed to doing something with w3 space recover it is there for a reason, which is recover access to the space with the agent. I think best course of action is to either

Gozala commented 4 months ago

Since we have the private key for the space, I assume we can revoke anything travis (or proxy or anyone else) delegates, right?

Yes, that is post-compromise recovery, which is available.