Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add ability to generate delegations from spaces #180

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

travis
Copy link
Member

@travis travis commented Apr 17, 2024

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

  • align on design
  • write tests
  • write docs

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 [link to line]

TODO

- [] align on design
- [] write docs
@travis travis requested review from alanshaw and Gozala April 17, 2024 23:23
@travis travis marked this pull request as draft April 17, 2024 23:32
@Gozala
Copy link
Contributor

Gozala commented Apr 18, 2024

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
Copy link
Member

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
Copy link
Member Author

travis commented Apr 18, 2024

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
Copy link
Contributor

Gozala commented Apr 19, 2024

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
Copy link
Contributor

Gozala commented Apr 19, 2024

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
Copy link
Member

alanshaw commented Apr 22, 2024

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
Copy link
Contributor

Gozala commented Apr 22, 2024

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

  • Use w3 space recover with some temporary agent so that it can not be compromised.
  • Load target keys into w3 cli to avoid proxy agent, I was under impression there are env vars to do so, but perhaps that my wishful thinking.

@Gozala
Copy link
Contributor

Gozala commented Apr 22, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants