Skip to content

API for bootstrapping Capabilities #1951

Closed

Description

Issue To Be Solved

After onflow/flow#945 was rejected, we still lack a clean solution for the use case of bootstrapping Capabilities (which is outlined in a comment on that FLIP). We'd like a dedicated API for creating a capability (or for a general value) and giving it to a specific user in a secure and asynchronous manner.

The original comment (from @dete) is replicated here:

Here is the problematic use case. I'll describe possible solutions (including one using an Identity object) afterwards.

I have a project that requires some amount of human oversight, maybe something as simple as a "pause" button that lets me block activity in the smart contract temporarily in response to a bug or market panic. As such, I have an administrator capability in my account that gives me access to call the "pause" function if necessary.

In time, Bjarte joins my team, and I decide that it'd be useful if his account could also call the "pause" function in case I'm sleeping when the emergency happens. I'd like to send him a Capability for the same Admin object that I have. How do we get the Capability into his account securely?

One possible solution: Co-signing

One solution (which is possible in Cadence today) is for Bjarte and I to both sign a single transaction. That transaction can create/copy the Capability using my account, and then store it in his account.

This solution is workable, but awkward. In particular, it has a coordination problem. Both Bjarte and I have to be online at more-or-less that same time in order to both sign the shared transaction within the expiry window.

Another solution: The Dropbox

Another answer would be for me to create the Capability for Bjarte whenever it suits me and then "leave it somewhere he can get it at his convenience". But where do I leave it that doesn't allow a stranger to intervene?

Ideally, I'd have a public function on my account that returns that Capability, but only if the caller provides Bjarte's Identity.

To be clear: I don't love this use case, because once the Identity object exists people might start using it in other cases, and if it's used frequently, in a variety of ways, it could open the window for attacks. For example, perhaps a malicious actor notices that I've posted a Capability for Bjarte before Bjarte himself notices it. That attacker could offer him "1000 free FLOW!" using a different Dropbox object that asks for his Identity. But instead of returning the 1000F, the malicious Dropbox object uses Bjarte's Identity to grab the Admin Capability I was offering and transfer it to the attacker!

The problem with an Identity object in a capability-based security system like Cadence that sharing the Identity object is transitive. I'm not just proving my identity to a smart contract when I pass it my Identity, I'm temporarily allowing it to impersonate me!

We'd really need wallets to carefully restrict the use of the Identity object to scenarios where they explicitly check the type of the Resource they are passing the Identity to in the transaction itself, and ensuring that the type they see is on a short list of known-safe Dropbox implementations (ideally one!).

Unfortunately, I don't really have a better solution for bootstrapping a new Capability setup that doesn't suffer from the coordination problem of double-signing. I'd love to hear other suggestions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions