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

Allow list with cohort and auth admin roles #341

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

Conversation

vzotova
Copy link
Member

@vzotova vzotova commented Jan 20, 2025

Type of PR:

  • Bugfix
  • Feature
  • Documentation
  • Other

Required reviews:

  • 1
  • 2
  • 3

What this does:

High-level idea of the changes introduced in this PR.
List relevant API changes (if any), as well as related PRs and issues.

Issues fixed/closed:

  • Fixes #...

Why it's needed:

Explain how this PR fits in the greater context of the NuCypher Network.
E.g., if this PR address a nucypher/productdev issue, let reviewers know!

Notes for reviewers:

What should reviewers focus on?
Is there a particular commit/function/section of your PR that requires more attention from reviewers?

@vzotova vzotova self-assigned this Jan 20, 2025
@vzotova vzotova changed the title [WIP] Allow list with cohort and auth admin roles Allow list with cohort and auth admin roles Jan 20, 2025
@vzotova vzotova marked this pull request as ready for review January 20, 2025 21:03
Copy link
Member

@derekpierre derekpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So based on @cygnusv 's comment in Discord:

Maybe we can just add a flag to disallow setting auth admins, so with the flag off the contract simply behaves as a normal global allows list. The point would be to have a single type of contract

The "flag" at the moment, is really just either using the GlobalAllowList or the ManagedAllowList as the accessController for a Ritual. Correct?

tests/test_managed_allow_list.py Outdated Show resolved Hide resolved
}
function grantAuthAdminRole(uint32 ritualId, address account) external {
initializeCohortAdminRole(ritualId);
grantRole(ritualRole(ritualId, AUTH_ADMIN_BASE), account);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So just to confirm, if the ritual authority calls grantRole() directly without having first called initializeCohortAdminRole(), the call will fail.

But, if the ritual authority either:

  • makes the two separate calls in here themselves directly
    OR
  • calls grantAuthAdminRole()

then granting the role will work correctly.

Copy link
Member

@derekpierre derekpierre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving (assuming my clarifications were correct) - nice work 🎸 !

Copy link
Member

@cygnusv cygnusv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still digesting

@vzotova vzotova force-pushed the new-allow-list branch 2 times, most recently from a2bf89c to 86c48c3 Compare January 27, 2025 14:56
Copy link
Member

@cygnusv cygnusv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More comments. There's still a design issue we need to address before moving forward.

require(address(_subscription) != address(0), "Subscription cannot be the zero address");
subscription = _subscription;
constructor(Coordinator _coordinator) GlobalAllowList(_coordinator) {
_disableInitializers();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GlobalAllowList constructor already _disableInitializers(), but I guess we do it just in case this dependence is removed, right? In any case, calling it twice doesn't do any harm. Just double-checking on this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a habit, I'll remove it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

_grantRole(cohortAdminRole, authority);
}

function grantAuthAdminRole(uint32 ritualId, address account) external {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need some docstrings here saying that this can only be called by the cohort admin

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be sure: this contract is removed because it was only used in the old ManagedAllowList and we already have AbstractSubscription.sol, correct?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, Old Subscription contract was there just as reference (and mostly to compile old ManagedAllowList)

import "./GlobalAllowList.sol";
import "./Coordinator.sol";
import {UpfrontSubscriptionWithEncryptorsCap} from "./subscription/Subscription.sol";

/**
* @title ManagedAllowList
* @notice Manages a list of addresses that are authorized to decrypt ciphertexts, with additional management features.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @notice Manages a list of addresses that are authorized to decrypt ciphertexts, with additional management features.
* @notice Manages a list of addresses that are authorized to encrypt ciphertexts, with additional management features.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✔️

subscription.authorizationActionsCap(ritualId, addresses[i]),
"Authorization cap exceeded"
);
function initializeCohortAdminRole(uint32 ritualId) public {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it is expected this function to be called? The way I see it, we could do it in the coordinator when the ritual is initiated. This shouldn't matter in the case of ritual failing, but if ritual succeeds, then this is already done from day 1.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd avoid any changes in Coordinator to call it
This function included in grantAuthAdminRole function, so it will be called anyway during first granting

managed_allow_list.addAdministrators(RITUAL_ID, [admin.address], ADMIN_CAP, sender=admin)
managed_allow_list.grantRole(auth_admin_role, initiator, sender=initiator)
with ape.reverts("Encryptor must be authorized by the sender first"):
managed_allow_list.deauthorize(ritual_id, [deployer.address], sender=initiator)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's some food for thought for a new test:

  • Cohort admin authorizes auth admin A
  • Cohort admin authorizes auth admin B
  • A authorizes encryptor E
  • B authorizes encryptor E
  • A deauthorizes encryptor E

What should happen with E? Is E still authorized or not?

cc @arjunhassard @derekpierre @KPrasch

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting scenario. Given that E is used by both A and B, what scenario could yield that? 🤔 . An encryption service of some sort? But it would be using the same signer for both A and B? Maybe the user encrypting for themselves on two different apps (A and B) using the same ritual...?

At first blush, it seems that E should still be authorized for B. It's unclear the relationship between A and B, and feels like without that knowledge the safest philosophy is that A's actions should not affect B's.

Did you have existing thoughts here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'B authorizes encryptor E' - that will fail with the current code, encryptor can be authorized only by one auth admin

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, if B can't authorize E becasue it's already authorized by A, then the problem disappears. We need to think carefully if this is acceptable, but if so, then I don't have further comments.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the following scenario be a possibility? Two apps, A and B, each being authAdmins for the same ritual (use as part of using the same broader service) and wanting to control their own set of encryptors. The encryptor could be the user and the user utilizes the same wallet across the two apps?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you elaborate a bit more
so we have two auth admins? and same ritual? each of them can have own set of encryptors within paid subscription

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Effectively, two auth admins for the same ritual. e.g. Ceramic pays for a ritual, r, for their developers, and then assigns two separate developers/application owners, A and B, as auth admins as part of their respective applications.

Both applications allow their individual users to be encryptors. User, U, uses both apps and wants to use their EOA wallet as an encryptor...?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, now it's not allowed, but point that we don't have separation for two apps using same ritual, so for contract it will be that any admin authorizes User and this User can authorize for the ritual which effectively means both apps

Co-authored-by: derekpierre <[email protected]>
Co-authored-by: David Núñez <[email protected]>
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