Preparing for the Sovrin Transaction Author Agreement

June 26, 2019

By: Adam Burdett, Software Engineer, Sovrin Foundation

All terms appearing in First Letter Capitals in this article are defined in the Sovrin Glossary.

The Sovrin community has approved adding a legal agreement between the Sovrin Foundation and the individuals and organizations that write to the Sovrin Ledger as Transaction Authors. The Transaction Author Agreement (TAA) will be enforced on networks such as MainNet, StagingNet, and BuilderNet. This article helps users of the Sovrin Network better understand the technical requirements of implementing this new agreement. Software interacting with the ledger will need to use the updated API, and application developers must understand how to demonstrate their user’s acceptance of the agreement.

Why this new agreement?

In order to serve as a global public utility for identity, the Sovrin Network provides a public, immutable ledger. Immutability means that data will not be deleted. Any users writing data to the ledger must agree that once it is published, it cannot be unpublished. This includes DIDs, DID metadata, Schemas, Credential Definitions, Revocation Accumulators, and any other cryptographic primitives used for Verifiable Credentials. More information regarding what goes on the ledger can be found here.

As a global public ledger, the Sovrin Ledger and all its participants are subject to privacy and data protection regulations such as the EU General Data Protection Regulation (GDPR). These regulations require that the participants be explicit about responsibilities for Personal Data. For example, some Sovrin Stewards have expressed concern that, in their role as data processors for the Sovrin Ledger, users might hold them liable for their inability to remove Personal Data from the ledger. 

To clarify these responsibilities and provide protection for all parties, the Sovrin Governance Framework Working Group developed an agreement between Transaction Authors and the Sovrin Foundation. The TAA can be found at Sovrin.org. It ensures that users are aware of and consent to the fact that all data written to the Sovrin Ledger cannot be removed, even if the original author of the transaction requests its removal.

The TAA outlines the policies that users must follow when interacting with the Sovrin Ledger. When a user’s client software is preparing a transaction for submission to the network, it must include a demonstration that the user had the opportunity to review the current TAA and accept it. This is done by including some additional fields in the ledger write transaction: 

  1. A hash of the agreement
  2. A date when the agreement was accepted, and
  3. A string indicating the user interaction that was followed to obtain the acceptance. 

The Indy client API used by Sovrin has been extended to allow users to review current and past agreements and to indicate acceptance through an approved user interaction pattern.

Valid client transaction

To indicate acceptance of the agreement, the write transaction is required to have an added field called “taaAcceptance”. The “taaAcceptance” contains the digest of the accepted TAA, the mechanism by which it was accepted, and the timestamp of the date when it was accepted. When the TAA is enforced, the transaction is not valid if the “taaAcceptance”, or any of its attributes, is omitted. Similarly, the transaction will be rejected if the agreement digest does not match the digest of the current TAA on the config ledger, or if the acceptance mechanism string is not part of the current Acceptance Mechanism List (AML). The timestamp must be newer than when the TAA was added to the ledger. These fields must be signed along with the rest of the transaction.

Transactions can be sent to the ledger in many different ways. The following examples are client software agnostic, reflecting the JSON sent directly to the Indy client API.

A valid client transaction now includes a “taaAcceptance” json object. For example:

{
    'operation': {
        'type': <request type>,
        <request-specific fields>
    },
    
    'identifier': <sender/author DID>,
    'reqId': <req_id unique integer>,
    'taaAcceptance': {
        'taaDigest': <digest hex string>,
        'mechanism': <mechanism string>,
        'time': <time integer>
     }
    'protocolVersion': 2,
    'signature': <signature_value>,
    # 'signatures': {
    #      `did1`: <sig1>,
    #      `did2`: <sig2>,
    #  }    
           
}

Where “mechanism” is the string of the mechanism used to accept. For example:

'taaAcceptance': {
    'taaDigest': d8967f7d9eee82eedc98834387b866d721a2906a8b80d78e90e59d168d12d7d7,
    'mechanism': 'session_instantiation',
    'time': 1560366712
}

For more details, see the Indy-SDK Requests Document.

A warning about correlatability

The fields for “taaAcceptance” could in theory provide an additional way to correlate users across the various DIDs they have on the ledger based on their client software and the time they accepted the agreement. This design tries to minimize correlation by not asking the user to identify the specific software being used, but instead focusing on common patterns of acceptance. Similarly, the application should not provide the time the user accepts, but only the day. Correlation risk can be further reduced by tracking a different acceptance date per DID on the ledger, or regularly asking the user to reaccept the agreement in order to change the acceptance date—although we acknowledge these approaches may increase the user’s friction when writing to the ledger.

Getting the TAA from the ledger

The TAA can be retrieved from the ledger using the client transaction API. For example:

{
    'operation': {
        'type': '6'
        'version': '1.0',
    },
    
    'identifier': 'L5AD5g65TDQr1PPHHRoiGf',
    'reqId': 1514308188474704,
    'protocolVersion': 2
}

Will return the selected TAA.

....
'data': {
    "version": "1.0",
    "text": "Please read carefully before writing anything to the ledger ...",
},
....

For more details, see the Indy-SDK Requests Document

User interaction

In order for the agreement to be enforceable, the Sovrin Foundation needs some indication that the user reviewed the agreement in a meaningful way. So we are adding to the ledger the AML—a list of acceptance mechanisms that represent appropriate patterns of user interaction for completing this acceptance. When submitting a transaction to the ledger, the client software must indicate which of the AML patterns was used. Reporting a different interaction pattern than was actually used would be considered an act of fraud committed by the developer of the client application.

