Skip to content

smartcontract: allow payer access pass for subscribe and delete#3340

Draft
snormore wants to merge 4 commits intomainfrom
snor/multicast-subscribe-payer-accesspass
Draft

smartcontract: allow payer access pass for subscribe and delete#3340
snormore wants to merge 4 commits intomainfrom
snor/multicast-subscribe-payer-accesspass

Conversation

@snormore
Copy link
Contributor

@snormore snormore commented Mar 22, 2026

Summary

  • SubscribeMulticastGroup: accept access pass from either user.owner or payer, allowing a third party to subscribe a user using its own access pass
  • DeleteUser: same pattern — accept payer's access pass and authorize delete when payer matches the access pass user_payer field
  • DeleteUserCommand (SDK): try payer's access pass first, fall back to user.owner's
  • RemoveMulticastGroupSubAllowlist: add feed_authority to auth check
  • disconnect: get client IP from daemon instead of local discovery, matching connect behavior (PRd separately in client: get client IP from daemon in disconnect command #3341, will be merged first)

Testing Verification

  • All existing subscribe, delete, and allowlist tests pass unchanged
  • New test: access pass user_payer can delete user, stranger cannot
  • New test: feed_authority can remove from subscriber allowlist

@juan-malbeclabs
Copy link
Contributor

Clarification: The access pass is tied directly to the user payer when the connection is created, with a one-to-one relationship based on user_payer + client_ip. This access pass is used to authorize creation of the user, and it is updated both in the Access Pass state and in the connection counter. That is why, when deleting the user, the same access pass that was used to create the User account must also be used.

I understand that the goal of this change is to allow an oracle to subscribe a user to a specific multicast group. From what I see in the code, implementing it this way will require a second access pass keyed by (client_ip + oracle_pk), which must also have permission to subscribe to the multicast group in question.

My recommendation is to keep referencing the access pass that was used when the User was created (client_ip + user.owner), which should be the one authorized for the multicast group, and add a permission in global_state to allow the oracle to subscribe the user. This way, you do not need a new access pass.

With the new permissions model, you will be able to create a permission that allows a user (the oracle) to subscribe users without adding anything to global_state.

@snormore
Copy link
Contributor Author

snormore commented Mar 22, 2026

We'd have to also allow the feed authority (oracle) to update the user-owned access pass in that scenario.

So it's either:

  1. Allow feed authority (oracle) to update user-owned access pass, and to subscribe a user to a group using the user-owned access pass, or
  2. Allow feed authority (oracle) to subscribe a user to a group using a separate oracle-owned access pass (current change)

@juan-malbeclabs
Copy link
Contributor

juan-malbeclabs commented Mar 22, 2026

You could also allow the oracle authority to subscribe a user to a multicast group without that permission being granted in the Access Pass. You could register on the multicast group itself that the oracle is authorized to subscribe users to that group without any additional permissions. That way, you would not need to modify existing access passes or create new ones. You would be defining that each multicast group can have an authority allowed to subscribe users.

Ultimately, what you want is to grant the oracle the authority to subscribe the user.
What I would not do is introduce a second access pass.

@juan-malbeclabs
Copy link
Contributor

This is the main change: you are now assuming the user would no longer be created by the user themselves with their own signature, but instead by the oracle. If that is the case, then user.owner would point to the oracle’s public key rather than the user’s, and you would not have a problem subscribing.

I think changing the model so the user is no longer created under the user’s own identity is a substantial shift in how users are managed.

I think this discussion is already outside the scope of this PR.

@snormore snormore changed the title smartcontract: allow payer access pass for multicast group subscribe smartcontract: allow feed_authority to manage multicast subscriptions for any user Mar 22, 2026
@snormore snormore force-pushed the snor/multicast-subscribe-payer-accesspass branch from 1897f17 to 8688d86 Compare March 22, 2026 17:50
Match the connect command's behavior by getting the client IP from the
daemon instead of discovering it locally. This avoids mismatches when
the daemon has a different view of the public IP (e.g. behind NAT).

Extract resolve_client_ip() into a testable method and add unit tests
for valid IP, empty IP, invalid IP, and daemon-unreachable cases. Move
now-unused look_for_ip helpers behind #[cfg(test)]. Remove deprecated
--client-ip from connect/disconnect invocations in e2e tests.
Accept the access pass from either the user's owner or the payer,
enabling a third party (e.g. an oracle) to subscribe an existing user
to a new multicast group using its own access pass.
Accept the payer's access pass in DeleteUser (same pattern as
SubscribeMulticastGroup). Also authorize delete when the payer matches
the access pass user_payer field. SDK DeleteUserCommand tries the
payer's access pass first, falling back to user.owner's.
@snormore snormore force-pushed the snor/multicast-subscribe-payer-accesspass branch from 8688d86 to ed42d95 Compare March 22, 2026 23:28
@snormore snormore changed the title smartcontract: allow feed_authority to manage multicast subscriptions for any user smartcontract: allow payer access pass for subscribe and delete Mar 22, 2026
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.

2 participants