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

FLIP 198: Authorized Call #198

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

SnowyField1906
Copy link

Objective

The objective of this FLIP is to introduce the "Authorized Call" feature, which allows functions to be marked as private unless they are called with a specific prefix.

This feature aims to enhance access control in Contracts, providing developers with more flexibility and fine-grained control over function visibility based on caller Contracts.

Motivation

Flow introduced Cadence, a Resource-Oriented Programming Language which works towards the Capability system, it replaced msg.sender and proved to be effective for small projects.
However, as projects grow in size and complexity, the efficiency of the Capability system decreases compared to the use of msg.sender.

Besides, The existing access control mechanisms is relatively simple, they have limitations when it comes to defining private functions that can only be accessed under specific circumstances. This can make it challenging for developers to enforce strict access control rules in complex projects.

@turbolent
Copy link
Member

turbolent commented Sep 19, 2023

Thank you for opening this FLIP Thuận!

From what I understand, the FLIP proposes to introduce a "capability-based msg.sender equivalent" – the auth value is basically a capability (in the traditional sense).

Such a mechanism was previously proposed in a slightly different form: onflow/cadence#423 proposed adding an AuthAccount.Identity value, which could only be obtained from an AuthAccount. Similar to this FLIP's auth value, a &AuthAccount.Identity reference (value) could be passed around to functions and used to perform access control.

The FLIP for that future, onflow/flow#945, was eventually rejected.
Have you had a look at the Cadence GitHub issue and the FLIP before?

@dsainati1
Copy link
Contributor

In addition to Bastian's feedback, any changes to access control need to account for the upcoming Entitlements feature, which is outline in https://github.com/onflow/flips/blob/main/cadence/20221214-auth-remodel.md and https://github.com/onflow/flips/blob/main/cadence/20230623-entitlement-improvements.md. The old access control model will be obsolete within a matter of months, so there is little point in changing it unless those changes also translate to the new entitlement-based model.

@SnowyField1906
Copy link
Author

Thank you for the responses.

Firstly, I think this FLIP is more powerful in some aspects. At least, one of the implementations mentioned in the FLIP would be helpful.
I totally understand that Cadence puts Capability on top and everything should work towards it for various reasons, but honestly, this should not for all. I mean, in some unnecessary cases, this is totally annoying and counterproductive.

To me, if a contract is dominated by Capabilities, it is also dominated (dependent) by accounts (because Capabilities and Resources are obtained from them). This is the main difference, while this mechanism aims to release part of the contract from such things (related to accounts).

Anyway, this is just an alternative option. Combining both would have given a good result, and developers will know which is most suitable for their projects.

I have read that FLIP just now, but I'm still confused that it was rejected because there are problems in that FLIP or Cadence is sensitive to this mechanism. After all, since my FLIP is quite different, I would love to know the reasons why this should not be done.

@turbolent
Copy link
Member

@SnowyField1906

Thank you for your thoughts!

First, I want to reply to some of them and go into "why capabilities" and "why not identity-based access control".

Firstly, I think this FLIP is more powerful in some aspects. [...] in some unnecessary cases, this is totally annoying and counterproductive.

In what aspects is the proposed feature more powerful than the current access control API based on capabilities and entitlements, and in what way are these APIs annoying or even counterproductive? Do you have some examples?

The capability-based access control API was just recently improved by introducing Capability Controllers, after a long discussion with lots of input from the community, and entitlements are also an improvement over the previous feature of refining access using interfaces based on restricted types.

It would be great to hear how these improvements are not working out for you, especially given you mentioned a "scalability issue" for larger / more complex contracts.

To me, if a contract is dominated by Capabilities, it is also dominated (dependent) by accounts (because Capabilities and Resources are obtained from them). This is the main difference, while this mechanism aims to release part of the contract from such things (related to accounts).

Can you elaborate on that? The motivating example, granting access to a function, seems to be about "account access" by nature. What do you mean with "release part of the contract"?

Anyway, this is just an alternative option. Combining both would have given a good result, and developers will know which is most suitable for their projects.

The goal of Cadence is to provide a language to developers that is useful and safe. By design, it omits many features that are known to be unsafe (e.g. raw memory access) and provides features that allow developers to write safe programs (e.g. static type system). For any feature, there is always a trade-off between safety and convenience. Given that access control is a critical part of a smart contract, adding a feature that is potentially more convenient, but also leads to more bugs, does not align with Cadence's values.

Often it is also the case that developers are not necessarily familiar with all security nuances of an aspect of smart contract development (e.g. here, access control, but also e.g. random number generation): They might be unaware of the short-comings of identity-based access control, or the issues with reverting random numbers.

But neither should they! Cadence's goal is to provide tools to write useful programs, but also safe developers from mistakes. By providing safe features and guiding developers into using them, even inexperienced developers are able to write useful and safe contracts.

Adding alternatives which appear more convenient, will attract developers, likely making the "power user" feature the first stop. To many developers the convenient solution may appear as the better solution, and they are likely unaware of the short-comings.

In addition, having multiple features to achieve the same goal adds complexity. It will be hard for developers to reason about how the proposed functionality interacts with the existing functionality.

I have read that FLIP just now, but I'm still confused that it was rejected because there are problems in that FLIP or Cadence is sensitive to this mechanism. After all, since my FLIP is quite different, I would love to know the reasons why this should not be done.

The FLIP was rejected, because the access-control model that the functionality in that FLIP and in this FLIP is based on, identity-based access control has many short comings and is known for many security issues for decades. For example, see:

Security aside, Cadence encourages composability, but identity-based access control kills composability.

Regarding the FLIP in particular:

  • In the motivation section you are giving some examples for how capability-based access control can be used to implement the example use-case. Could you please add how the use-case would be implemented using the feature proposed in the FLIP?

  • In the prior art section, maybe link to the previous GitHub feature request and rejected FLIP that I shared in my previous comment.

  • The prior art section states:

    This works similarly to the msg.sender in Solidity (not tx.origin)

    In the previous FLIP, the program/developers passes a token/value which represents the identity of one of the signers from one function to another.
    From my limited understanding, this is equivalent to the behaviur of tx.origin in Soldity.

    Does the behavior in this FLIP differ? It is not quite clear to me what the value of auth.address is in a contract function of a deeper call-chain.

    For example, let's assume transaction A, signed by 0x1 and 0x2, calls a function of contract B.
    Is auth.address inside of the B function 0x1 or 0x2, depending on how the function was called?

    Further, if contract B, e.g. deployed at 0x3, then performs another call of a function in contract C, e.g. deployed at 0x4.
    What is the value of auth.address in the function inside of contract C Is it still 0x1/0x2, or 0x3?

Thank you again for your contributions into making Cadence better 👍

@bluesign
Copy link
Collaborator

I think the question is; what is the practical use case to prefer identity to capability ?

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

Successfully merging this pull request may close these issues.

None yet

4 participants