The various AML choices represent different user interactions and scopes for acceptance. A single software package may utilize multiple acceptance mechanisms based on the UX designed by the application developer. The client software MUST NOT automate TAA user acceptance. Users of the software should be able to access the current TAA on the ledger at any time and view when they accepted the TAA. Users should also have the option to reaccept the TAA.

Get AML from the ledger

The AML can be retrieved from the Ledger using Indy client API in a manner similar to the TAA. The following example is retrieving an AML by version:

{
    'operation': {
        'type': '7'
        'version': '1.0',
    },
    
    'identifier': 'L5AD5g65TDQr1PPHHRoiGf',
    'reqId': 1514308188474704,
    'protocolVersion': 2
}

Will return the requested AML. For example:

....
'data': {
    "version": "1.0",
    "aml": {
        "eula": "Included in the EULA for the product being used",
        "service_agreement": "Included in the agreement with the service provider managing the transaction",
        "click_agreement": "Agreed through the UI at the time of submission",
        "session_agreement": "Agreed at wallet instantiation or login"
    },
    "amlContext": "http://aml-context-descr"
},
....

For more details, see the Indy-SDK Requests Document.

Patterns for users interaction

The initial AML file can be found here. Each mechanism reflects a distinct approach to how the user will review and accept the agreement, which is described below to help guide application developers in designing their user interaction.

“product_eula”: The client software presents the transaction author agreement to the user as part of the product’s end user license agreement. At that time, the user can review the agreement, and the date of this review is stored along with a hash of the agreement at the time. If the agreement changes, the user will review and accept the agreement along with the EULA, or a different acceptance mechanism would be used for the review. Commercial products will likely use this approach with enterprise clients who do a legal review before purchasing.

“service_agreement”: This interaction is intended for cloud services that interact with the ledger. The service might not have any user interface, but the customer will accept the agreement when signing up for the service.

“at_submission”: At the time of preparing and submitting the transaction, the agreement was displayed to the user and the user was prompted to review it and agree to it.

“for_session”: When the user attempts to write to the ledger, they are given the opportunity to review and accept the agreement. This acceptance is then stored and reused for any other writes during the current session. This is the UX paradigm implemented in the Indy CLI.

“wallet_agreement”: When the user attempts to write to the ledger, the client application presents the agreement for review and acceptance. The date of acceptance is then persisted within the wallet where it can be reused as often as necessary until a new agreement is put on the ledger which the user must review and accept.

“on_file”: If the user of the client software is representing an organization, the user might not be authorized to accept legal agreements on behalf of that organization. In this case, the client software should prompt the user to enter the date when the authorized person (such as legal counsel) accepted the agreement, and indicate which version of the agreement is being kept on file with the user’s organization so that the user can be prompted if the agreement changes and requires additional review.

For developers testing their applications 

If a TAA is not anchored to the config ledger, Indy Node will not require that the related fields be included in write transactions. If you want to test the TAA functionality of your application against your own deployment of Indy Node, you must first set up the AML and then set a TAA.

Setting AML

Before a TAA can be set on the ledger the AML must be set. For example:

{
    'operation': {
        'type': '5'
        "version": "1.0",
        "aml": {
            "eula": "Included in the EULA for the product being used",
            "service_agreement": "Included in the agreement with the service provider managing the transaction",
            "click_agreement": "Agreed through the UI at the time of submission",
            "session_agreement": "Agreed at wallet instantiation or login"
        },
        "amlContext": "http://aml-context-descr"
    },
    
    'identifier': '21BPzYYrFzbuECcBV3M1FH',
    'reqId': 1514304094738044,
    'protocolVersion': 2,
    'signature': '3YVzDtSxxnowVwAXZmxCG2fz1A38j1qLrwKmGEG653GZw7KJRBX57Stc1oxQZqqu9mCqFLa7aBzt4MKXk4MeunVj',
}

For more details, see the Indy-SDK Requests Document.

Setting TAA

Once an AML has been set on the ledger, you can set the TAA. For example:

{
    'operation': {
        'type': '4'
        'version': '1.0',
        'text': "Please read carefully before writing anything to the ledger ...",
    },
    
    'identifier': '21BPzYYrFzbuECcBV3M1FH',
    'reqId': 1514304094738044,
    'protocolVersion': 2,
    'signature': '3YVzDtSxxnowVwAXZmxCG2fz1A38j1qLrwKmGEG653GZw7KJRBX57Stc1oxQZqqu9mCqFLa7aBzt4MKXk4MeunVj',
}

Here be dragons

Dangerous waters are ahead, so be prepared. Once the TAA is enabled and enforced, all write transactions that don’t meet these criteria will be rejected by the ledger, and any client software failing to represent a user’s TAA acceptance will break. If after reading this article you still have questions, you can reach us at http://forums.sovrin.org and http://chat.sovrin.org.

Updates


References

Design: https://github.com/hyperledger/indy-node/blob/master/design/txn_author_agreement.md

Jira Ticket: https://jira.hyperledger.org/browse/INDY-1942

Transaction Author Agreement (pdf): https://sovrin.org/wp-content/uploads/Transaction-Author-Agreement-V1.1.pdf

Transaction Author Agreement (string for ledger): link coming soon

Acceptable Acceptance Mechanisms (json object for ledger): https://github.com/sovrin-foundation/sovrin/blob/master/TAA/AML.md

« »