User Access, Authentication , Access Token and DAML Roles -

Context:
Generally an employee is given a particular role access to a daml app (or any other application for that matter) in our entitlement system. Employee belongs to a team and anyone in the team can perform certain actions on a contract in daml app. Let’s take an example of holiday request/approval so there are 5 members in the team who can request holidays and two members in the management team that can approve any of the 5 employees. So in the entitlement system E1-E5 are part of the dev role, and M1-M2 are in management role.

What’s the best practice to implement something like this using Role based on boarding in DAML and how the corresponding tokens can be generated and what structure these tokens should have so that the rules in entitlement systems are aligned and enforced on the ledger.

We thought of two approaches:

  1. use the team as a party on the ledger and then all relevant personal are mapped to the team-party in the entitlement system, this obviously loses full provenance, so one work around is to keep employee id on the contract as data field and its captured when any action is taken

  2. In the role contract there is a list of parties that are onboarded in that role and any of the parties can act on the given contract. This has a downside of maintaining the list and keep the role contracts in sync with the entitlement system additionally on every contract the check has to be made if the party executing the choice is in the current list in that role or not.

Is there a third and better approach? Also we are keen to see token structure so that we can give it to sec team that maintains their IAM/token issuing authority system.

4 Likes

It looks like you have a pretty good handle on your problem, and either of those two will work. There is a third option you can include in your considerations, and that is to represent each party’s role independently on the ledger. So rather than having a single DevRole contract and a single ManagerRole contract each with a set of parties, instead you have DevRole and ManagementRole templates and create a single instance per party when/while each party is assigned that role. The downside of this approach is visibility, you will need an alternative means of informing employees of who has what roles, as keeping observer lists consistent across that many contracts is a problem. That being said, as these contracts are going to have to be maintained by the entitlement system, presumably represented as its own party, this may not be an issue.

A few other random thoughts on this question:

  1. Keep an eye out for contention. With any solution that uses a centralised contract, updating that contract will cause fetch/archive contention with any use of that contract in other workflows. This can have serious performance impacts if/when this occurs.
  2. Sometimes it is worth considering using a constellation of contracts instead of a single contract. Here, what is conceptually one contract (the single role contract you mention as 2), is accompanied by a number of subsidiary contracts that are maintained as projections of the primary contract. This would be a way to combine the visibility advantages of a unified per-role contract, with the contention properties of individual per-party contracts.
2 Likes

There are also several kinds of “group” or “role” patterns discussed in this thread. The linked post seems most relevant here.

The issue I point out there also holds for what you are trying to achieve here: As your group membership changes, you need to update read permissions (ie observers) on all contracts that should be visible to that group. That becomes a performance bottleneck if the relationship between group and contract is many-to-many.

Openwork Board shows this pattern in action, with read-write permissions restricted to groups of users. It uses a single contract per board to store all access levels, but it could be disentangled into access tokens of the style @Andrae suggests. However, DAML does not have transactional ranged queries so if you need access to the full list of users of a group, you do need to keep that list somewhere.

1 Like