The tip and the iceberg: Identity and privacy management in Daml and Canton
Daml the programming language is the tip of the iceberg: It’s an abstraction—an interface—to the underlying, shared virtual ledger that is Canton.
Daml can be so elegant and safe because the underlying Canton layer takes care of all the complex details of distributed operation and atomic transaction management.
This blog post examines how the interplay between the surface Daml layer and the underlying Canton layer implements the identity and privacy features needed for the implementation of a Global Economic Network.
What is identity and privacy?
The words describing “identity” and “privacy” are not always used in consistent ways. So, before going into the details of how these features are implemented and what guarantees the platform gives, let’s clarify some concepts.
One aspect of identity is how we represent real-life people, systems, institutions, and so on (entities, for short) in a digital system. The other aspect of identity is what information one entity can learn about the others, and in what relationships one entity is with others. (Note that these are actually not different questions: Learning something about a real-life entity is always part of a relationship, in which sometimes a third party is also involved who vouches for the validity of that information, like a government, bank, etc.)
Privacy, in general, means that all users of a system can control what information is revealed about themselves and their relationships to whom. Privacy in a Daml system means that this information is distributed on a need-to-know basis.
Decoupling external from internal identity management
One fundamental advantage of Daml is that it separates the concern of a) connecting real-life entities with their on-ledger representations with b) internal identity and privacy management.
In a Daml system, real-life entities that are entitled to interact with the ledger are represented by ledger parties. The most important part of a ledger party object is a unique id. The linking of ledger parties with real-life entities is delegated to IAM (identity and authentication management) and KYC (know your customers) management service providers. These service providers make sure that only entitled, real-life entities can interact with the ledger on behalf of a ledger party, and that the real-life entity behind a ledger party can be verified.
Once we can assume that the ledger vs. real-world link is maintained correctly, it’s enough for us to make sure that the on-ledger representation of the relationships between ledger parties is also correct and fulfills privacy requirements.
Relationships—more specifically, roles in a relationship—and the rights and obligations attached to these roles are represented by smart contracts on the ledger. So, privacy boils down to the visibility of smart contracts and smart contract transactions.
The visibility of smart contracts and transactions
The working mechanism of need-to-know-basis privacy can be best understood by an example. For the simplest—but already relevant—use case, we need a three-party interaction. So, let’s examine the simplified implementation of the use case in which the concert organizer “Ticket Wizard” sells a ticket to Alice, who pays for it with her cash held by “Scrooge Bank.”
The code below contains two things:
- The Daml templates, which implement this business model
- A Daml script, which emulates
- the allocation of the on-ledger representation of the parties who are entitled to interact with the ledger, and users who encapsulates them; and
- three ledger submissions:
- Scrooge Bank issues cash to Alice;
- Ticket Wizard makes an offer to sell a ticket to Alice;
- Alice accepts the offer, uses her cash to pay, and becomes owner of the ticket (the last step is an “atomic swap”: if the cash offered by Alice is not enough to buy the ticket, nothing changes on the ledger).
The party allocation and the ledger submissions are not part of the Daml model; the Daml scripts emulate steps, which are performed by client applications.
An interesting thing to note is that one, real-life entity, Alice, represented by one party id (which is something like `Alice::1220939bc9a7…`), plays several roles in several relationships:
- In the “Cash” relationship at the beginning of the workflow, she is cash owner (her party id is in the `owner` field of the `Cash` contract)
- In the “TicketOffer” relationship, as long as it exists, she is ticket buyer (her party id is in the `buyer` field of the `TicketOffer` contract)
- In the “TicketAgreement” relationship, which emerges during the process, she is the ticket owner (her party id is in the `owner` field of the `TicketAgreement` contract)
The fact that the ticket and the cash change hands is expressed in two different ways: The cash is issued in advance and gets transferred during the transaction, while the ticket is issued during the process.
Now, how can you, the Daml developer, know which entity playing a role in this process can see what? Under the hood, this information can be retrieved from the transaction tree service of the ledger API. If you retrieve the transaction tree, you get a (possibly huge) JSON file, from which you can extract the information you need. For small ledgers, like this one containing only three transactions and their children, Daml Studio can be used to inspect the transaction tree by clicking on the “Script result” link appearing above the script declaration and choosing the transaction view.
From this screen, you can see that there are three transactions in this process, numbered from zero. TX 0 is the issuance of cash, which initially is only visible to Alice and Scrooge Bank, but later, from TX 2, it is also visible to Ticket Wizard, who accepts the cash as a payment for the ticket. TX 1 is the issuance of the ticket offer, visible only to Alice and Ticket Wizard; Scrooge Bank doesn’t have to know about the offer.
TX 2 is the most complex transaction, containing the atomic swap. It contains several children at two levels, so it’s best to describe its contents here also in a structured way:
- Alice accepts the ticket offer, which has the following consequences:
- The cash contract she offers for payment also gets revealed to Ticket Wizard;
- the cash gets transferred to Ticket Wizard; Alice doesn’t have to authorize (and also cannot prevent from happening) this step separately, and it is visible to all three parties;
- An implicit consequence of the transfer, which is not depicted in the above diagram, is that Alice’s Cash contract gets archived, meaning she no longer owns the cash
- The other leg of the transfer is that Ticket Wizard becomes the owner of the same amount of cash held with the same bank, and this is also visible to all three parties
- Alice becomes the owner of the newly issued ticket. Scrooge Bank doesn’t know about this, because it doesn’t have to do anything with the ticket: This is need-to-know-basis privacy.
Front-door and back-door privacy in Canton
As mentioned above, identity management and privacy in the Daml layer is relatively simple, easy to understand, and safe. But, in order for things to work in this orderly manner, a lot of complexity needs to be handled, which comes from the distributed operation and the requirement of atomic transaction management.
A post like this is not enough to explain all the details of the underlying Canton operation. Fortunately, the creators of Canton listed the design principles and functional requirements of the platform, so I will point the reader to these and let her dive into the details of the documentation as deep as she likes.
When we extend our focus beyond the Daml layer to the underlying Canton implementation, we realize that privacy requirements have two layers: a) Controlled visibility for ledger parties according to the Daml model (need-to-know-basis), which I call for this post “front-door privacy,” and b) shielding private data from entities that are not ledger parties but that play a role in the operation of the ledger, which I call “back-door privacy.”
The current level of back-door privacy has been added recently with Daml SDK version 2.0, which made Canton generally available and has been summed up in the release notes in the following way:
- Security confidence regardless of the underlying infrastructure: Messages are encrypted at the participant level regardless of the underlying infrastructure—a relational database or a blockchain layer—requiring less trust in anyone who has access to information on the domain.
- Increased privacy: Encrypting messages at the participant level means that the content of the transaction is hidden from anyone who has access to information on the domain.
Further explanation can be found in the System Architecture FAQ / How does Canton ensure privacy? section of the docs. This FAQ also contains links to more in-depth explanations.
For understanding front-door privacy, we need to grasp at least a bit about how Canton manages identity in general (not just regarding ledger parties) and how it processes transaction requests.
Identity management requirements, principles, and the whole mathematical model of it is described in the Identity Management section of the docs. I only highlight one element of the description that is essential for business users: “The identity providing service needs to comply with regulatory requirements, such as the GDPR right to be forgotten.”
The way transactions are processed in Canton is described in the Transaction Processing in Canton section of the docs. A rough, first approximation to understand this is to say that transaction requests are chopped up to pieces, and every party can see only that piece in which it is a stakeholder. After the participants have validated their parts independently, the confirmed parts are distributed to the stakeholders. In this way, no ledger party ever sees any information that it doesn’t have to see.
Summarized in the High-Level Requirements section of the docs: “I want the visibility of the ledger contents to be restricted according to the privacy model of DA ledgers, so that the information about any (sub)action on the ledger is provided only to participant nodes of parties privy to this action.”