Atomic Party Allocation and association with User

Consider you have an existing user in the User management service: you then want to add an additional Party (actAs). The User “owns” the party. Is there an atomic process to create the party and grant ActAs?

To create the user user you must have the primary party information already created, so an allocation of the party would have already occurred, but there seems to be a risk of orphaned parties if the user creation or party allocation to a existing user fails.

You can’t do directly what you want but you can play some tricks:

  1. You need to reliably allocate a party and only one. The thing that makes that difficult is that you might get a timeout or some other transient error and you don’t know if the party has been allocated. You can use the solution from the The role of party id hints section of our blogpost: If you set the hint, either you’ll allocate a new party or the request will fail. So if you get a timeout you can send a new allocate request. Either that will allocate the party or it will fail because it already exists. So you can repeat that until eventually you either get a successful response or a duplicate and you have your party and only one.
  2. Then next you create a user. You can only create one user with a given user id so just create until it either succeeds or fails because the user already exists and you have created exactly one user.

The one case that does not protect against is if you have multiple clients trying to do this stuff in parallel. I think for that it’s useful to keep one thing in mind: These are admin operations on a specific participants. So you only need to coordinate those which is usually fairly easy. There are two main options:

  1. Given that admin operations are generally low frequency, the simplest option is to just sequentialize them all through a single client.
  2. Alternatively you can try to shard the namespace of party id hints & user id hints. E.g., give everyone a unique prefix and then they’re only allowed to use party ids and user ids of the form $fixedprefix_variablesuffix.

Unless you have a very strong reason why 1 is not an option I’d just go with that. Easy to implement, easy to reason about and more than fast enough for pretty much all apps (if it reallly becomes an issue you are probably much better off using multiple participants than trying to parallelize admin operations).

@cocreature your solution in #1 ~solves the PrimaryParty scenario (as the User would be unique and so to use the partyIdHint would help to create a unique party as the user’s primary party), but what about other party allocations/creation. If a user wants to create a new party (to represent a “role”), we then end up with a issue of having to create “unique” roles names or various naming spacing ~tricks.

It would seem this separation of services would be better suited for a messaging based architecture: allocate the party and add it into the queue for Rights Grant to the requesting user. (not really a ledger issue, just the layers we add on top)

we then end up with a issue of having to create “unique” roles names or various naming spacing

True but in practice, I don’t think that’s really a big issue. First, again these are admin operations. You don’t need to coordinate them between a lot of people and especially not malicious entities. So if you go for the “sequentialize all admin ops” approach, you can just use an incrementing counter for all party hints you use. If that’s not an option for whatever reason, generate random UUIDs to avoid collisions.

How then can the daml ledger arch be used for non-admin party creation?

lets use by Organization scenario again:

  1. User A logs into the application for the first time: a User is generated in IDM and a Primary Party is generated.
  2. User A would like to create an organization (a top level object that all other contracts are birthed from / similar concept to like Create a Organizational Github Repo). The Organization requires a org party so the org’s signatory ability can be passed down into child contracts. So User A requests a new party “Org1”.
  3. Party Org1 is created and User A is granted ActAs: Org1.
  4. User A can now create an Organization contract acting as Org1.

You could also wrap the steps above into a single “Create Org” function, but the end result is the same.

These are not exactly “rare admin functions”. Party creation would be common. (imagine within a Org, you could create “Departments” contracts with Dept1 Party as the owner. New departments, teams, or whatever construct would be created frequently)

These are not exactly “rare admin functions”

I’m not saying they’re rare. I’m saying they’re sufficiently infrequent that sequentializing them is not an issue. Taking your example, teams, departments, employees, … are going to change in a frequency of days or at a very very huge company maybe hours but not several times a second.

In your example, assuming you have one participant per the whole company, the it department would probably be the admin on that participant and you make a request for them to give you a party. If you have one participant per department same thing applies to those individual participants and the corresponding admins.

In my example I have to assume that the whole process should be automatic: a registered user should be able to create new parties as needed (assume it is hidden behind an interaction such as “create org”). So there would not be any out-of-band party creation.

I understand the mitigation you are suggesting though.

Thanks!

You can still build automation but there has to be some off-ledger component. E.g., you could write request contracts on the ledger to create a new party with an accept choice with the admin as the controller that passes in the new party. The admin could then run some automation that listens for the requests contracts and once it sees one, it can do whatever checks it needs to do to check that it’s a legitimate request, then allocate the party as I described before and then feed the result back to the user.

for brevity another example of party creation with choice execution:

Scenario:

you have a template with a nonconsuming choice that will create a new contract:
example: Org > Create Team > Team. The team contract will have a party representing the root party of that team (role party).

In order to do this my understanding would be:

  1. Allocate the party
  2. Grant actAs/readAs to the user creating the party
  3. Execute the choice and pass the party as the argument (with the new party is the signatory of the Team contract).

But you then have to deal with:

  1. rights grant could fail and,
  2. The user/party executing the choice may not have access to the contract or choice, so you can end up with orphaned parties.

@Robert_Autenrieth you wrote the article: Roles in Daml - Introducing Multi-party submissions. Did you solve this flows?

there is a technical flow that could be implemented, but it feels vastly complicated to achieve the role parties pattern/usage.

I think you noted correctly that party allocation and user management operations are not part of Daml transactions, and that you need to manually handle errors and partial states. Note that party allocation in practice may involve registering the party in some external IAM - in that case, there’s no way around writing client code that handles all errors.

1 Like

@Robert_Autenrieth agreed. It was more about the User Manager service providing a AllocatePartyAndGrantRight type of function that would allocate the party and grant the right. It would be very common code that each app/implementation would need to now re-implement.

It is like Github asking if you want to auto-create a readme when creating a new repo. The two actions are very common action-pairs.